Skip to content

Commit

Permalink
InheritanceDiagram: cleanup code; avoid iframe hack; use single param…
Browse files Browse the repository at this point in the history
…eter (#5056)

* Cleanup code; avoid iframe hack

* feedback

* Prevent cutoffs when xpos is negative

* No inheritance diagram when there is no inheritance chain
  • Loading branch information
Elchi3 authored Jan 13, 2022
1 parent 5698ff2 commit 96fce93
Showing 1 changed file with 94 additions and 97 deletions.
191 changes: 94 additions & 97 deletions kumascript/macros/InheritanceDiagram.ejs
Original file line number Diff line number Diff line change
@@ -1,132 +1,129 @@
<%
/*
Draws an responsive SVG diagram for the inheritance chain (inverted in rtl)
Draws an SVG diagram to display an interface's inheritance chain
$0 - width - defaults to 600
$1 - height - defaults to 70
$2 - offset - defaults to 50
$3 - Interface name
$0 - Interface name (defaults to the interface page the macro is called on)
Test pages
- http://localhost:3000/en-US/docs/Web/API/SVGTextPositioningElement
- http://localhost:3000/en-US/docs/Web/API/WheelEvent
- http://localhost:3000/en-US/docs/Web/API/USB/connect_event
*/
var data = web.getJSONData("InterfaceData");
var slug = env.slug;
var result = "";
// slug is not available in preview mode.
if (slug) {
var locale = env.locale;
var href = 'https://developer.mozilla.org/' + locale + '/docs/Web/API/';
var mainIF = $3 || slug.replace('Web/API/','').split('/')[0];
var rtlLocales = ['ar', 'he', 'fa'];
var inheritanceChain = [mainIF];
var inh = data[0][mainIF] != undefined ? data[0][mainIF].inh : '';
var width = $0 || 600;
var height = $1 || 70;
var offset = $2 || 50;
var rtl = false;
if (rtlLocales.indexOf(locale) != -1) {
rtl = true;
}
const data = web.getJSONData("InterfaceData")[0];
const href = `/${env.locale}/docs/Web/API/`;
const mainInterfaceName = $0 || env.slug.replace('Web/API/','').split('/')[0];
let height = 40;
let offset = 0;
let xpos = 1;
let ypos = 1;
let inheritanceChain = [mainInterfaceName];
let inh = data[mainInterfaceName] != undefined ? data[mainInterfaceName].inh : '';
function getInheritance(inh) {
if (inh.length > 0) {
if (inh !== '') {
inheritanceChain.unshift(inh);
if (Object.prototype.hasOwnProperty.call(data[0], inh)) {
var inh = data[0][inh].inh;
if (data[inh]) {
inh = data[inh].inh;
getInheritance(inh);
}
}
}
getInheritance(inh);
var l = 0;
function rectWithText(x, y, fill, interface, reverse) {
var flip = rtl ? 'transform="scale(-1 1)"' : '';
var inv = rtl ? '-' : '';
l = interface.length * 10 < 75 ? 75 : interface.length * 10;
function rectWithText(x, y, fill, interfaceName, reverse) {
const rectWidth = interfaceName.length * 8 < 75 ? 75 : interfaceName.length * 8;
if (reverse) {
xpos -= l;
xpos -= rectWidth;
x = xpos;
} else {
xpos += rectWidth;
}
if (!reverse) {
xpos += l;
}
return '<a xlink:href="' + href + interface + '" target="_top">' +
'<rect x="'+x+'" y="'+y+'" width="'+l+'" height="50" fill="'+fill+'" stroke="#D4DDE4" stroke-width="2px" />' +
'<text '+flip+' x="'+inv+(x+l/2)+'" y="'+(y+29)+'" font-size="12px" font-family="Consolas,Monaco,Andale Mono,monospace"' +
' fill="#4D4E53" text-anchor="middle" alignment-baseline="middle">'+interface+'</text>' +
'</a>';
return `
<a style="text-decoration: none;" xlink:href="${href+interfaceName}">
<rect x="${x}" y="${y}" width="${rectWidth}" height="25" fill="${fill}" stroke="#D4DDE4" stroke-width="2px" />
<text x="${x+rectWidth/2}" y="${y+16}" font-size="10px" fill="#4D4E53" text-anchor="middle">
${interfaceName}
</text>
</a>`;
}
function lineWithTriangle(x, y, reverse) {
var str = '';
let str = '';
let polylinePoints = `${x},${y+14} ${x+10},${y+9} ${x+10},${y+19} ${x},${y+14}`;
let linePoints = `x1="${x+10}" y1="${y+14}" x2="${x+30}" y2="${y+14}"`;
if (reverse) {
str += '<polyline points="'+x+','+(y+24)+' '+(x-10)+','+(y+19)+' '+(x-10)+','+(y+29)+' '+x+','+(y+24)+'" stroke="#D4DDE4" fill="none"/>';
x -= 10;
str += '<line x1="'+x+'" y1="'+(y+24)+'" x2="'+(x-30)+'" y2="'+(y+24)+'" stroke="#D4DDE4"/>';
} else {
str += '<polyline points="'+x+','+(y+24)+' '+(x+10)+','+(y+19)+' '+(x+10)+','+(y+29)+' '+x+','+(y+24)+'" stroke="#D4DDE4" fill="none"/>';
x += 10;
str += '<line x1="'+x+'" y1="'+(y+24)+'" x2="'+(x+30)+'" y2="'+(y+24)+'" stroke="#D4DDE4"/>';
polylinePoints = `${x},${y+14} ${x-10},${y+9} ${x-10},${y+19} ${x},${y+14}`;
linePoints = `x1="${x-10}" y1="${y+14}" x2="${x-30}" y2="${y+14}"`;
}
str += `<polyline points="${polylinePoints}" stroke="#D4DDE4" fill="none"/>`;
x -= 10;
str += `<line ${linePoints} stroke="#D4DDE4"/>`;
return str;
}
var padding = (height / width) * 100;
var xpos = 1;
var ypos = 1;
var viewbox = 'viewbox="-'+ offset + ' 0 '+ width + ' ' + height +'"';
function connectingLineWithTriangle() {
let str = '';
if (rtl) {
viewbox = 'viewbox="510 0 '+ width + ' ' + height +'" transform="scale(-1 1)"';
str += `<polyline points="${xpos},${ypos+14} ${xpos+10},${ypos+9} ${xpos+10},${ypos+19} ${xpos},${ypos+14}" stroke="#D4DDE4" fill="none"/>`;
xpos += 10;
str += `<line x1="${xpos}" y1="${ypos+14}" x2="${xpos+8}" y2="${ypos+14}" stroke="#D4DDE4"/>`;
xpos += 8;
str += `<line x1="${xpos}" y1="${ypos+14}" x2="${xpos}" y2="${ypos+59}" stroke="#D4DDE4"/>`;
ypos = 60;
str += `<line x1="${xpos}" y1="${ypos}" x2="${xpos-17}" y2="${ypos}" stroke="#D4DDE4"/>`;
return str;
}
result = '<div id="interfaceDiagram" style="display: inline-block; position: relative; width: 100%; padding-bottom: '+ padding +'%; vertical-align: middle; overflow: hidden;">' +
'<svg style="display: inline-block; position: absolute; top: 0; left: 0;" '+ viewbox +' preserveAspectRatio="xMinYMin meet">';
for (var i = 0; i < inheritanceChain.length; i++) {
var fill = (inheritanceChain[i] == mainIF) ? '#F4F7F8': '#fff';
// we are going to the second row with a special line
if (i == 4) {
result += '<polyline points="'+xpos+','+(ypos+24)+' '+(xpos+10)+','+(ypos+19)+' '+(xpos+10)+','+(ypos+29)+' '+xpos+','+(ypos+24)+'" stroke="#D4DDE4" fill="none"/>'
xpos += 10;
result += '<line x1="'+xpos+'" y1="'+(ypos+24)+'" x2="'+(xpos+8)+'" y2="'+(ypos+24)+'" stroke="#D4DDE4"/>';
xpos += 8;
result += '<line x1="'+xpos+'" y1="'+(ypos+24)+'" x2="'+xpos+'" y2="'+(ypos+89)+'" stroke="#D4DDE4"/>';
ypos = 90;
result += '<line x1="'+xpos+'" y1="'+ypos+'" x2="'+(xpos-17)+'" y2="'+ypos+'" stroke="#D4DDE4"/>';
xpos -= 18;
ypos = 65;
}
// first row
if (i < 4) {
result += rectWithText(xpos, ypos, fill, inheritanceChain[i]);
if (i != inheritanceChain.length - 1 && i != 3) {
result += lineWithTriangle(xpos, ypos);
xpos += 40;
function drawDiagram(inheritanceChain) {
let str = '';
for (let i = 0; i < inheritanceChain.length; i++) {
const fill = (inheritanceChain[i] == mainInterfaceName) ? '#F4F7F8': '#fff';
// we are going to the second row with a connecting line
if (i === 4) {
str += connectingLineWithTriangle();
xpos -= 18;
ypos = 47;
}
} else {
// first row
if (i < 4) {
str += rectWithText(xpos, ypos, fill, inheritanceChain[i]);
if (i != inheritanceChain.length - 1 && i != 3) {
str += lineWithTriangle(xpos, ypos);
xpos += 30;
}
// second row
result += rectWithText(xpos, ypos, fill, inheritanceChain[i], true);
if (i != inheritanceChain.length - 1 && i != 3) {
result += lineWithTriangle(xpos, ypos, true);
xpos -= 40;
} else {
height = 80; // need more space
str += rectWithText(xpos, ypos, fill, inheritanceChain[i], true);
if (i != inheritanceChain.length - 1) {
str += lineWithTriangle(xpos, ypos, true);
xpos -= 30;
}
if (xpos < 0) {
// prevent cut off in case of a really long chain (see e.g. SVGTextPositioningElement)
offset = 1 + Math.abs(xpos);
}
}
}
return str;
}
result +='</svg></div>';
}
%>
<div class="hidden" id="inheritance_diagram">

<pre class="brush: html">
<%=result%>
</pre>
let output = '';
<pre class="brush: css">
a:hover text { fill: #0095DD; pointer-events: all;}
</pre>

</div>
if (inheritanceChain.length > 1) {
let diagram = drawDiagram(inheritanceChain); // needs to run first to calculate offset and height
output = `<svg viewbox="-${offset} 0 650 ${height}" preserveAspectRatio="xMinYMin meet">`;
output += diagram;
output +='</svg>';
}
<%-await template("EmbedLiveSample", ["inheritance_diagram", width, height, '', '', 'inheritance-diagram-frame'])%>
%>
<%-output%>

0 comments on commit 96fce93

Please sign in to comment.