move semantic.dropdown.custom.js to webpack (#9064)
* move semantic.dropdown.custom.js to webpack Also disabled a annoying linter rule which insisted that imports can not contain a file extension. Fixes: https://github.com/go-gitea/gitea/issues/8971 * reorganize web_src files and rebuild * restart ci
This commit is contained in:
parent
f0aaffeedc
commit
7bc8c6b180
16 changed files with 455 additions and 468 deletions
|
@ -1,16 +1,426 @@
|
|||
$(async () => {
|
||||
const graphCanvas = document.getElementById('graph-canvas');
|
||||
if (!graphCanvas) return;
|
||||
/* This is a customized version of https://github.com/bluef/gitgraph.js/blob/master/gitgraph.js
|
||||
Changes include conversion to ES6 and linting fixes */
|
||||
|
||||
const [{ default: gitGraph }] = await Promise.all([
|
||||
import(/* webpackChunkName: "gitgraph" */'../vendor/gitgraph.js/gitgraph.custom.js'),
|
||||
import(/* webpackChunkName: "gitgraph" */'../vendor/gitgraph.js/gitgraph.custom.css'),
|
||||
]);
|
||||
/*
|
||||
* @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 = [];
|
||||
$('#graph-raw-list li span.node-relation').each(function () {
|
||||
graphList.push($(this).text());
|
||||
});
|
||||
|
||||
gitGraph(graphCanvas, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line */
|
||||
if (condensePrevLength < condenseCurrentLength
|
||||
&& ((nodePos = findColomn('*', currentRow)) !== -1
|
||||
&& (findColomn('_', currentRow) === -1))) {
|
||||
flows.splice(nodePos - 1, 0, genNewFlow());
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line */
|
||||
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] === '|') {
|
||||
/* eslint-disable-next-line */
|
||||
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)) {
|
||||
/* eslint-disable-next-line */
|
||||
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
|
||||
|
|
16
web_src/js/gitGraphLoader.js
Normal file
16
web_src/js/gitGraphLoader.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
$(async () => {
|
||||
const graphCanvas = document.getElementById('graph-canvas');
|
||||
if (!graphCanvas) return;
|
||||
|
||||
const [{ default: gitGraph }] = await Promise.all([
|
||||
import(/* webpackChunkName: "gitgraph" */'./gitGraph.js'),
|
||||
import(/* webpackChunkName: "gitgraph" */'../css/gitGraph.css'),
|
||||
]);
|
||||
|
||||
const graphList = [];
|
||||
$('#graph-raw-list li span.node-relation').each(function () {
|
||||
graphList.push($(this).text());
|
||||
});
|
||||
|
||||
gitGraph(graphCanvas, graphList);
|
||||
});
|
|
@ -2,8 +2,9 @@
|
|||
/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */
|
||||
/* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */
|
||||
|
||||
import './publicPath';
|
||||
import './gitGraph';
|
||||
import './publicPath.js';
|
||||
import './gitGraphLoader.js';
|
||||
import './semanticDropdown.js';
|
||||
|
||||
function htmlEncode(text) {
|
||||
return jQuery('<div />').text(text).html();
|
||||
|
|
4026
web_src/js/semanticDropdown.js
Normal file
4026
web_src/js/semanticDropdown.js
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue