enable lazy-loading of gitgraph.js (#9036)
- moved gitgraph.js to web_src and made it importable and es6-compatible - created new webpack chunk for gitgraph - enabled CSS loader in webpack - enabled async/await syntax via regenerator-runtime - added script to ensure webpack chunks are loaded correctly - disable terser's comment extraction to prevent .LICENCE files gitgraph.js has many issues: 1. it is incompatible with ES6 because of strict-mode violations 1. it does not export anything 1. it's css has weird styles like for `body` 1. it is not available on npm I fixed points 1-3 in our version so it's now loadable in webpack. We should eventually consider alternatives.
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
/public/js/semantic.dropdown.custom.js
|
/public/js/semantic.dropdown.custom.js
|
||||||
|
/web_src/js/vendor/**
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ env:
|
|||||||
node: true
|
node: true
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
|
__webpack_public_path__: true
|
||||||
Clipboard: false
|
Clipboard: false
|
||||||
CodeMirror: false
|
CodeMirror: false
|
||||||
Dropzone: false
|
Dropzone: false
|
||||||
|
|||||||
Generated
+826
-179
File diff suppressed because it is too large
Load Diff
@@ -6,16 +6,20 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.7.2",
|
"@babel/core": "7.7.2",
|
||||||
|
"@babel/plugin-transform-runtime": "7.6.2",
|
||||||
"@babel/preset-env": "7.7.1",
|
"@babel/preset-env": "7.7.1",
|
||||||
|
"@babel/runtime": "7.7.2",
|
||||||
"autoprefixer": "9.7.1",
|
"autoprefixer": "9.7.1",
|
||||||
"babel-loader": "8.0.6",
|
"babel-loader": "8.0.6",
|
||||||
"core-js": "3.4.1",
|
"core-js": "3.4.1",
|
||||||
|
"css-loader": "3.2.0",
|
||||||
"eslint": "6.6.0",
|
"eslint": "6.6.0",
|
||||||
"eslint-config-airbnb-base": "14.0.0",
|
"eslint-config-airbnb-base": "14.0.0",
|
||||||
"eslint-plugin-import": "2.18.2",
|
"eslint-plugin-import": "2.18.2",
|
||||||
"less": "3.10.3",
|
"less": "3.10.3",
|
||||||
"less-plugin-clean-css": "1.5.1",
|
"less-plugin-clean-css": "1.5.1",
|
||||||
"postcss-cli": "6.1.3",
|
"postcss-cli": "6.1.3",
|
||||||
|
"style-loader": "1.0.0",
|
||||||
"stylelint": "11.1.1",
|
"stylelint": "11.1.1",
|
||||||
"stylelint-config-standard": "19.0.0",
|
"stylelint-config-standard": "19.0.0",
|
||||||
"terser-webpack-plugin": "2.2.1",
|
"terser-webpack-plugin": "2.2.1",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
-3
@@ -17,9 +17,6 @@ Version: 2.3.1
|
|||||||
File(s): /vendor/plugins/clipboard/clipboard.min.js
|
File(s): /vendor/plugins/clipboard/clipboard.min.js
|
||||||
Version: 1.5.9
|
Version: 1.5.9
|
||||||
|
|
||||||
File(s): /vendor/plugins/gitgraph/gitgraph.js
|
|
||||||
Version: 745f604212e2abfe2f0a59169ea530857b46625c
|
|
||||||
|
|
||||||
File(s): /vendor/plugins/vue/vue.min.js
|
File(s): /vendor/plugins/vue/vue.min.js
|
||||||
Version: 2.1.10
|
Version: 2.1.10
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -46,7 +46,7 @@
|
|||||||
<td><a href="https://github.com/zenorocha/clipboard.js/archive/v1.5.9.tar.gz">clipboard-1.5.9.tar.gz</a></td>
|
<td><a href="https://github.com/zenorocha/clipboard.js/archive/v1.5.9.tar.gz">clipboard-1.5.9.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/gitgraph/gitgraph.js">gitgraph.js</a></td>
|
<td><a href="../js/gitgraph.js">gitgraph.js</a></td>
|
||||||
<td><a href="https://github.com/bluef/gitgraph.js/blob/master/LICENSE">BSD 3-Clause</a></td>
|
<td><a href="https://github.com/bluef/gitgraph.js/blob/master/LICENSE">BSD 3-Clause</a></td>
|
||||||
<td><a href="https://github.com/bluef/gitgraph.js">gitgraph.js-latest</a></td>
|
<td><a href="https://github.com/bluef/gitgraph.js">gitgraph.js-latest</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
-435
@@ -1,435 +0,0 @@
|
|||||||
/*
|
|
||||||
* @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD 3-Clause
|
|
||||||
* Copyright (c) 2011, Terrence Lee <kill889@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the <organization> nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var gitGraph = function (canvas, rawGraphList, config) {
|
|
||||||
if (!canvas.getContext) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof config === "undefined") {
|
|
||||||
config = {
|
|
||||||
unitSize: 20,
|
|
||||||
lineWidth: 3,
|
|
||||||
nodeRadius: 4
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var flows = [];
|
|
||||||
var graphList = [];
|
|
||||||
|
|
||||||
var ctx = canvas.getContext("2d");
|
|
||||||
|
|
||||||
var devicePixelRatio = window.devicePixelRatio || 1;
|
|
||||||
var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
|
|
||||||
ctx.mozBackingStorePixelRatio ||
|
|
||||||
ctx.msBackingStorePixelRatio ||
|
|
||||||
ctx.oBackingStorePixelRatio ||
|
|
||||||
ctx.backingStorePixelRatio || 1;
|
|
||||||
|
|
||||||
var ratio = devicePixelRatio / backingStoreRatio;
|
|
||||||
|
|
||||||
var init = function () {
|
|
||||||
var maxWidth = 0;
|
|
||||||
var i;
|
|
||||||
var l = rawGraphList.length;
|
|
||||||
var row;
|
|
||||||
var midStr;
|
|
||||||
|
|
||||||
for (i = 0; i < l; i++) {
|
|
||||||
midStr = rawGraphList[i].replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
|
|
||||||
|
|
||||||
maxWidth = Math.max(midStr.replace(/(\_|\s)/g, "").length, maxWidth);
|
|
||||||
|
|
||||||
row = midStr.split("");
|
|
||||||
|
|
||||||
graphList.unshift(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
var width = maxWidth * config.unitSize;
|
|
||||||
var height = graphList.length * config.unitSize;
|
|
||||||
|
|
||||||
canvas.width = width * ratio;
|
|
||||||
canvas.height = height * ratio;
|
|
||||||
|
|
||||||
canvas.style.width = width + 'px';
|
|
||||||
canvas.style.height = height + 'px';
|
|
||||||
|
|
||||||
ctx.lineWidth = config.lineWidth;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
ctx.lineCap = "round";
|
|
||||||
|
|
||||||
ctx.scale(ratio, ratio);
|
|
||||||
};
|
|
||||||
|
|
||||||
var genRandomStr = function () {
|
|
||||||
var chars = "0123456789ABCDEF";
|
|
||||||
var stringLength = 6;
|
|
||||||
var randomString = '', rnum, i;
|
|
||||||
for (i = 0; i < stringLength; i++) {
|
|
||||||
rnum = Math.floor(Math.random() * chars.length);
|
|
||||||
randomString += chars.substring(rnum, rnum + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return randomString;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findFlow = function (id) {
|
|
||||||
var i = flows.length;
|
|
||||||
|
|
||||||
while (i-- && flows[i].id !== id) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findColomn = function (symbol, row) {
|
|
||||||
var i = row.length;
|
|
||||||
|
|
||||||
while (i-- && row[i] !== symbol) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findBranchOut = function (row) {
|
|
||||||
if (!row) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
var i = row.length;
|
|
||||||
|
|
||||||
while (i-- &&
|
|
||||||
!(row[i - 1] && row[i] === "/" && row[i - 1] === "|") &&
|
|
||||||
!(row[i - 2] && row[i] === "_" && row[i - 2] === "|")) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var findLineBreak = function (row) {
|
|
||||||
if (!row) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
var i = row.length;
|
|
||||||
|
|
||||||
while (i-- &&
|
|
||||||
!(row[i - 1] && row[i - 2] && row[i] === " " && row[i - 1] === "|" && row[i - 2] === "_")) {}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
var genNewFlow = function () {
|
|
||||||
var newId;
|
|
||||||
|
|
||||||
do {
|
|
||||||
newId = genRandomStr();
|
|
||||||
} while (findFlow(newId) !== -1);
|
|
||||||
|
|
||||||
return {id:newId, color:"#" + newId};
|
|
||||||
};
|
|
||||||
|
|
||||||
//Draw methods
|
|
||||||
var drawLine = function (moveX, moveY, lineX, lineY, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(moveX, moveY);
|
|
||||||
ctx.lineTo(lineX, lineY);
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineRight = function (x, y, color) {
|
|
||||||
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y + config.unitSize / 2, color);
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineUp = function (x, y, color) {
|
|
||||||
drawLine(x, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawNode = function (x, y, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
|
|
||||||
drawLineUp(x, y, color);
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x, y, config.nodeRadius, 0, Math.PI * 2, true);
|
|
||||||
ctx.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineIn = function (x, y, color) {
|
|
||||||
drawLine(x + config.unitSize, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawLineOut = function (x, y, color) {
|
|
||||||
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y - config.unitSize / 2, color);
|
|
||||||
};
|
|
||||||
|
|
||||||
var draw = function (graphList) {
|
|
||||||
var colomn, colomnIndex, prevColomn, condenseIndex, breakIndex = -1;
|
|
||||||
var x, y;
|
|
||||||
var color;
|
|
||||||
var nodePos;
|
|
||||||
var tempFlow;
|
|
||||||
var prevRowLength = 0;
|
|
||||||
var flowSwapPos = -1;
|
|
||||||
var lastLinePos;
|
|
||||||
var i, l;
|
|
||||||
var condenseCurrentLength, condensePrevLength = 0, condenseNextLength = 0;
|
|
||||||
|
|
||||||
var inlineIntersect = false;
|
|
||||||
|
|
||||||
//initiate color array for first row
|
|
||||||
for (i = 0, l = graphList[0].length; i < l; i++) {
|
|
||||||
if (graphList[0][i] !== "_" && graphList[0][i] !== " ") {
|
|
||||||
flows.push(genNewFlow());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
y = (canvas.height / ratio) - config.unitSize * 0.5;
|
|
||||||
|
|
||||||
//iterate
|
|
||||||
for (i = 0, l = graphList.length; i < l; i++) {
|
|
||||||
x = config.unitSize * 0.5;
|
|
||||||
|
|
||||||
currentRow = graphList[i];
|
|
||||||
nextRow = graphList[i + 1];
|
|
||||||
prevRow = graphList[i - 1];
|
|
||||||
|
|
||||||
flowSwapPos = -1;
|
|
||||||
|
|
||||||
condenseCurrentLength = currentRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
if (nextRow) {
|
|
||||||
condenseNextLength = nextRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
} else {
|
|
||||||
condenseNextLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//pre process begin
|
|
||||||
//use last row for analysing
|
|
||||||
if (prevRow) {
|
|
||||||
if (!inlineIntersect) {
|
|
||||||
//intersect might happen
|
|
||||||
for (colomnIndex = 0; colomnIndex < prevRowLength; colomnIndex++) {
|
|
||||||
if (prevRow[colomnIndex + 1] &&
|
|
||||||
(prevRow[colomnIndex] === "/" && prevRow[colomnIndex + 1] === "|") ||
|
|
||||||
((prevRow[colomnIndex] === "_" && prevRow[colomnIndex + 1] === "|") &&
|
|
||||||
(prevRow[colomnIndex + 2] === "/"))) {
|
|
||||||
|
|
||||||
flowSwapPos = colomnIndex;
|
|
||||||
|
|
||||||
//swap two flow
|
|
||||||
tempFlow = {id:flows[flowSwapPos].id, color:flows[flowSwapPos].color};
|
|
||||||
|
|
||||||
flows[flowSwapPos].id = flows[flowSwapPos + 1].id;
|
|
||||||
flows[flowSwapPos].color = flows[flowSwapPos + 1].color;
|
|
||||||
|
|
||||||
flows[flowSwapPos + 1].id = tempFlow.id;
|
|
||||||
flows[flowSwapPos + 1].color = tempFlow.color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (condensePrevLength < condenseCurrentLength &&
|
|
||||||
((nodePos = findColomn("*", currentRow)) !== -1 &&
|
|
||||||
(findColomn("_", currentRow) === -1))) {
|
|
||||||
|
|
||||||
flows.splice(nodePos - 1, 0, genNewFlow());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevRowLength > currentRow.length &&
|
|
||||||
(nodePos = findColomn("*", prevRow)) !== -1) {
|
|
||||||
|
|
||||||
if (findColomn("_", currentRow) === -1 &&
|
|
||||||
findColomn("/", currentRow) === -1 &&
|
|
||||||
findColomn("\\", currentRow) === -1) {
|
|
||||||
|
|
||||||
flows.splice(nodePos + 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //done with the previous row
|
|
||||||
|
|
||||||
prevRowLength = currentRow.length; //store for next round
|
|
||||||
colomnIndex = 0; //reset index
|
|
||||||
condenseIndex = 0;
|
|
||||||
condensePrevLength = 0;
|
|
||||||
breakIndex = -1; //reset break index
|
|
||||||
while (colomnIndex < currentRow.length) {
|
|
||||||
colomn = currentRow[colomnIndex];
|
|
||||||
|
|
||||||
if (colomn !== " " && colomn !== "_") {
|
|
||||||
++condensePrevLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check and fix line break in next row
|
|
||||||
if (colomn === "/" && currentRow[colomnIndex - 1] && currentRow[colomnIndex - 1] === "|") {
|
|
||||||
if ((breakIndex = findLineBreak(nextRow)) !== -1) {
|
|
||||||
nextRow.splice(breakIndex, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//if line break found replace all '/' with '|' after breakIndex in previous row
|
|
||||||
if (breakIndex !== - 1 && colomn === "/" && colomnIndex > breakIndex) {
|
|
||||||
currentRow[colomnIndex] = "|";
|
|
||||||
colomn = "|";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn === " " &&
|
|
||||||
currentRow[colomnIndex + 1] &&
|
|
||||||
currentRow[colomnIndex + 1] === "_" &&
|
|
||||||
currentRow[colomnIndex - 1] &&
|
|
||||||
currentRow[colomnIndex - 1] === "|") {
|
|
||||||
|
|
||||||
currentRow.splice(colomnIndex, 1);
|
|
||||||
|
|
||||||
currentRow[colomnIndex] = "/";
|
|
||||||
colomn = "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
//create new flow only when no intersect happened
|
|
||||||
if (flowSwapPos === -1 &&
|
|
||||||
colomn === "/" &&
|
|
||||||
currentRow[colomnIndex - 1] &&
|
|
||||||
currentRow[colomnIndex - 1] === "|") {
|
|
||||||
|
|
||||||
flows.splice(condenseIndex, 0, genNewFlow());
|
|
||||||
}
|
|
||||||
|
|
||||||
//change \ and / to | when it's in the last position of the whole row
|
|
||||||
if (colomn === "/" || colomn === "\\") {
|
|
||||||
if (!(colomn === "/" && findBranchOut(nextRow) === -1)) {
|
|
||||||
if ((lastLinePos = Math.max(findColomn("|", currentRow),
|
|
||||||
findColomn("*", currentRow))) !== -1 &&
|
|
||||||
(lastLinePos < colomnIndex - 1)) {
|
|
||||||
|
|
||||||
while (currentRow[++lastLinePos] === " ") {}
|
|
||||||
|
|
||||||
if (lastLinePos === colomnIndex) {
|
|
||||||
currentRow[colomnIndex] = "|";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn === "*" &&
|
|
||||||
prevRow &&
|
|
||||||
prevRow[condenseIndex + 1] === "\\") {
|
|
||||||
flows.splice(condenseIndex + 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colomn !== " ") {
|
|
||||||
++condenseIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
++colomnIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
condenseCurrentLength = currentRow.filter(function (val) {
|
|
||||||
return (val !== " " && val !== "_")
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
//do some clean up
|
|
||||||
if (flows.length > condenseCurrentLength) {
|
|
||||||
flows.splice(condenseCurrentLength, flows.length - condenseCurrentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
colomnIndex = 0;
|
|
||||||
|
|
||||||
//a little inline analysis and draw process
|
|
||||||
while (colomnIndex < currentRow.length) {
|
|
||||||
colomn = currentRow[colomnIndex];
|
|
||||||
prevColomn = currentRow[colomnIndex - 1];
|
|
||||||
|
|
||||||
if (currentRow[colomnIndex] === " ") {
|
|
||||||
currentRow.splice(colomnIndex, 1);
|
|
||||||
x += config.unitSize;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//inline interset
|
|
||||||
if ((colomn === "_" || colomn === "/") &&
|
|
||||||
currentRow[colomnIndex - 1] === "|" &&
|
|
||||||
currentRow[colomnIndex - 2] === "_") {
|
|
||||||
|
|
||||||
inlineIntersect = true;
|
|
||||||
|
|
||||||
tempFlow = flows.splice(colomnIndex - 2, 1)[0];
|
|
||||||
flows.splice(colomnIndex - 1, 0, tempFlow);
|
|
||||||
currentRow.splice(colomnIndex - 2, 1);
|
|
||||||
|
|
||||||
colomnIndex = colomnIndex - 1;
|
|
||||||
} else {
|
|
||||||
inlineIntersect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
color = flows[colomnIndex].color;
|
|
||||||
|
|
||||||
switch (colomn) {
|
|
||||||
case "_" :
|
|
||||||
drawLineRight(x, y, color);
|
|
||||||
|
|
||||||
x += config.unitSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "*" :
|
|
||||||
drawNode(x, y, color);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "|" :
|
|
||||||
drawLineUp(x, y, color);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "/" :
|
|
||||||
if (prevColomn &&
|
|
||||||
(prevColomn === "/" ||
|
|
||||||
prevColomn === " ")) {
|
|
||||||
x -= config.unitSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawLineOut(x, y, color);
|
|
||||||
|
|
||||||
x += config.unitSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "\\" :
|
|
||||||
drawLineIn(x, y, color);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++colomnIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
y -= config.unitSize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
init();
|
|
||||||
draw(graphList);
|
|
||||||
};
|
|
||||||
// @end-license
|
|
||||||
@@ -111,7 +111,6 @@ func Graph(ctx *context.Context) {
|
|||||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||||
ctx.Data["CommitCount"] = commitsCount
|
ctx.Data["CommitCount"] = commitsCount
|
||||||
ctx.Data["Branch"] = ctx.Repo.BranchName
|
ctx.Data["Branch"] = ctx.Repo.BranchName
|
||||||
ctx.Data["RequireGitGraph"] = true
|
|
||||||
ctx.Data["Page"] = context.NewPagination(int(allCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
|
ctx.Data["Page"] = context.NewPagination(int(allCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
|
||||||
ctx.HTML(200, tplGraph)
|
ctx.HTML(200, tplGraph)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,6 @@
|
|||||||
CodeMirror.modeURL = "{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/%N/%N.js";
|
CodeMirror.modeURL = "{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/%N/%N.js";
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .RequireGitGraph}}
|
|
||||||
<!-- graph -->
|
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js"></script>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<!-- Third-party libraries -->
|
<!-- Third-party libraries -->
|
||||||
{{if .RequireHighlightJS}}
|
{{if .RequireHighlightJS}}
|
||||||
|
|||||||
@@ -87,11 +87,6 @@
|
|||||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
|
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if .RequireGitGraph}}
|
|
||||||
<!-- graph -->
|
|
||||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.css">
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .RequireTribute}}
|
{{if .RequireTribute}}
|
||||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
|
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ var urlsToCache = [
|
|||||||
'{{StaticUrlPrefix}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
|
'{{StaticUrlPrefix}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js',
|
||||||
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
||||||
|
'{{StaticUrlPrefix}}/js/gitgraph.js?v={{MD5 AppVer}}',
|
||||||
'{{StaticUrlPrefix}}/js/semantic.dropdown.custom.js?v={{MD5 AppVer}}',
|
'{{StaticUrlPrefix}}/js/semantic.dropdown.custom.js?v={{MD5 AppVer}}',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js',
|
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.custom.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.custom.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
|
||||||
@@ -25,7 +25,6 @@ var urlsToCache = [
|
|||||||
'{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css',
|
'{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css',
|
||||||
'{{StaticUrlPrefix}}/vendor/assets/octicons/octicons.min.css',
|
'{{StaticUrlPrefix}}/vendor/assets/octicons/octicons.min.css',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css',
|
'{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.css',
|
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css',
|
'{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.css',
|
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.css',
|
||||||
'{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}',
|
'{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}',
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
/* globals gitGraph */
|
|
||||||
|
|
||||||
$(() => {
|
|
||||||
const graphList = [];
|
|
||||||
|
|
||||||
if (!document.getElementById('graph-canvas')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#graph-raw-list li span.node-relation').each(function () {
|
|
||||||
graphList.push($(this).text());
|
|
||||||
});
|
|
||||||
|
|
||||||
gitGraph(document.getElementById('graph-canvas'), graphList);
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
$(async () => {
|
||||||
|
const graphCanvas = document.getElementById('graph-canvas');
|
||||||
|
if (!graphCanvas) return;
|
||||||
|
|
||||||
|
const [{ default: gitGraph }] = await Promise.all([
|
||||||
|
import(/* webpackChunkName: "gitgraph" */'../vendor/gitgraph.js/gitgraph.custom.js'),
|
||||||
|
import(/* webpackChunkName: "gitgraph" */'../vendor/gitgraph.js/gitgraph.custom.css'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const graphList = [];
|
||||||
|
$('#graph-raw-list li span.node-relation').each(function () {
|
||||||
|
graphList.push($(this).text());
|
||||||
|
});
|
||||||
|
|
||||||
|
gitGraph(graphCanvas, graphList);
|
||||||
|
});
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */
|
/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */
|
||||||
/* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */
|
/* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */
|
||||||
|
|
||||||
|
import './publicPath';
|
||||||
|
import './gitGraph';
|
||||||
|
|
||||||
function htmlEncode(text) {
|
function htmlEncode(text) {
|
||||||
return jQuery('<div />').text(text).html();
|
return jQuery('<div />').text(text).html();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/* This sets up webpack's chunk loading to load resources from the same
|
||||||
|
directory where it loaded index.js from. This file must be imported
|
||||||
|
before any lazy-loading is being attempted. */
|
||||||
|
|
||||||
|
if (document.currentScript && document.currentScript.src) {
|
||||||
|
const url = new URL(document.currentScript.src);
|
||||||
|
__webpack_public_path__ = `${url.pathname.replace(/\/[^/]*$/, '')}/`;
|
||||||
|
} else {
|
||||||
|
// compat: IE11
|
||||||
|
const script = document.querySelector('script[src*="/index.js"]');
|
||||||
|
__webpack_public_path__ = `${script.getAttribute('src').replace(/\/[^/]*$/, '')}/`;
|
||||||
|
}
|
||||||
Vendored
+1
-4
@@ -1,6 +1,3 @@
|
|||||||
body {font:13.34px/1.4 helvetica,arial,freesans,clean,sans-serif;}
|
|
||||||
em {font-style:normal;}
|
|
||||||
|
|
||||||
#git-graph-container, #rel-container {float:left;}
|
#git-graph-container, #rel-container {float:left;}
|
||||||
#rel-container {max-width:30%; overflow-x:auto;}
|
#rel-container {max-width:30%; overflow-x:auto;}
|
||||||
#git-graph-container {overflow-x:auto; width:100%}
|
#git-graph-container {overflow-x:auto; width:100%}
|
||||||
@@ -13,4 +10,4 @@ em {font-style:normal;}
|
|||||||
#git-graph-container li a em {color:#BB0000;border-bottom:1px dotted #BBBBBB;text-decoration:none;font-style:normal;}
|
#git-graph-container li a em {color:#BB0000;border-bottom:1px dotted #BBBBBB;text-decoration:none;font-style:normal;}
|
||||||
#rev-container {width:100%}
|
#rev-container {width:100%}
|
||||||
#rev-list {margin:0;padding:0 5px 0 5px;min-width:95%}
|
#rev-list {margin:0;padding:0 5px 0 5px;min-width:95%}
|
||||||
#graph-raw-list {margin:0px;}
|
#graph-raw-list {margin:0px;}
|
||||||
+419
@@ -0,0 +1,419 @@
|
|||||||
|
/*
|
||||||
|
* @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD 3-Clause
|
||||||
|
* Copyright (c) 2011, Terrence Lee <kill889@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default function gitGraph(canvas, rawGraphList, config) {
|
||||||
|
if (!canvas.getContext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof config === 'undefined') {
|
||||||
|
config = {
|
||||||
|
unitSize: 20,
|
||||||
|
lineWidth: 3,
|
||||||
|
nodeRadius: 4
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const flows = [];
|
||||||
|
const graphList = [];
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
const devicePixelRatio = window.devicePixelRatio || 1;
|
||||||
|
const backingStoreRatio = ctx.webkitBackingStorePixelRatio
|
||||||
|
|| ctx.mozBackingStorePixelRatio
|
||||||
|
|| ctx.msBackingStorePixelRatio
|
||||||
|
|| ctx.oBackingStorePixelRatio
|
||||||
|
|| ctx.backingStorePixelRatio || 1;
|
||||||
|
|
||||||
|
const ratio = devicePixelRatio / backingStoreRatio;
|
||||||
|
|
||||||
|
const init = function () {
|
||||||
|
let maxWidth = 0;
|
||||||
|
let i;
|
||||||
|
const l = rawGraphList.length;
|
||||||
|
let row;
|
||||||
|
let midStr;
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++) {
|
||||||
|
midStr = rawGraphList[i].replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
|
||||||
|
|
||||||
|
maxWidth = Math.max(midStr.replace(/(_|\s)/g, '').length, maxWidth);
|
||||||
|
|
||||||
|
row = midStr.split('');
|
||||||
|
|
||||||
|
graphList.unshift(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
const width = maxWidth * config.unitSize;
|
||||||
|
const height = graphList.length * config.unitSize;
|
||||||
|
|
||||||
|
canvas.width = width * ratio;
|
||||||
|
canvas.height = height * ratio;
|
||||||
|
|
||||||
|
canvas.style.width = `${width}px`;
|
||||||
|
canvas.style.height = `${height}px`;
|
||||||
|
|
||||||
|
ctx.lineWidth = config.lineWidth;
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
|
||||||
|
ctx.scale(ratio, ratio);
|
||||||
|
};
|
||||||
|
|
||||||
|
const genRandomStr = function () {
|
||||||
|
const chars = '0123456789ABCDEF';
|
||||||
|
const stringLength = 6;
|
||||||
|
let randomString = '', rnum, i;
|
||||||
|
for (i = 0; i < stringLength; i++) {
|
||||||
|
rnum = Math.floor(Math.random() * chars.length);
|
||||||
|
randomString += chars.substring(rnum, rnum + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return randomString;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findFlow = function (id) {
|
||||||
|
let i = flows.length;
|
||||||
|
|
||||||
|
while (i-- && flows[i].id !== id);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findColomn = function (symbol, row) {
|
||||||
|
let i = row.length;
|
||||||
|
|
||||||
|
while (i-- && row[i] !== symbol);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findBranchOut = function (row) {
|
||||||
|
if (!row) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = row.length;
|
||||||
|
|
||||||
|
while (i--
|
||||||
|
&& !(row[i - 1] && row[i] === '/' && row[i - 1] === '|')
|
||||||
|
&& !(row[i - 2] && row[i] === '_' && row[i - 2] === '|'));
|
||||||
|
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findLineBreak = function (row) {
|
||||||
|
if (!row) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = row.length;
|
||||||
|
|
||||||
|
while (i--
|
||||||
|
&& !(row[i - 1] && row[i - 2] && row[i] === ' ' && row[i - 1] === '|' && row[i - 2] === '_'));
|
||||||
|
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const genNewFlow = function () {
|
||||||
|
let newId;
|
||||||
|
|
||||||
|
do {
|
||||||
|
newId = genRandomStr();
|
||||||
|
} while (findFlow(newId) !== -1);
|
||||||
|
|
||||||
|
return { id: newId, color: `#${newId}` };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw methods
|
||||||
|
const drawLine = function (moveX, moveY, lineX, lineY, color) {
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(moveX, moveY);
|
||||||
|
ctx.lineTo(lineX, lineY);
|
||||||
|
ctx.stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawLineRight = function (x, y, color) {
|
||||||
|
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y + config.unitSize / 2, color);
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawLineUp = function (x, y, color) {
|
||||||
|
drawLine(x, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawNode = function (x, y, color) {
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
|
||||||
|
drawLineUp(x, y, color);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, config.nodeRadius, 0, Math.PI * 2, true);
|
||||||
|
ctx.fill();
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawLineIn = function (x, y, color) {
|
||||||
|
drawLine(x + config.unitSize, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawLineOut = function (x, y, color) {
|
||||||
|
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y - config.unitSize / 2, color);
|
||||||
|
};
|
||||||
|
|
||||||
|
const draw = function (graphList) {
|
||||||
|
let colomn, colomnIndex, prevColomn, condenseIndex, breakIndex = -1;
|
||||||
|
let x, y;
|
||||||
|
let color;
|
||||||
|
let nodePos;
|
||||||
|
let tempFlow;
|
||||||
|
let prevRowLength = 0;
|
||||||
|
let flowSwapPos = -1;
|
||||||
|
let lastLinePos;
|
||||||
|
let i, l;
|
||||||
|
let condenseCurrentLength, condensePrevLength = 0;
|
||||||
|
|
||||||
|
let inlineIntersect = false;
|
||||||
|
|
||||||
|
// initiate color array for first row
|
||||||
|
for (i = 0, l = graphList[0].length; i < l; i++) {
|
||||||
|
if (graphList[0][i] !== '_' && graphList[0][i] !== ' ') {
|
||||||
|
flows.push(genNewFlow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y = (canvas.height / ratio) - config.unitSize * 0.5;
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
for (i = 0, l = graphList.length; i < l; i++) {
|
||||||
|
x = config.unitSize * 0.5;
|
||||||
|
|
||||||
|
const currentRow = graphList[i];
|
||||||
|
const nextRow = graphList[i + 1];
|
||||||
|
const prevRow = graphList[i - 1];
|
||||||
|
|
||||||
|
flowSwapPos = -1;
|
||||||
|
|
||||||
|
condenseCurrentLength = currentRow.filter((val) => {
|
||||||
|
return (val !== ' ' && val !== '_');
|
||||||
|
}).length;
|
||||||
|
|
||||||
|
// pre process begin
|
||||||
|
// use last row for analysing
|
||||||
|
if (prevRow) {
|
||||||
|
if (!inlineIntersect) {
|
||||||
|
// intersect might happen
|
||||||
|
for (colomnIndex = 0; colomnIndex < prevRowLength; colomnIndex++) {
|
||||||
|
if (prevRow[colomnIndex + 1]
|
||||||
|
&& (prevRow[colomnIndex] === '/' && prevRow[colomnIndex + 1] === '|')
|
||||||
|
|| ((prevRow[colomnIndex] === '_' && prevRow[colomnIndex + 1] === '|')
|
||||||
|
&& (prevRow[colomnIndex + 2] === '/'))) {
|
||||||
|
flowSwapPos = colomnIndex;
|
||||||
|
|
||||||
|
// swap two flow
|
||||||
|
tempFlow = { id: flows[flowSwapPos].id, color: flows[flowSwapPos].color };
|
||||||
|
|
||||||
|
flows[flowSwapPos].id = flows[flowSwapPos + 1].id;
|
||||||
|
flows[flowSwapPos].color = flows[flowSwapPos + 1].color;
|
||||||
|
|
||||||
|
flows[flowSwapPos + 1].id = tempFlow.id;
|
||||||
|
flows[flowSwapPos + 1].color = tempFlow.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condensePrevLength < condenseCurrentLength
|
||||||
|
&& ((nodePos = findColomn('*', currentRow)) !== -1
|
||||||
|
&& (findColomn('_', currentRow) === -1))) {
|
||||||
|
flows.splice(nodePos - 1, 0, genNewFlow());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevRowLength > currentRow.length
|
||||||
|
&& (nodePos = findColomn('*', prevRow)) !== -1) {
|
||||||
|
if (findColomn('_', currentRow) === -1
|
||||||
|
&& findColomn('/', currentRow) === -1
|
||||||
|
&& findColomn('\\', currentRow) === -1) {
|
||||||
|
flows.splice(nodePos + 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // done with the previous row
|
||||||
|
|
||||||
|
prevRowLength = currentRow.length; // store for next round
|
||||||
|
colomnIndex = 0; // reset index
|
||||||
|
condenseIndex = 0;
|
||||||
|
condensePrevLength = 0;
|
||||||
|
breakIndex = -1; // reset break index
|
||||||
|
while (colomnIndex < currentRow.length) {
|
||||||
|
colomn = currentRow[colomnIndex];
|
||||||
|
|
||||||
|
if (colomn !== ' ' && colomn !== '_') {
|
||||||
|
++condensePrevLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check and fix line break in next row
|
||||||
|
if (colomn === '/' && currentRow[colomnIndex - 1] && currentRow[colomnIndex - 1] === '|') {
|
||||||
|
if ((breakIndex = findLineBreak(nextRow)) !== -1) {
|
||||||
|
nextRow.splice(breakIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if line break found replace all '/' with '|' after breakIndex in previous row
|
||||||
|
if (breakIndex !== -1 && colomn === '/' && colomnIndex > breakIndex) {
|
||||||
|
currentRow[colomnIndex] = '|';
|
||||||
|
colomn = '|';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colomn === ' '
|
||||||
|
&& currentRow[colomnIndex + 1]
|
||||||
|
&& currentRow[colomnIndex + 1] === '_'
|
||||||
|
&& currentRow[colomnIndex - 1]
|
||||||
|
&& currentRow[colomnIndex - 1] === '|') {
|
||||||
|
currentRow.splice(colomnIndex, 1);
|
||||||
|
|
||||||
|
currentRow[colomnIndex] = '/';
|
||||||
|
colomn = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new flow only when no intersect happened
|
||||||
|
if (flowSwapPos === -1
|
||||||
|
&& colomn === '/'
|
||||||
|
&& currentRow[colomnIndex - 1]
|
||||||
|
&& currentRow[colomnIndex - 1] === '|') {
|
||||||
|
flows.splice(condenseIndex, 0, genNewFlow());
|
||||||
|
}
|
||||||
|
|
||||||
|
// change \ and / to | when it's in the last position of the whole row
|
||||||
|
if (colomn === '/' || colomn === '\\') {
|
||||||
|
if (!(colomn === '/' && findBranchOut(nextRow) === -1)) {
|
||||||
|
if ((lastLinePos = Math.max(findColomn('|', currentRow),
|
||||||
|
findColomn('*', currentRow))) !== -1
|
||||||
|
&& (lastLinePos < colomnIndex - 1)) {
|
||||||
|
while (currentRow[++lastLinePos] === ' ');
|
||||||
|
|
||||||
|
if (lastLinePos === colomnIndex) {
|
||||||
|
currentRow[colomnIndex] = '|';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colomn === '*'
|
||||||
|
&& prevRow
|
||||||
|
&& prevRow[condenseIndex + 1] === '\\') {
|
||||||
|
flows.splice(condenseIndex + 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colomn !== ' ') {
|
||||||
|
++condenseIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
++colomnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
condenseCurrentLength = currentRow.filter((val) => {
|
||||||
|
return (val !== ' ' && val !== '_');
|
||||||
|
}).length;
|
||||||
|
|
||||||
|
// do some clean up
|
||||||
|
if (flows.length > condenseCurrentLength) {
|
||||||
|
flows.splice(condenseCurrentLength, flows.length - condenseCurrentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
colomnIndex = 0;
|
||||||
|
|
||||||
|
// a little inline analysis and draw process
|
||||||
|
while (colomnIndex < currentRow.length) {
|
||||||
|
colomn = currentRow[colomnIndex];
|
||||||
|
prevColomn = currentRow[colomnIndex - 1];
|
||||||
|
|
||||||
|
if (currentRow[colomnIndex] === ' ') {
|
||||||
|
currentRow.splice(colomnIndex, 1);
|
||||||
|
x += config.unitSize;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inline interset
|
||||||
|
if ((colomn === '_' || colomn === '/')
|
||||||
|
&& currentRow[colomnIndex - 1] === '|'
|
||||||
|
&& currentRow[colomnIndex - 2] === '_') {
|
||||||
|
inlineIntersect = true;
|
||||||
|
|
||||||
|
tempFlow = flows.splice(colomnIndex - 2, 1)[0];
|
||||||
|
flows.splice(colomnIndex - 1, 0, tempFlow);
|
||||||
|
currentRow.splice(colomnIndex - 2, 1);
|
||||||
|
|
||||||
|
colomnIndex -= 1;
|
||||||
|
} else {
|
||||||
|
inlineIntersect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = flows[colomnIndex].color;
|
||||||
|
|
||||||
|
switch (colomn) {
|
||||||
|
case '_':
|
||||||
|
drawLineRight(x, y, color);
|
||||||
|
|
||||||
|
x += config.unitSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
drawNode(x, y, color);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '|':
|
||||||
|
drawLineUp(x, y, color);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
if (prevColomn
|
||||||
|
&& (prevColomn === '/'
|
||||||
|
|| prevColomn === ' ')) {
|
||||||
|
x -= config.unitSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLineOut(x, y, color);
|
||||||
|
|
||||||
|
x += config.unitSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
drawLineIn(x, y, color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++colomnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
y -= config.unitSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
draw(graphList);
|
||||||
|
}
|
||||||
|
// @end-license
|
||||||
+23
-4
@@ -4,17 +4,24 @@ const TerserPlugin = require('terser-webpack-plugin');
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
entry: {
|
entry: {
|
||||||
index: ['./web_src/js/index', './web_src/js/draw']
|
index: ['./web_src/js/index']
|
||||||
},
|
},
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'public/js'),
|
path: path.resolve(__dirname, 'public/js'),
|
||||||
filename: 'index.js'
|
filename: 'index.js',
|
||||||
|
chunkFilename: '[name].js',
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: true,
|
minimize: true,
|
||||||
minimizer: [new TerserPlugin({
|
minimizer: [new TerserPlugin({
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
|
extractComments: false,
|
||||||
|
terserOptions: {
|
||||||
|
output: {
|
||||||
|
comments: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
})],
|
})],
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
@@ -33,10 +40,22 @@ module.exports = {
|
|||||||
corejs: 3,
|
corejs: 3,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
],
|
||||||
|
plugins: [
|
||||||
|
[
|
||||||
|
'@babel/plugin-transform-runtime',
|
||||||
|
{
|
||||||
|
regenerator: true,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/i,
|
||||||
|
use: ['style-loader', 'css-loader'],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user