Skip to content

Commit de11f23

Browse files
committedJan 2, 2016
Merge remote-tracking branch 'upstream/master'
2 parents 0f4057d + 1a294ce commit de11f23

10 files changed

+157
-35
lines changed
 

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ An UML Class explorer for InterSystems Caché.
77
+ Edit diagrams after build;
88
+ Switch between strict UML notation and designed view;
99
+ Export diagrams as an image;
10-
+ See Class methods, properties, parameters, SQL queries and more;
10+
+ See Class methods, properties, parameters, SQL queries, xDatas and more;
1111
+ See any keywords and related information by hovering over everything with pointer;
1212
+ Check which fields are connected by hovering over link;
13-
+ View class methods code with syntax highlighting;
13+
+ View methods code, sql queries and xDatas with syntax highlighting;
1414
+ Zoom in and out;
1515
+ Search on diagram or in class tree;
1616
+ Explore!

‎cache/projectTemplate.xml

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Description>
55
Cache Class Explorer vX.X.X/*build.replace:pkg.version*/
66
Class contains methods that return structured classes/packages data.</Description>
7-
<TimeChanged>63844,1495</TimeChanged>
7+
<TimeChanged>63919,67431.456639</TimeChanged>
88
<TimeCreated>63653,67019.989197</TimeCreated>
99

