mirror of
				https://gitcode.com/gitea/gitea.git
				synced 2025-11-01 01:36:12 +08:00 
			
		
		
		
	Reorganize frontend files and tooling (#10168)
- move "vendor" files to js/vendor and less/vendor - move swagger to js/standalone (meant for standalone pages) - move gitgraph to features and streamline its loading - add linting configs to webpack dependencies in make - set ignored files for eslint/stylelint directly in their configs Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										424
									
								
								web_src/js/vendor/gitGraph.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										424
									
								
								web_src/js/vendor/gitGraph.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,424 @@ | ||||
| /* This is a customized version of https://github.com/bluef/gitgraph.js/blob/master/gitgraph.js | ||||
|    Changes include conversion to ES6 and linting fixes */ | ||||
|  | ||||
| /* | ||||
|  * @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 // eslint-disable-line no-cond-assign | ||||
|           && (findColomn('_', currentRow) === -1))) { | ||||
|           flows.splice(nodePos - 1, 0, genNewFlow()); | ||||
|         } | ||||
|  | ||||
|         if (prevRowLength > currentRow.length | ||||
|           && (nodePos = findColomn('*', prevRow)) !== -1) { // eslint-disable-line no-cond-assign | ||||
|           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 | ||||
		Reference in New Issue
	
	Block a user
	 silverwind
					silverwind