1010
<Method name="getAllNamespacesList">
@@ -97,6 +97,7 @@ Return structured data about class.</Description>
9797
set oProperties = ##class(%ZEN.proxyObject).%New()
9898
set oQueries = ##class(%ZEN.proxyObject).%New()
9999
set oIndices = ##class(%ZEN.proxyObject).%New()
100+
set oXDatas = ##class(%ZEN.proxyObject).%New()
100101
101102
set oClass.isDataType = classDefinition.ClientDataTypeIsDefined()
102103
set oClass.isOdbcType = classDefinition.OdbcTypeIsDefined()
@@ -184,6 +185,19 @@ Return structured data about class.</Description>
184185
do oQueries.%DispatchSetProperty(q.Name, oProp)
185186
}
186187
188+
#dim xd as %Dictionary.XDataDefinition
189+
set oClass.xdatas = oXDatas
190+
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.XDataDefinition")
191+
for i=1:1:classDefinition.XDatas.Count() {
192+
set oProp = ##class(%ZEN.proxyObject).%New()
193+
set xd = classDefinition.XDatas.GetAt(i)
194+
for j=1:1:props.Properties.Count() {
195+
set pname = props.Properties.GetAt(j).Name
196+
set:(pname '= "parent") $PROPERTY(oProp, pname) = $PROPERTY(xd, pname)
197+
}
198+
do oXDatas.%DispatchSetProperty(xd.Name, oProp)
199+
}
200+
187201
#dim ind as %Dictionary.IndexDefinition
188202
set oClass.indices = oIndices
189203
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.IndexDefinition")

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "CacheClassExplorer",
3-
"version": "1.11.0",
3+
"version": "1.12.0",
44
"description": "Class Explorer for InterSystems Caché",
55
"directories": {
66
"test": "test"

‎web/css/classView.css

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ svg {
1919
/*fill: lightgray;*/
2020
}
2121

22-
.uml-class-attrs-rect, .uml-class-methods-rect, .uml-class-queries-rect {
22+
.uml-class-attrs-rect, .uml-class-methods-rect, .uml-class-queries-rect, .uml-class-xdatas-rect {
2323
fill: white;
2424
}
2525

@@ -78,6 +78,12 @@ text {
7878
fill: magenta;
7979
}
8080

81+
.uml-class-xdatas-label {
82+
font-family: monospace;
83+
font-weight: 900;
84+
fill: #0ab;
85+
}
86+
8187
.line-clickable {
8288
cursor: pointer;
8389
-webkit-transition: all .2s ease;

‎web/index.html

+5
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ <h1>
132132
<td><label for="setting.showQueries">Show Queries</label></td>
133133
<td>Display block with class queries</td>
134134
</tr>
135+
<tr>
136+
<td><input id="setting.showXDatas" type="checkbox"/></td>
137+
<td><label for="setting.showXDatas">Show xDatas</label></td>
138+
<td>Display block with class xDatas</td>
139+
</tr>
135140
</tbody>
136141
</table>
137142
<p id="settingsExtraText"></p>

‎web/js/CacheClassExplorer.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ var CacheClassExplorer = function (treeViewContainer, classViewContainer) {
4747
showParameters: id("setting.showParameters"),
4848
showProperties: id("setting.showProperties"),
4949
showMethods: id("setting.showMethods"),
50-
showQueries: id("setting.showQueries")
50+
showQueries: id("setting.showQueries"),
51+
showXDatas: id("setting.showXDatas")
5152
}
5253
};
5354

@@ -64,7 +65,8 @@ var CacheClassExplorer = function (treeViewContainer, classViewContainer) {
6465
showParameters: settingsValue("showParameters", true),
6566
showProperties: settingsValue("showProperties", true),
6667
showMethods: settingsValue("showMethods", true),
67-
showQueries: settingsValue("showQueries", true)
68+
showQueries: settingsValue("showQueries", true),
69+
showXDatas: settingsValue("showXDatas", true)
6870
};
6971

7072
this.UI = new UI(this);

‎web/js/ClassView.js

+38-1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ ClassView.prototype.getPropertyHoverText = function (prop, type) {
341341
"Encoded": 1,
342342
// -- queries
343343
"SqlView": 1,
344+
// -- xDatas
345+
"MimeType": function (data) {
346+
return "MimeType = " + data;
347+
},
344348
// -- class
345349
"ClientDataType": function (data, p) {
346350
return !p["isDataType"] ? ""
@@ -450,6 +454,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
450454
classProps = classMetaData["properties"],
451455
classMethods = classMetaData["methods"],
452456
classQueries = classMetaData["queries"],
457+
classXDatas = classMetaData["xdatas"],
453458
keyWordsArray = [name],
454459
self = this;
455460

@@ -525,6 +530,22 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
525530
}
526531
return arr;
527532
})(classQueries),
533+
xdatas: (function (xds) {
534+
var arr = [], n;
535+
for (n in xds) {
536+
keyWordsArray.push(n);
537+
arr.push({
538+
name: n,
539+
text: n + (xds[n]["MimeType"] ? ": " + xds[n]["MimeType"] : ""),
540+
hover: self.getPropertyHoverText(xds[n], "xdata"),
541+
icons: self.getPropertyIcons(xds[n]),
542+
clickHandler: (function (d, className) {
543+
return function () { self.showXData(className, d); }
544+
})(xds[n], name)
545+
});
546+
}
547+
return arr;
548+
})(classXDatas),
528549
classSigns: this.getClassSigns(classMetaData),
529550
classType: classMetaData.ClassType || "registered",
530551
SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH
@@ -571,6 +592,22 @@ ClassView.prototype.showQuery = function (className, queryData) {
571592

572593
};
573594

595+
/**
596+
* @param {string} className
597+
* @param {string} xData
598+
*/
599+
ClassView.prototype.showXData = function (className, xData) {
600+
601+
xData = xData || "";
602+
603+
this.showPanel({
604+
header: "##class(" + className + ")." + xData["Name"] + (xData["MimeType"] ? " (" + xData["MimeType"] + ")" : xData["MimeType"]),
605+
comment: xData["Description"],
606+
body: lib.highlightXML(xData["Data"] || "")
607+
});
608+
609+
};
610+
574611
/**
575612
* Show panel filled with given HTML contents.
576613
* @param {string} data.header
@@ -949,7 +986,7 @@ ClassView.prototype.bindLinkHighlight = function () {
949986
highlighted = !!fields.length;
950987
});
951988

952-
this.paper.on("cell:mouseout", function (e) {
989+
this.paper.on("cell:mouseout", function () {
953990
highlighted = false;
954991
freeFields();
955992
});

‎web/js/Lib.js

+49-6
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,7 @@ Lib.prototype.sqlKeyWords = {
178178
*/
179179
Lib.prototype.highlightCOS = function (code) {
180180
var self = this;
181-
return code.replace(/[<>&]/g, function (r) {
182-
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;"
183-
}).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) {
181+
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) {
184182
var i = -1, c;
185183
[].slice.call(arguments, 1, arguments.length - 2).every(function (e) {
186184
i++;
@@ -201,15 +199,19 @@ Lib.prototype.highlightCOS = function (code) {
201199
});
202200
};
203201

202+
Lib.prototype.replaceSpecial = function (str) {
203+
return str.replace(/[<>&]/g, function (r) {
204+
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;";
205+
});
206+
};
207+
204208
/**
205209
* Highlight SQL code.
206210
* @param {string} code
207211
*/
208212
Lib.prototype.highlightSQL = function (code) {
209213
var self = this;
210-
return code.replace(/[<>&]/g, function (r) {
211-
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;"
212-
}).replace(/(&[lgtamp]{2,3};)|([a-zA-Z]+)/gi, function (part, a, kw) {
214+
return this.replaceSpecial(code).replace(/(&[lgtamp]{2,3};)|([a-zA-Z]+)/gi, function (part, a, kw) {
213215
var i = -1, c;
214216
[].slice.call(arguments, 1, arguments.length - 2).every(function (e) {
215217
i++;
@@ -224,6 +226,47 @@ Lib.prototype.highlightSQL = function (code) {
224226
});
225227
};
226228

229+
/**
230+
* Highlight XML code.
231+
* @param {string} code
232+
*/
233+
Lib.prototype.highlightXML = function (code) {
234+
235+
var replaceSpecial = this.replaceSpecial,
236+
level = 0,
237+
regex = new RegExp("<!\\[CDATA\\[([^]*?)]]" // this line break is done to avoid xData
238+
// injection fail, as CDATA cannot have the closing character sequence inside.
239+
// DO NOT join these three characters in one inline string
240+
// KEEP THIS LINE
241+
+ [].join("")
242+
+ ">|<(\\/?)[\\w](?:.*(?=\\/>)|.*(?=>))(\\/?)>|(<!--[^]*?-->)"
243+
+ "|(<\\?[^]*?\\?>)|(<[^]*?>)", "g");
244+
245+
function stringFill (n) {
246+
return new Array(n + 1).join(" ")
247+
}
248+
249+
return code.replace(regex, function (part, cData, tagS, tagG, comment, special, etc) {
250+
return typeof tagS !== "undefined" ? part.replace(/<\/?([^\s]+)(.*(?=\/>)|.*(?=>))\/?>/ig, function (p, tagName, attrs) {
251+
if (tagS) level--;
252+
var s = stringFill(level) + " &lt;" + tagS + "<span class=\"syntax-keyword\">"
253+
+ tagName + "</span>"
254+
+ attrs.replace(/(\s*[^=]+)=(\s*(?:'[^']*'|"[^"]*"))/g, function (part, a, b) {
255+
return "<span class=\"syntax-names\">" + a
256+
+ "</span>=<span class=\"syntax-string\">" + b + "</span>";
257+
})
258+
+ tagG + "&gt;";
259+
if (!tagS && !tagG) level++;
260+
return s;
261+
}) : comment ? "<span class=\"syntax-comment\">" + replaceSpecial(comment) + "</span>"
262+
: special ? replaceSpecial(special)
263+
: etc ? replaceSpecial(etc)
264+
: "<span class=\"syntax-other\">&lt;![CDATA[</span>"
265+
+ replaceSpecial(cData) + "<span class=\"syntax-other\">]]&gt;</span>";
266+
});
267+
268+
};
269+
227270
Lib.prototype.getSelection = function () {
228271
var html = "";
229272
if (typeof window.getSelection != "undefined") {

‎web/js/Logic.js

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Logic.prototype.process = function (data) {
3939
if (cls.properties && !this.umlExplorer.settings.showProperties) delete cls.properties;
4040
if (cls.methods && !this.umlExplorer.settings.showMethods) delete cls.methods;
4141
if (cls.queries && !this.umlExplorer.settings.showQueries) delete cls.queries;
42+
if (cls.xdatas && !this.umlExplorer.settings.showXDatas) delete cls.xdatas;
4243
}
4344

4445
if (!this.umlExplorer.settings.showDataTypesOnDiagram) {

‎web/jsLib/joint.shapes.uml.js

+35-21
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
1414

1515
markup: [
1616
'<g class="rotatable">',
17-
'<g class="scalable">',
18-
'<rect class="uml-class-name-rect"/>',
19-
'<rect class="uml-class-params-rect"/>',
20-
'<text class="uml-class-params-label">Parameters</text>',
21-
'<rect class="uml-class-attrs-rect"/>',
22-
'<text class="uml-class-attrs-label">Properties</text>',
23-
'<rect class="uml-class-methods-rect"/>',
24-
'<text class="uml-class-methods-label">Methods</text>',
25-
'<rect class="uml-class-queries-rect"/>',
26-
'<text class="uml-class-queries-label">Queries</text>',
27-
'</g>',
28-
'<text class="uml-class-name-text"/>',
29-
'<text class="uml-class-params-text"/>',
30-
'<text class="uml-class-attrs-text"/>',
31-
'<text class="uml-class-methods-text"/>',
32-
'<text class="uml-class-queries-text"/>',
17+
'<g class="scalable">',
18+
'<rect class="uml-class-name-rect"/>',
19+
'<rect class="uml-class-params-rect"/>',
20+
'<text class="uml-class-params-label">Parameters</text>',
21+
'<rect class="uml-class-attrs-rect"/>',
22+
'<text class="uml-class-attrs-label">Properties</text>',
23+
'<rect class="uml-class-methods-rect"/>',
24+
'<text class="uml-class-methods-label">Methods</text>',
25+
'<rect class="uml-class-queries-rect"/>',
26+
'<text class="uml-class-queries-label">Queries</text>',
27+
'<rect class="uml-class-xdatas-rect"/>',
28+
'<text class="uml-class-xdatas-label">xDatas</text>',
29+
'</g>',
30+
'<text class="uml-class-name-text"/>',
31+
'<text class="uml-class-params-text"/>',
32+
'<text class="uml-class-attrs-text"/>',
33+
'<text class="uml-class-methods-text"/>',
34+
'<text class="uml-class-queries-text"/>',
35+
'<text class="uml-class-xdatas-text"/>',
3336
'</g>'
3437
].join(''),
3538

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

5458
'.uml-class-name-text': {
5559
'ref': '.uml-class-name-rect', 'ref-y': .5, 'ref-x': .5, 'text-anchor': 'middle', 'y-alignment': 'middle', 'font-weight': 'bold',
@@ -71,6 +75,10 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
7175
'ref': '.uml-class-queries-rect', 'ref-y': 5, 'ref-x': 5,
7276
'fill': 'black', 'font-size': 12
7377
},
78+
'.uml-class-xdatas-text': {
79+
'ref': '.uml-class-xdatas-rect', 'ref-y': 5, 'ref-x': 5,
80+
'fill': 'black', 'font-size': 12
81+
},
7482
'.uml-class-attrs-label': {
7583
ref: '.uml-class-attrs-label', fill: "black", 'font-size': 10,
7684
xPos: -56
@@ -83,6 +91,9 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
8391
},
8492
'.uml-class-params-label': {
8593
ref: '.uml-class-methods-label', fill: "black", 'font-size': 10
94+
},
95+
'.uml-class-xdatas-label': {
96+
ref: '.uml-class-xdatas-label', fill: "black", 'font-size': 10
8697
}
8798
},
8899

@@ -91,6 +102,7 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
91102
attributes: [],
92103
methods: [],
93104
queries: [],
105+
xdatas: [],
94106
classSigns: []
95107

96108
}, joint.shapes.basic.Generic.prototype.defaults),
@@ -100,10 +112,11 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
100112
var o,
101113
rects = [
102114
{ type: 'name', text: this.getClassName() },
103-
{ type: 'params', text: (o = this.get('params')) , o: (o.forEach(function(e){e._BLOCK="parameters"}) && o) },
104-
{ type: 'attrs', text: (o = this.get('attributes')), o: (o.forEach(function(e){e._BLOCK="properties"}) && o) },
105-
{ type: 'methods', text: (o = this.get('methods')) , o: (o.forEach(function(e){e._BLOCK="methods"}) && o) },
106-
{ type: 'queries', text: (o = this.get('queries')) , o: (o.forEach(function(e){e._BLOCK="queries"}) && o) }
115+
{ type: 'params', text: (o = this.get('params')||[]) , o: (o.forEach(function(e){e._BLOCK="parameters"}) && o) },
116+
{ type: 'attrs', text: (o = this.get('attributes')||[]), o: (o.forEach(function(e){e._BLOCK="properties"}) && o) },
117+
{ type: 'methods', text: (o = this.get('methods')||[]) , o: (o.forEach(function(e){e._BLOCK="methods"}) && o) },
118+
{ type: 'queries', text: (o = this.get('queries')||[]) , o: (o.forEach(function(e){e._BLOCK="queries"}) && o) },
119+
{ type: 'xdatas', text: (o = this.get('xdatas')||[]) , o: (o.forEach(function(e){e._BLOCK="xdatas"}) && o) }
107120
],
108121
self = this,
109122
classSigns = this.get('classSigns'),
@@ -199,7 +212,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
199212
{ type: 'params', text: this.get('params') },
200213
{ type: 'attrs', text: this.get('attributes') },
201214
{ type: 'methods', text: this.get('methods') },
202-
{ type: 'queries', text: this.get('queries') }
215+
{ type: 'queries', text: this.get('queries') },
216+
{ type: 'xdatas', text: this.get('xdatas') }
203217
];
204218

205219
var offsetY = 0;

0 commit comments

Comments
 (0)
Please sign in to comment.