* setup eslint

* fix eslint issues

* add lint check in PR checks
This commit is contained in:
James Yeung 2024-02-27 12:42:10 +08:00 коммит произвёл GitHub
Родитель 62677fd11e
Коммит d6bb7be446
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
25 изменённых файлов: 4812 добавлений и 1007 удалений

1
.github/workflows/pull-request.yml поставляемый
Просмотреть файл

@ -49,6 +49,7 @@ jobs:
- name: Test 📝 - name: Test 📝
run: | run: |
npm run lint
dotnet test ./tests/AntDesign.Tests/AntDesign.Tests.csproj --configuration:Release --collect:"XPlat Code Coverage" dotnet test ./tests/AntDesign.Tests/AntDesign.Tests.csproj --configuration:Release --collect:"XPlat Code Coverage"
npm install ./tests/AntDesign.Tests.Js npm install ./tests/AntDesign.Tests.Js
npm --prefix ./tests/AntDesign.Tests.Js run test-cov npm --prefix ./tests/AntDesign.Tests.Js run test-cov

20
components/.eslintrc Normal file
Просмотреть файл

@ -0,0 +1,20 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"indent": [
"error",
2,
{ "ignoreComments": true }
]
}
}

Просмотреть файл

@ -1,12 +1,10 @@
import { infoHelper as domInfoHelper } from '../modules/dom/infoHelper'; import { infoHelper as domInfoHelper } from '../modules/dom/infoHelper';
export class intersectionObserver { export class intersectionObserver {
// @ts-ignore: TS2304: Cannot find name 'IntersectionObserver'
private static intersectionObservers: Map<string, IntersectionObserver> = new Map<string, IntersectionObserver>(); private static intersectionObservers: Map<string, IntersectionObserver> = new Map<string, IntersectionObserver>();
static create(key: string, invoker, isDotNetInvoker: boolean = true) { static create(key: string, invoker, isDotNetInvoker: boolean = true) {
// @ts-ignore: TS2304: Cannot find name 'IntersectionObserver'
let observer; let observer;
if (isDotNetInvoker) { if (isDotNetInvoker) {
@ -17,10 +15,11 @@ export class intersectionObserver {
intersectionObserver.intersectionObservers.set(key, observer) intersectionObserver.intersectionObservers.set(key, observer)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static observe(key: string, element, options?: IntersectionObserverInit) { static observe(key: string, element, options?: IntersectionObserverInit) {
const observer = intersectionObserver.intersectionObservers.get(key); const observer = intersectionObserver.intersectionObservers.get(key);
if (observer) { if (observer) {
let domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
observer.observe(domElement); observer.observe(domElement);
} }
} }

Просмотреть файл

@ -1,12 +1,9 @@
import { infoHelper as domInfoHelper } from '../modules/dom/infoHelper'; import { infoHelper as domInfoHelper } from '../modules/dom/infoHelper';
export class mutationObserver { export class mutationObserver {
// @ts-ignore: TS2304: Cannot find name 'MutationObserver'
private static mutationObservers: Map<string, MutationObserver> = new Map<string, MutationObserver>(); private static mutationObservers: Map<string, MutationObserver> = new Map<string, MutationObserver>();
static create(key: string, invoker, isDotNetInvoker: boolean = true) { static create(key: string, invoker, isDotNetInvoker: boolean = true) {
// @ts-ignore: TS2304: Cannot find name 'MutationObserver'
let observer; let observer;
if (isDotNetInvoker) { if (isDotNetInvoker) {
@ -20,7 +17,7 @@ export class mutationObserver {
static observe(key: string, element, options?: MutationObserverInit) { static observe(key: string, element, options?: MutationObserverInit) {
const observer = mutationObserver.mutationObservers.get(key); const observer = mutationObserver.mutationObservers.get(key);
if (observer) { if (observer) {
let domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
observer.observe(domElement, options); observer.observe(domElement, options);
} }
} }

Просмотреть файл

@ -14,11 +14,9 @@ export class resizeObserver {
return "ResizeObserver" in window; return "ResizeObserver" in window;
} }
// @ts-ignore: TS2304: Cannot find name 'ResizeObserver'
private static resizeObservers: Map<string, ResizeObserver> = new Map<string, ResizeObserver>(); private static resizeObservers: Map<string, ResizeObserver> = new Map<string, ResizeObserver>();
static create(key, invoker, isDotNetInvoker: boolean = true ) { static create(key, invoker, isDotNetInvoker: boolean = true ) {
// @ts-ignore: TS2304: Cannot find name 'ResizeObserver'
let observer; let observer;
if (isDotNetInvoker) { if (isDotNetInvoker) {
@ -32,7 +30,7 @@ export class resizeObserver {
static observe(key: string, element) { static observe(key: string, element) {
const observer = resizeObserver.resizeObservers.get(key); const observer = resizeObserver.resizeObservers.get(key);
if (observer) { if (observer) {
let domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
observer.observe(domElement); observer.observe(domElement);
} }
} }
@ -48,7 +46,7 @@ export class resizeObserver {
const observer = this.resizeObservers.get(key) const observer = this.resizeObservers.get(key)
if (observer) { if (observer) {
let domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
observer.unobserve(domElement) observer.unobserve(domElement)
} }
} }

Просмотреть файл

@ -3,17 +3,17 @@ export * as observable from './ObservableApi/observableApi';
export { domInfoHelper, domTypes, domManipulationHelper, eventHelper } from './modules/dom/exports'; export { domInfoHelper, domTypes, domManipulationHelper, eventHelper } from './modules/dom/exports';
export { styleHelper } from './modules/styleHelper'; export { styleHelper } from './modules/styleHelper';
export { export {
backtopHelper, backtopHelper,
iconHelper, iconHelper,
imageHelper, imageHelper,
inputHelper, inputHelper,
mentionsHelper, mentionsHelper,
modalHelper, modalHelper,
overlayHelper, overlayHelper,
tableHelper, tableHelper,
uploadHelper, uploadHelper,
downloadHelper, downloadHelper,
watermarkHelper, watermarkHelper,
} from './modules/components/export' } from './modules/components/export'
@ -21,9 +21,6 @@ export { enableDraggable, disableDraggable, resetModalPosition } from "./modules
export { generate as generateColor } from "@ant-design/colors"; export { generate as generateColor } from "@ant-design/colors";
import {modalHelper} from './modules/components/export'
import {manipulationHelper}from './modules/dom/manipulationHelper'
export function log(text) { export function log(text) {
console.log(text); console.log(text);
} }

Просмотреть файл

@ -2,7 +2,7 @@
export class backtopHelper { export class backtopHelper {
static backTop(target: string) { static backTop(target: string) {
let dom = domInfoHelper.get(target); const dom = domInfoHelper.get(target);
if (dom) { if (dom) {
domManipulationHelper.slideTo(dom.scrollTop); domManipulationHelper.slideTo(dom.scrollTop);
} else { } else {

Просмотреть файл

@ -1,9 +1,9 @@
export class downloadHelper { export class downloadHelper {
static triggerFileDownload(fileName, url) { static triggerFileDownload(fileName, url) {
const anchorElement = document.createElement('a'); const anchorElement = document.createElement('a');
anchorElement.href = url; anchorElement.href = url;
anchorElement.download = fileName ?? ''; anchorElement.download = fileName ?? '';
anchorElement.click(); anchorElement.click();
anchorElement.remove(); anchorElement.remove();
} }
} }

Просмотреть файл

@ -1,56 +1,56 @@
export class imageHelper { export class imageHelper {
static imgDragAndDrop(element: HTMLImageElement): void { static imgDragAndDrop(element: HTMLImageElement): void {
if (!element) { if (!element) {
throw new Error('Element not found.'); throw new Error('Element not found.');
} }
let mouseX: number, mouseY: number, imgX: number, imgY: number; let mouseX: number, mouseY: number, imgX: number, imgY: number;
let isDragging = false; let isDragging = false;
function handleMouseDown(event: MouseEvent) { function handleMouseDown(event: MouseEvent) {
mouseX = event.clientX; mouseX = event.clientX;
mouseY = event.clientY; mouseY = event.clientY;
imgX = element.offsetLeft; imgX = element.offsetLeft;
imgY = element.offsetTop; imgY = element.offsetTop;
isDragging = true; isDragging = true;
element.style.cursor = 'grabbing'; element.style.cursor = 'grabbing';
document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp); document.addEventListener('mouseup', handleMouseUp);
} }
function handleMouseMove(event: MouseEvent) { function handleMouseMove(event: MouseEvent) {
if (isDragging) { if (isDragging) {
const deltaX = event.clientX - mouseX; const deltaX = event.clientX - mouseX;
const deltaY = event.clientY - mouseY; const deltaY = event.clientY - mouseY;
element.style.left = imgX + deltaX + 'px'; element.style.left = imgX + deltaX + 'px';
element.style.top = imgY + deltaY + 'px'; element.style.top = imgY + deltaY + 'px';
} }
} }
function handleMouseUp() { function handleMouseUp() {
if (isDragging) { if (isDragging) {
isDragging = false; isDragging = false;
element.style.cursor = 'grab'; element.style.cursor = 'grab';
document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp); document.removeEventListener('mouseup', handleMouseUp);
} }
} }
element.addEventListener('mousedown', handleMouseDown); element.addEventListener('mousedown', handleMouseDown);
element.addEventListener('dragstart', (event: DragEvent) => { element.addEventListener('dragstart', (event: DragEvent) => {
event.preventDefault(); event.preventDefault();
}); });
// Handle mouse leaving window // Handle mouse leaving window
window.addEventListener('mouseout', (event: MouseEvent) => { window.addEventListener('mouseout', (event: MouseEvent) => {
if (event.target === document.body || event.target === document.documentElement) { if (event.target === document.body || event.target === document.documentElement) {
handleMouseUp(); handleMouseUp();
} }
}); });
} }
} }

Просмотреть файл

@ -6,8 +6,8 @@ export class inputHelper {
static getTextAreaInfo(element) { static getTextAreaInfo(element) {
if (!element) return null; if (!element) return null;
var result = {}; const result = {};
var dom = domInfoHelper.get(element); const dom = domInfoHelper.get(element);
if (!dom) return null; if (!dom) return null;
result["scrollHeight"] = dom.scrollHeight || 0; result["scrollHeight"] = dom.scrollHeight || 0;
@ -59,21 +59,21 @@ export class inputHelper {
} }
static resizeTextArea(element: HTMLTextAreaElement, minRows: number, maxRows: number) { static resizeTextArea(element: HTMLTextAreaElement, minRows: number, maxRows: number) {
let dims = this.getTextAreaInfo(element); const dims = this.getTextAreaInfo(element);
if (!dims) return; if (!dims) return;
let rowHeight = dims["lineHeight"]; const rowHeight = dims["lineHeight"];
let offsetHeight = dims["paddingTop"] + dims["paddingBottom"] + dims["borderTop"] + dims["borderBottom"]; const offsetHeight = dims["paddingTop"] + dims["paddingBottom"] + dims["borderTop"] + dims["borderBottom"];
let oldHeight = parseFloat(element.style.height); const oldHeight = parseFloat(element.style.height);
//use rows attribute to evaluate real scroll height //use rows attribute to evaluate real scroll height
let oldRows = element.rows; const oldRows = element.rows;
element.rows = minRows; element.rows = minRows;
element.style.height = 'auto'; element.style.height = 'auto';
var rows = Math.trunc(element.scrollHeight / rowHeight); let rows = Math.trunc(element.scrollHeight / rowHeight);
element.rows = oldRows; element.rows = oldRows;
rows = Math.max(minRows, rows); rows = Math.max(minRows, rows);
var newHeight = 0; let newHeight = 0;
if (rows > maxRows) { if (rows > maxRows) {
rows = maxRows; rows = maxRows;
@ -87,14 +87,14 @@ export class inputHelper {
element.style.overflowY = "hidden"; element.style.overflowY = "hidden";
} }
if (oldHeight !== newHeight) { if (oldHeight !== newHeight) {
let textAreaObj = state.objReferenceDict[element.id]; const textAreaObj = state.objReferenceDict[element.id];
textAreaObj.invokeMethodAsync("ChangeSizeAsyncJs", element.scrollWidth, newHeight); textAreaObj.invokeMethodAsync("ChangeSizeAsyncJs", element.scrollWidth, newHeight);
} }
} }
static setSelectionStart(element, position: number) { static setSelectionStart(element, position: number) {
if (position >= 0) { if (position >= 0) {
let dom: HTMLInputElement = domInfoHelper.get(element); const dom: HTMLInputElement = domInfoHelper.get(element);
if (dom) { if (dom) {
if (position <= dom.value.length) { if (position <= dom.value.length) {
dom.selectionStart = position; dom.selectionStart = position;

Просмотреть файл

@ -1,80 +1,80 @@
export class mentionsHelper { export class mentionsHelper {
private static isPopShowFlag: boolean; private static isPopShowFlag: boolean;
public static setPopShowFlag = function (show: boolean): void { public static setPopShowFlag = function (show: boolean): void {
mentionsHelper.isPopShowFlag = show; mentionsHelper.isPopShowFlag = show;
} }
public static setEditorKeyHandler = function (Mentions: any, element: HTMLTextAreaElement): void { public static setEditorKeyHandler = function (Mentions: any, element: HTMLTextAreaElement): void {
var textArea = mentionsHelper.getTextarea(element); const textArea = mentionsHelper.getTextarea(element);
textArea.onkeydown = async (ev): Promise<any> => { textArea.onkeydown = async (ev): Promise<any> => {
//判断isPopShow不能用异步方法 //判断isPopShow不能用异步方法
if (!mentionsHelper.isPopShowFlag) return; if (!mentionsHelper.isPopShowFlag) return;
if (ev.key == "ArrowUp") { if (ev.key == "ArrowUp") {
ev.preventDefault(); ev.preventDefault();
await Mentions.invokeMethodAsync("PrevOption"); await Mentions.invokeMethodAsync("PrevOption");
} else if (ev.key == "ArrowDown") { } else if (ev.key == "ArrowDown") {
ev.preventDefault(); ev.preventDefault();
await Mentions.invokeMethodAsync("NextOption"); await Mentions.invokeMethodAsync("NextOption");
} }
else if (ev.key == "Enter") { else if (ev.key == "Enter") {
ev.preventDefault(); ev.preventDefault();
await Mentions.invokeMethodAsync("EnterOption"); await Mentions.invokeMethodAsync("EnterOption");
} }
//其他按键在c#中处理 //其他按键在c#中处理
}
} }
}
public static getProp = function (e: HTMLElement, propName: string): any { public static getProp = function (e: HTMLElement, propName: string): any {
var textArea = mentionsHelper.getTextarea(e); const textArea = mentionsHelper.getTextarea(e);
return textArea[propName]; return textArea[propName];
} }
public static getCursorXY = function (element: HTMLElement) { public static getCursorXY = function (element: HTMLElement) {
var textArea = mentionsHelper.getTextarea(element); const textArea = mentionsHelper.getTextarea(element);
let format = function (value) { const format = function (value) {
value = value.replace(/<|>|`|"|&/g, '?'); value = value.replace(/<|>|`|"|&/g, '?');
return value; return value;
}; };
let inputorValue = textArea.value; const inputorValue = textArea.value;
let pos = textArea.selectionStart; const pos = textArea.selectionStart;
let start_range = inputorValue.slice(0, pos); let start_range = inputorValue.slice(0, pos);
if (start_range.length > 0) start_range = start_range.substring(0, start_range.length - 1); if (start_range.length > 0) start_range = start_range.substring(0, start_range.length - 1);
let end_range = inputorValue.slice(pos); const end_range = inputorValue.slice(pos);
let html = format(start_range); let html = format(start_range);
html += "<span>@</span>"; html += "<span>@</span>";
html += format(end_range); html += format(end_range);
let div_mirror = document.createElement("div"); const div_mirror = document.createElement("div");
div_mirror.className = "ant-mentions-measure" div_mirror.className = "ant-mentions-measure"
div_mirror.innerHTML = html; div_mirror.innerHTML = html;
textArea.parentNode.append(div_mirror); textArea.parentNode.append(div_mirror);
let flag: HTMLSpanElement = div_mirror.querySelector("span"); const flag: HTMLSpanElement = div_mirror.querySelector("span");
// let flagPos = flag.getBoundingClientRect(); // let flagPos = flag.getBoundingClientRect();
// let textAreaPos = textArea.getBoundingClientRect(); // let textAreaPos = textArea.getBoundingClientRect();
// let bodyPos = document.body.getBoundingClientRect(); // let bodyPos = document.body.getBoundingClientRect();
let left = flag.offsetLeft - textArea.scrollLeft + 16; const left = flag.offsetLeft - textArea.scrollLeft + 16;
let top = flag.offsetTop - textArea.scrollTop + 16; const top = flag.offsetTop - textArea.scrollTop + 16;
div_mirror.remove(); div_mirror.remove();
return [left, top]; return [left, top];
}; };
private static getTextarea(element: HTMLElement) { private static getTextarea(element: HTMLElement) {
const textAreaTag = "TEXTAREA"; const textAreaTag = "TEXTAREA";
var textarea = element; let textarea = element;
if (element.tagName != textAreaTag) { if (element.tagName != textAreaTag) {
var allTextareas = element.getElementsByTagName(textAreaTag); const allTextareas = element.getElementsByTagName(textAreaTag);
if (allTextareas.length == 0) { if (allTextareas.length == 0) {
throw "Mentions requires a textarea to be rendered, but none were found."; throw "Mentions requires a textarea to be rendered, but none were found.";
} }
textarea = allTextareas[0] as HTMLTextAreaElement; textarea = allTextareas[0] as HTMLTextAreaElement;
}
return textarea as HTMLTextAreaElement;
} }
return textarea as HTMLTextAreaElement;
}
} }

Просмотреть файл

@ -3,15 +3,15 @@ import { manipulationHelper } from '../dom/manipulationHelper'
export class modalHelper { export class modalHelper {
static focusDialog(selector: string, count: number = 0) { static focusDialog(selector: string, count: number = 0) {
let ele = <HTMLElement>document.querySelector(selector); const ele = <HTMLElement>document.querySelector(selector);
if (ele) { if (ele) {
if (ele.hasAttribute("disabled")) { if (ele.hasAttribute("disabled")) {
let htmlElement = <HTMLElement>document.activeElement; const htmlElement = <HTMLElement>document.activeElement;
htmlElement?.blur(); htmlElement?.blur();
} else { } else {
setTimeout(() => { setTimeout(() => {
ele.focus(); ele.focus();
let curId = "#" + domInfoHelper.getActiveElement(); const curId = "#" + domInfoHelper.getActiveElement();
if (curId !== selector) { if (curId !== selector) {
if (count < 10) { if (count < 10) {
this.focusDialog(selector, count + 1); this.focusDialog(selector, count + 1);
@ -24,7 +24,7 @@ export class modalHelper {
static destroyAllDialog() { static destroyAllDialog() {
document.querySelectorAll(".ant-modal-root").forEach((e) => { document.querySelectorAll(".ant-modal-root").forEach((e) => {
let container = e.parentNode; const container = e.parentNode;
if (container instanceof HTMLElement) { if (container instanceof HTMLElement) {
container.remove(); container.remove();
} }

Просмотреть файл

@ -1,4 +1,5 @@
import { domInfoHelper, domTypes } from '../dom/exports' /* eslint-disable @typescript-eslint/no-unused-vars */
import { domInfoHelper, domTypes } from '../dom/exports'
import { resize } from '../../ObservableApi/observableApi'; import { resize } from '../../ObservableApi/observableApi';
import { mutationObserver as mutation } from '../../ObservableApi/mutationObserver'; import { mutationObserver as mutation } from '../../ObservableApi/mutationObserver';
@ -58,23 +59,24 @@ export type overlayPosition = {
} }
export class Overlay { export class Overlay {
private static appliedStylePositionMap: Map<Placement, private static appliedStylePositionMap: Map<Placement,
{ horizontal: "left" | "right", vertical: "top" | "bottom", class: string }> = { horizontal: "left" | "right", vertical: "top" | "bottom", class: string }> =
new Map([ new Map([
[Placement.TopLeft, { horizontal: "left", vertical: "bottom", class: "topLeft" }], [Placement.TopLeft, { horizontal: "left", vertical: "bottom", class: "topLeft" }],
[Placement.Top, { horizontal: "left", vertical: "bottom", class: "top" }], [Placement.Top, { horizontal: "left", vertical: "bottom", class: "top" }],
[Placement.TopRight, { horizontal: "right", vertical: "bottom", class: "topRight" }], [Placement.TopRight, { horizontal: "right", vertical: "bottom", class: "topRight" }],
[Placement.Left, { horizontal: "right", vertical: "top", class: "left" }], [Placement.Left, { horizontal: "right", vertical: "top", class: "left" }],
[Placement.LeftTop, { horizontal: "right", vertical: "top", class: "leftTop" }], [Placement.LeftTop, { horizontal: "right", vertical: "top", class: "leftTop" }],
[Placement.LeftBottom, { horizontal: "right", vertical: "bottom", class: "leftBottom" }], [Placement.LeftBottom, { horizontal: "right", vertical: "bottom", class: "leftBottom" }],
[Placement.Right, { horizontal: "left", vertical: "top", class: "right" }], [Placement.Right, { horizontal: "left", vertical: "top", class: "right" }],
[Placement.RightTop, { horizontal: "left", vertical: "top", class: "rightTop" }], [Placement.RightTop, { horizontal: "left", vertical: "top", class: "rightTop" }],
[Placement.RightBottom, { horizontal: "left", vertical: "bottom", class: "rightBottom" }], [Placement.RightBottom, { horizontal: "left", vertical: "bottom", class: "rightBottom" }],
[Placement.BottomLeft, { horizontal: "left", vertical: "top", class: "bottomLeft" }], [Placement.BottomLeft, { horizontal: "left", vertical: "top", class: "bottomLeft" }],
[Placement.Bottom, { horizontal: "left", vertical: "top", class: "bottom" }], [Placement.Bottom, { horizontal: "left", vertical: "top", class: "bottom" }],
[Placement.BottomRight, { horizontal: "right", vertical: "top", class: "bottomRight" }], [Placement.BottomRight, { horizontal: "right", vertical: "top", class: "bottomRight" }],
]); ]);
// eslint-disable-next-line @typescript-eslint/ban-types
private static reverseVerticalPlacementMap: Map<Placement, Function> = private static reverseVerticalPlacementMap: Map<Placement, Function> =
new Map([ new Map([
[Placement.TopLeft, (position: string) => Placement.BottomLeft], [Placement.TopLeft, (position: string) => Placement.BottomLeft],
@ -91,6 +93,7 @@ export class Overlay {
[Placement.BottomRight, (position: string) => Placement.TopRight] [Placement.BottomRight, (position: string) => Placement.TopRight]
]); ]);
// eslint-disable-next-line @typescript-eslint/ban-types
private static reverseHorizontalPlacementMap: Map<Placement, Function> = private static reverseHorizontalPlacementMap: Map<Placement, Function> =
new Map([ new Map([
[Placement.TopLeft, (position: string) => Placement.TopRight], [Placement.TopLeft, (position: string) => Placement.TopRight],
@ -235,56 +238,56 @@ export class Overlay {
static setVerticalCalculation(placement: Placement, position: "top" | "bottom") { static setVerticalCalculation(placement: Placement, position: "top" | "bottom") {
if (position === "top") { if (position === "top") {
switch (placement) { switch (placement) {
case Placement.LeftTop: case Placement.LeftTop:
case Placement.RightTop: case Placement.RightTop:
return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) { return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) {
return { return {
top: triggerTop, top: triggerTop,
bottom: Overlay.reversePositionValue(triggerTop, container.scrollHeight, overlayHeight) bottom: Overlay.reversePositionValue(triggerTop, container.scrollHeight, overlayHeight)
};
}; };
case Placement.BottomLeft: };
case Placement.Bottom: case Placement.BottomLeft:
case Placement.BottomRight: case Placement.Bottom:
return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) { case Placement.BottomRight:
const position: verticalPosition = { return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) {
top: triggerTop + triggerHeight + constraints.verticalOffset, const position: verticalPosition = {
}; top: triggerTop + triggerHeight + constraints.verticalOffset,
position.bottom = Overlay.reversePositionValue(position.top, container.scrollHeight, overlayHeight)
return position;
}; };
case Placement.Left: position.bottom = Overlay.reversePositionValue(position.top, container.scrollHeight, overlayHeight)
case Placement.Right: return position;
return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) { };
const position: verticalPosition = { case Placement.Left:
top: triggerTop + (triggerHeight / 2) - (overlayHeight / 2) case Placement.Right:
}; return function(triggerTop: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) {
position.bottom = Overlay.reversePositionValue(position.top, container.scrollHeight, overlayHeight) const position: verticalPosition = {
return position; top: triggerTop + (triggerHeight / 2) - (overlayHeight / 2)
}; };
position.bottom = Overlay.reversePositionValue(position.top, container.scrollHeight, overlayHeight)
return position;
};
} }
} }
if (position === "bottom") { if (position === "bottom") {
switch (placement) { switch (placement) {
case Placement.TopLeft: case Placement.TopLeft:
case Placement.Top: case Placement.Top:
case Placement.TopRight: case Placement.TopRight:
return function(triggerBottom: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) { return function(triggerBottom: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) {
const position: verticalPosition = { const position: verticalPosition = {
bottom: triggerBottom + triggerHeight + constraints.verticalOffset, bottom: triggerBottom + triggerHeight + constraints.verticalOffset,
};
position.top = Overlay.reversePositionValue(position.bottom, container.scrollHeight, overlayHeight);
return position;
}; };
case Placement.LeftBottom: position.top = Overlay.reversePositionValue(position.bottom, container.scrollHeight, overlayHeight);
case Placement.RightBottom: return position;
return function(triggerBottom: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) { };
const position: verticalPosition = { case Placement.LeftBottom:
bottom: triggerBottom, case Placement.RightBottom:
top: Overlay.reversePositionValue(triggerBottom, container.scrollHeight, overlayHeight) return function(triggerBottom: number, triggerHeight: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayHeight: number, constraints: overlayConstraints) {
}; const position: verticalPosition = {
return position; bottom: triggerBottom,
top: Overlay.reversePositionValue(triggerBottom, container.scrollHeight, overlayHeight)
}; };
return position;
};
} }
} }
//fallback - should not happen, but to avoid crashing scenarios, revert to BottomLeft //fallback - should not happen, but to avoid crashing scenarios, revert to BottomLeft
@ -295,57 +298,57 @@ export class Overlay {
static setHorizontalCalculation(placement: Placement, position: "left" | "right") { static setHorizontalCalculation(placement: Placement, position: "left" | "right") {
if (position === "left") { if (position === "left") {
switch (placement) { switch (placement) {
case Placement.TopLeft: case Placement.TopLeft:
case Placement.BottomLeft: case Placement.BottomLeft:
return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) { return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) {
return { return {
left: triggerLeft, left: triggerLeft,
right: Overlay.reversePositionValue(triggerLeft, container.scrollWidth, overlayWidth) right: Overlay.reversePositionValue(triggerLeft, container.scrollWidth, overlayWidth)
};
}; };
case Placement.Right: };
case Placement.RightTop: case Placement.Right:
case Placement.RightBottom: case Placement.RightTop:
return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) { case Placement.RightBottom:
const position: horizontalPosition = { return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) {
left: triggerLeft + triggerWidth + constraints.horizontalOffset const position: horizontalPosition = {
}; left: triggerLeft + triggerWidth + constraints.horizontalOffset
position.right = Overlay.reversePositionValue(position.left, container.scrollWidth, overlayWidth)
return position;
}; };
position.right = Overlay.reversePositionValue(position.left, container.scrollWidth, overlayWidth)
return position;
};
case Placement.Top: case Placement.Top:
case Placement.Bottom: case Placement.Bottom:
return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) { return function(triggerLeft: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) {
const position: horizontalPosition = { const position: horizontalPosition = {
left: triggerLeft + (triggerWidth / 2) - (overlayWidth / 2) left: triggerLeft + (triggerWidth / 2) - (overlayWidth / 2)
};
position.right = Overlay.reversePositionValue(position.left, container.scrollWidth, overlayWidth)
return position;
}; };
position.right = Overlay.reversePositionValue(position.left, container.scrollWidth, overlayWidth)
return position;
};
} }
} }
if (position === "right") { if (position === "right") {
switch (placement) { switch (placement) {
case Placement.TopRight: case Placement.TopRight:
case Placement.BottomRight: case Placement.BottomRight:
return function(triggerRight: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) { return function(triggerRight: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) {
let position: horizontalPosition = { const position: horizontalPosition = {
right: triggerRight, right: triggerRight,
left: Overlay.reversePositionValue(triggerRight, container.scrollWidth, overlayWidth) left: Overlay.reversePositionValue(triggerRight, container.scrollWidth, overlayWidth)
};
return position;
}; };
case Placement.Left: return position;
case Placement.LeftTop: };
case Placement.LeftBottom: case Placement.Left:
return function(triggerRight: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) { case Placement.LeftTop:
const position: horizontalPosition = { case Placement.LeftBottom:
right: triggerRight + triggerWidth + constraints.horizontalOffset return function(triggerRight: number, triggerWidth: number, container: domTypes.domInfo, trigger: domTypes.domInfo, overlayWidth: number, constraints: overlayConstraints) {
}; const position: horizontalPosition = {
position.left = Overlay.reversePositionValue(position.right, container.scrollWidth, overlayWidth) right: triggerRight + triggerWidth + constraints.horizontalOffset
return position;
}; };
position.left = Overlay.reversePositionValue(position.right, container.scrollWidth, overlayWidth)
return position;
};
} }
} }
//fallback - should not happen, but to avoid crashing scenarios, revert to BottomLeft //fallback - should not happen, but to avoid crashing scenarios, revert to BottomLeft
@ -366,10 +369,10 @@ export class Overlay {
} }
private removeHiddenClass() { private removeHiddenClass() {
let end = this.overlay.className.indexOf("-hidden"); const end = this.overlay.className.indexOf("-hidden");
let start = this.overlay.className.lastIndexOf(" ", end) const start = this.overlay.className.lastIndexOf(" ", end)
if (start >= 0) { if (start >= 0) {
let className = this.overlay.className.substr(start + 1, end); const className = this.overlay.className.substr(start + 1, end);
if (className !== "") { if (className !== "") {
this.overlay.classList.remove(className); this.overlay.classList.remove(className);
} }
@ -671,11 +674,11 @@ export class Overlay {
position: this.position, position: this.position,
sanitizedPosition: this.sanitizedPosition, sanitizedPosition: this.sanitizedPosition,
placment: { placment: {
initialPlacement: this.initialPlacement, initialPlacement: this.initialPlacement,
recentPlacement: this.recentPlacement, recentPlacement: this.recentPlacement,
placement: this.placement, placement: this.placement,
selectedHorizontalPosition: this.selectedHorizontalPosition, selectedHorizontalPosition: this.selectedHorizontalPosition,
selectedVerticalPosition: this.selectedVerticalPosition selectedVerticalPosition: this.selectedVerticalPosition
} }
} }
); );
@ -752,7 +755,7 @@ export class Overlay {
} else { } else {
currentPlacement = Overlay.appliedStylePositionMap.get(this.initialPlacement).class; currentPlacement = Overlay.appliedStylePositionMap.get(this.initialPlacement).class;
} }
let newPlacement = stringMach + Overlay.appliedStylePositionMap.get(this.placement).class; const newPlacement = stringMach + Overlay.appliedStylePositionMap.get(this.placement).class;
this.overlay.classList.replace(currentPlacement, newPlacement); this.overlay.classList.replace(currentPlacement, newPlacement);
} }
} }
@ -786,7 +789,7 @@ export class Overlay {
let position: verticalPosition; let position: verticalPosition;
//usually first offsetHeight is taken, as the measurement contains the borders //usually first offsetHeight is taken, as the measurement contains the borders
this.triggerPosition.height = this.triggerInfo.offsetHeight != 0 ? this.triggerInfo.offsetHeight this.triggerPosition.height = this.triggerInfo.offsetHeight != 0 ? this.triggerInfo.offsetHeight
: this.triggerInfo.clientHeight; : this.triggerInfo.clientHeight;
if (this.overlayPreset) { if (this.overlayPreset) {
this.triggerPosition.top = this.triggerInfo.absoluteTop + this.overlayPreset.y; this.triggerPosition.top = this.triggerInfo.absoluteTop + this.overlayPreset.y;
this.triggerPosition.height = 0; this.triggerPosition.height = 0;
@ -862,14 +865,14 @@ export class Overlay {
} }
private setBodyBoundayrSize() { private setBodyBoundayrSize() {
const window = domInfoHelper.getWindow(); const window = domInfoHelper.getWindow();
const scroll = domInfoHelper.getScroll(); const scroll = domInfoHelper.getScroll();
this.bodyBoundarySize = { this.bodyBoundarySize = {
top : scroll.y, top : scroll.y,
left: scroll.x, left: scroll.x,
right: window.innerWidth + scroll.x, right: window.innerWidth + scroll.x,
bottom: window.innerHeight + scroll.y bottom: window.innerHeight + scroll.y
}; };
} }
/** /**
@ -886,11 +889,11 @@ export class Overlay {
this.setBodyBoundayrSize(); this.setBodyBoundayrSize();
} }
return { return {
left: 0, left: 0,
right: this.containerInfo.scrollWidth, right: this.containerInfo.scrollWidth,
top: 0, top: 0,
bottom: this.containerInfo.scrollHeight bottom: this.containerInfo.scrollHeight
}; };
} }
this.setBodyBoundayrSize(); this.setBodyBoundayrSize();
@ -994,7 +997,7 @@ export class Overlay {
visibleWidthInBodyBeforeAdjustment = this.getOverlayVisibleWidth("body"); visibleWidthInBodyBeforeAdjustment = this.getOverlayVisibleWidth("body");
} else { } else {
visibleWidthInBodyBeforeAdjustment = visibleWidthBeforeAdjustment visibleWidthInBodyBeforeAdjustment = visibleWidthBeforeAdjustment
}; }
this.getHorizontalAdjustment(); this.getHorizontalAdjustment();
@ -1004,7 +1007,7 @@ export class Overlay {
visibleWidthInBodyAfterAdjustment = this.getOverlayVisibleWidth("body"); visibleWidthInBodyAfterAdjustment = this.getOverlayVisibleWidth("body");
} else { } else {
visibleWidthInBodyAfterAdjustment = visibleWidthAfterAdjustment visibleWidthInBodyAfterAdjustment = visibleWidthAfterAdjustment
}; }
if ( if (
!(visibleWidthInBodyBeforeAdjustment < visibleWidthInBodyAfterAdjustment !(visibleWidthInBodyBeforeAdjustment < visibleWidthInBodyAfterAdjustment
@ -1037,7 +1040,7 @@ export class Overlay {
visibleHeightInBodyBeforeAdjustment = this.getOverlayVisibleHeight("body"); visibleHeightInBodyBeforeAdjustment = this.getOverlayVisibleHeight("body");
} else { } else {
visibleHeightInBodyBeforeAdjustment = visibleHeightBeforeAdjustment visibleHeightInBodyBeforeAdjustment = visibleHeightBeforeAdjustment
}; }
this.getVerticalAdjustment(); this.getVerticalAdjustment();
@ -1047,7 +1050,7 @@ export class Overlay {
visibleHeightInBodyAfterAdjustment = this.getOverlayVisibleHeight("body"); visibleHeightInBodyAfterAdjustment = this.getOverlayVisibleHeight("body");
} else { } else {
visibleHeightInBodyAfterAdjustment = visibleHeightAfterAdjustment visibleHeightInBodyAfterAdjustment = visibleHeightAfterAdjustment
}; }
if ( if (
!(visibleHeightInBodyBeforeAdjustment < visibleHeightInBodyAfterAdjustment !(visibleHeightInBodyBeforeAdjustment < visibleHeightInBodyAfterAdjustment

Просмотреть файл

@ -17,9 +17,9 @@ export class overlayHelper {
if (!domManipulationHelper.addElementTo(overlaySelector, containerElement)) { if (!domManipulationHelper.addElementTo(overlaySelector, containerElement)) {
console.log("Failed to add overlay. Details:", { console.log("Failed to add overlay. Details:", {
triggerPrefixCls: triggerPrefixCls, triggerPrefixCls: triggerPrefixCls,
overlaySelector: overlaySelector, overlaySelector: overlaySelector,
containerElement: containerElement containerElement: containerElement
} ); } );
return null; return null;
} }
@ -50,17 +50,17 @@ export class overlayHelper {
const overlay = this.overlayRegistry[blazorId]; const overlay = this.overlayRegistry[blazorId];
if (overlay){ if (overlay){
let overlayPresets: domTypes.position; let overlayPresets: domTypes.position;
if (overlayTop || overlayLeft) { if (overlayTop || overlayLeft) {
overlayPresets = { x: overlayLeft, y: overlayTop }; overlayPresets = { x: overlayLeft, y: overlayTop };
} }
return overlay.calculatePosition(false, false, overlayPresets); return overlay.calculatePosition(false, false, overlayPresets);
} else { } else {
//When page is slow, it may happen that rendering of an overlay may not happen, even if //When page is slow, it may happen that rendering of an overlay may not happen, even if
//blazor thinks it did happen. In such a case, when overlay object is not found, just try //blazor thinks it did happen. In such a case, when overlay object is not found, just try
//to render it again. //to render it again.
return overlayHelper.addOverlayToContainer(blazorId, overlaySelector, triggerSelector, placement, containerSelector,triggerBoundyAdjustMode, triggerIsWrappedInDiv, triggerPrefixCls, return overlayHelper.addOverlayToContainer(blazorId, overlaySelector, triggerSelector, placement, containerSelector,triggerBoundyAdjustMode, triggerIsWrappedInDiv, triggerPrefixCls,
verticalOffset, horizontalOffset, arrowPointAtCenter, verticalOffset, horizontalOffset, arrowPointAtCenter,
overlayTop, overlayLeft); overlayTop, overlayLeft);
} }
} }

Просмотреть файл

@ -31,9 +31,9 @@
static SetScrollPositionClassName(bodyRef, wrapperRef) { static SetScrollPositionClassName(bodyRef, wrapperRef) {
let scrollLeft = bodyRef.scrollLeft; const scrollLeft = bodyRef.scrollLeft;
let scrollWidth = bodyRef.scrollWidth; const scrollWidth = bodyRef.scrollWidth;
let clientWidth = bodyRef.clientWidth; const clientWidth = bodyRef.clientWidth;
let pingLeft = false; let pingLeft = false;
let pingRight = false; let pingRight = false;

Просмотреть файл

@ -31,9 +31,9 @@ export class uploadHelper {
static getFileInfo(element: HTMLInputElement) { static getFileInfo(element: HTMLInputElement) {
if (element.files && element.files.length > 0) { if (element.files && element.files.length > 0) {
let fileInfo = Array<fileInfo>(); const fileInfo = Array<fileInfo>();
for (var i = 0; i < element.files.length; i++) { for (let i = 0; i < element.files.length; i++) {
let file = element.files[i]; const file = element.files[i];
const objectUrl = this.getObjectURL(file); const objectUrl = this.getObjectURL(file);
fileInfo.push({ fileInfo.push({
fileName: file.name, fileName: file.name,
@ -48,7 +48,7 @@ export class uploadHelper {
} }
private static getObjectURL(file: File): string { private static getObjectURL(file: File): string {
var url = null; let url = null;
if (window.URL != undefined) { if (window.URL != undefined) {
url = window.URL.createObjectURL(file); url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) { } else if (window.webkitURL != undefined) {
@ -58,12 +58,12 @@ export class uploadHelper {
} }
static uploadFile(element, index, data, headers, fileId, url, name, instance, percentMethod, successMethod, errorMethod, method: string) { static uploadFile(element, index, data, headers, fileId, url, name, instance, percentMethod, successMethod, errorMethod, method: string) {
let formData = new FormData(); const formData = new FormData();
var file = element.files[index]; const file = element.files[index];
var size = file.size; const size = file.size;
formData.append(name, file); formData.append(name, file);
if (data != null) { if (data != null) {
for (var key in data) { for (const key in data) {
formData.append(key, data[key]); formData.append(key, data[key]);
} }
} }
@ -80,15 +80,16 @@ export class uploadHelper {
} }
} }
req.upload.onprogress = function (event) { req.upload.onprogress = function (event) {
var percent = Math.floor(event.loaded / size * 100); const percent = Math.floor(event.loaded / size * 100);
instance.invokeMethodAsync(percentMethod, fileId, percent); instance.invokeMethodAsync(percentMethod, fileId, percent);
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
req.onerror = function (e) { req.onerror = function (e) {
instance.invokeMethodAsync(errorMethod, fileId, "error"); instance.invokeMethodAsync(errorMethod, fileId, "error");
} }
req.open(method, url, true) req.open(method, url, true)
if (headers != null) { if (headers != null) {
for (var header in headers) { for (const header in headers) {
req.setRequestHeader(header, headers[header]); req.setRequestHeader(header, headers[header]);
} }
} }

Просмотреть файл

@ -1,16 +1,16 @@
export class watermarkHelper { export class watermarkHelper {
static generateBase64Url({ static generateBase64Url({
width, width,
height, height,
gapX, gapX,
gapY, gapY,
offsetLeft, offsetLeft,
offsetTop, offsetTop,
rotate, rotate,
alpha, alpha,
watermarkContent, watermarkContent,
lineSpace, lineSpace,
}: { }: {
width: number, width: number,
height: number, height: number,
gapX: number, gapX: number,
@ -22,117 +22,118 @@
watermarkContent: WatermarkText | WatermarkImage | Array<WatermarkText | WatermarkImage>, watermarkContent: WatermarkText | WatermarkImage | Array<WatermarkText | WatermarkImage>,
lineSpace: number lineSpace: number
}, dotnetRef, watermarkContentRef: HTMLElement, watermarkRef: HTMLElement): string { }, dotnetRef, watermarkContentRef: HTMLElement, watermarkRef: HTMLElement): string {
const onFinish = (url: string) => { const onFinish = (url: string) => {
dotnetRef.invokeMethodAsync("load", url); dotnetRef.invokeMethodAsync("load", url);
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
// eslint-disable-next-line no-console
console.warn('Current environment does not support Canvas, cannot draw watermarks.');
onFinish('');
return;
}
const ratio = window.devicePixelRatio || 1;
const canvasWidth = (gapX + width) * ratio;
const canvasHeight = (gapY + height) * ratio;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.style.width = `${gapX + width}px`;
canvas.style.height = `${gapY + height}px`;
ctx.translate(offsetLeft * ratio, offsetTop * ratio);
ctx.rotate((Math.PI / 180) * Number(rotate));
ctx.globalAlpha = alpha;
const markWidth = width * ratio;
const markHeight = height * ratio;
ctx.fillStyle = 'transparent';
ctx.fillRect(0, 0, markWidth, markHeight);
const contents = Array.isArray(watermarkContent) ? watermarkContent : [{ ...watermarkContent }];
let top = 0;
contents.forEach((item: WatermarkText & WatermarkImage & { top: number }) => {
if (item.url) {
const { url, isGrayscale = false } = item;
// eslint-disable-next-line no-param-reassign
item.top = top;
top += height;
const img = new Image();
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.src = url;
img.onload = () => {
// ctx.filter = 'grayscale(1)';
ctx.drawImage(img, 0, item.top * ratio, width * ratio, height * ratio);
if (isGrayscale) {
const imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
const pixels = imgData.data;
for (let i = 0; i < pixels.length; i += 4) {
const lightness = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
pixels[i] = lightness;
pixels[i + 1] = lightness;
pixels[i + 2] = lightness;
}
ctx.putImageData(imgData, 0, 0);
}
onFinish(canvas.toDataURL());
};
} else if (item.text) {
const {
text,
fontColor = 'rgba(0, 0, 0, 0.1)',
fontSize = 16,
fontFamily = undefined,
fontWeight = 'normal',
textAlign = 'start',
fontStyle = 'normal'
} = item;
// eslint-disable-next-line no-param-reassign
item.top = top;
top += lineSpace;
const markSize = Number(fontSize) * ratio;
ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${markHeight}px ${fontFamily}`;
ctx.textAlign = textAlign;
ctx.textBaseline = 'top';
ctx.fillStyle = fontColor;
ctx.fillText(text, 0, item.top * ratio);
}
});
onFinish(canvas.toDataURL());
const parent = watermarkRef.parentElement;
const observer = new MutationObserver((mutationsList, observer) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
const removeNodes = mutation.removedNodes;
removeNodes.forEach((node) => {
const element = node as HTMLElement;
if (element === watermarkRef) {
parent.appendChild(element);
}
if (element === watermarkContentRef) {
watermarkRef.appendChild(element);
}
});
}
});
});
observer.observe(parent, {
attributes: true,
childList: true,
characterData: true,
subtree: true,
});
watermarkRef['_observer'] = observer;
} }
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
// eslint-disable-next-line no-console
console.warn('Current environment does not support Canvas, cannot draw watermarks.');
onFinish('');
return;
}
const ratio = window.devicePixelRatio || 1;
const canvasWidth = (gapX + width) * ratio;
const canvasHeight = (gapY + height) * ratio;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.style.width = `${gapX + width}px`;
canvas.style.height = `${gapY + height}px`;
ctx.translate(offsetLeft * ratio, offsetTop * ratio);
ctx.rotate((Math.PI / 180) * Number(rotate));
ctx.globalAlpha = alpha;
const markWidth = width * ratio;
const markHeight = height * ratio;
ctx.fillStyle = 'transparent';
ctx.fillRect(0, 0, markWidth, markHeight);
const contents = Array.isArray(watermarkContent) ? watermarkContent : [{ ...watermarkContent }];
let top = 0;
contents.forEach((item: WatermarkText & WatermarkImage & { top: number }) => {
if (item.url) {
const { url, isGrayscale = false } = item;
// eslint-disable-next-line no-param-reassign
item.top = top;
top += height;
const img = new Image();
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.src = url;
img.onload = () => {
// ctx.filter = 'grayscale(1)';
ctx.drawImage(img, 0, item.top * ratio, width * ratio, height * ratio);
if (isGrayscale) {
const imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
const pixels = imgData.data;
for (let i = 0; i < pixels.length; i += 4) {
const lightness = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
pixels[i] = lightness;
pixels[i + 1] = lightness;
pixels[i + 2] = lightness;
}
ctx.putImageData(imgData, 0, 0);
}
onFinish(canvas.toDataURL());
};
} else if (item.text) {
const {
text,
fontColor = 'rgba(0, 0, 0, 0.1)',
fontSize = 16,
fontFamily = undefined,
fontWeight = 'normal',
textAlign = 'start',
fontStyle = 'normal'
} = item;
// eslint-disable-next-line no-param-reassign
item.top = top;
top += lineSpace;
const markSize = Number(fontSize) * ratio;
ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${markHeight}px ${fontFamily}`;
ctx.textAlign = textAlign;
ctx.textBaseline = 'top';
ctx.fillStyle = fontColor;
ctx.fillText(text, 0, item.top * ratio);
}
});
onFinish(canvas.toDataURL());
const parent = watermarkRef.parentElement;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const observer = new MutationObserver((mutationsList, observer) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
const removeNodes = mutation.removedNodes;
removeNodes.forEach((node) => {
const element = node as HTMLElement;
if (element === watermarkRef) {
parent.appendChild(element);
}
if (element === watermarkContentRef) {
watermarkRef.appendChild(element);
}
});
}
});
});
observer.observe(parent, {
attributes: true,
childList: true,
characterData: true,
subtree: true,
});
watermarkRef['_observer'] = observer;
}
} }
export interface WatermarkText { export interface WatermarkText {

Просмотреть файл

@ -1,8 +1,9 @@
const throttle = (fn, threshold = 160) => { const throttle = (fn, threshold = 160) => {
let timeout; let timeout;
var start = +new Date(); let start = +new Date();
return function (...args) { return function (...args) {
let context = this, // eslint-disable-next-line @typescript-eslint/no-this-alias
const context = this,
curTime = +new Date() - 0; curTime = +new Date() - 0;
//总是干掉事件回调 //总是干掉事件回调
window.clearTimeout(timeout); window.clearTimeout(timeout);
@ -13,7 +14,6 @@
} else { } else {
//让方法在脱离事件后也能执行一次 //让方法在脱离事件后也能执行一次
timeout = window.setTimeout(() => { timeout = window.setTimeout(() => {
//@ts-ignore
fn.apply(this, args); fn.apply(this, args);
}, threshold); }, threshold);
} }
@ -130,6 +130,7 @@ class Dragger {
state.mouseDownYOffset = yOffset; state.mouseDownYOffset = yOffset;
}; };
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onMouseup = (e) => { onMouseup = (e) => {
const state = this._state; const state = this._state;
state.isInDrag = false; state.isInDrag = false;
@ -138,9 +139,8 @@ class Dragger {
onMousemove = throttle((e) => { onMousemove = throttle((e) => {
const state = this._state; const state = this._state;
if (state.isInDrag) { if (state.isInDrag) {
var nowX = e.clientX, const nowX = e.clientX, nowY = e.clientY;
nowY = e.clientY, let offsetX = nowX - state.mouseDownX + state.mouseDownXOffset,
offsetX = nowX - state.mouseDownX + state.mouseDownXOffset,
offsetY = nowY - state.mouseDownY + state.mouseDownYOffset; offsetY = nowY - state.mouseDownY + state.mouseDownYOffset;
if (this._options.inViewport) { if (this._options.inViewport) {
@ -159,6 +159,7 @@ class Dragger {
} }
}, 10).bind(this); }, 10).bind(this);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onResize = throttle((e) => { onResize = throttle((e) => {
this._state.bound = getBoundPosition( this._state.bound = getBoundPosition(
this._container, this._container,
@ -207,7 +208,7 @@ function getBoundPosition(childNode: HTMLElement, parentNode: HTMLElement) {
const childComputedStyle = window.getComputedStyle(parentNode); const childComputedStyle = window.getComputedStyle(parentNode);
const parentComputedStyle = window.getComputedStyle(parentNode); const parentComputedStyle = window.getComputedStyle(parentNode);
let bounds = { const bounds = {
left: left:
-childNode.offsetLeft + -childNode.offsetLeft +
parseInt(childComputedStyle.marginLeft) + parseInt(childComputedStyle.marginLeft) +

Просмотреть файл

@ -10,10 +10,10 @@ export class eventHelper {
return element.dispatchEvent(evt); return element.dispatchEvent(evt);
} }
static addDomEventListener(element, eventName: string, preventDefault: boolean, invoker: any, stopPropagation: boolean = false) { static addDomEventListener(element, eventName: string, preventDefault: boolean, invoker: any, stopPropagation: boolean = false) {
const callback = args => { const callback = args => {
const obj = {}; const obj = {};
for (let k in args) { for (const k in args) {
if (k !== 'originalTarget') { //firefox occasionally raises Permission Denied when this property is being stringified if (k !== 'originalTarget') { //firefox occasionally raises Permission Denied when this property is being stringified
obj[k] = args[k]; obj[k] = args[k];
} }
@ -29,7 +29,7 @@ export class eventHelper {
args.preventDefault(); args.preventDefault();
} }
if (stopPropagation) { if (stopPropagation) {
args.stopPropagation(); args.stopPropagation();
} }
}; };
@ -91,8 +91,9 @@ export class eventHelper {
} }
private static debounce(func, wait, immediate) { private static debounce(func, wait, immediate) {
var timeout; let timeout;
return (...args) => { return (...args) => {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const context = this; const context = this;
const later = () => { const later = () => {
timeout = null; timeout = null;
@ -103,7 +104,7 @@ export class eventHelper {
timeout = setTimeout(later, wait); timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args); if (callNow) func.apply(context, args);
}; };
}; }
private static preventKeys(e: KeyboardEvent, keys: string[]) { private static preventKeys(e: KeyboardEvent, keys: string[]) {
if (keys.indexOf(e.key.toUpperCase()) !== -1) { if (keys.indexOf(e.key.toUpperCase()) !== -1) {

Просмотреть файл

@ -13,7 +13,7 @@ export class infoHelper {
element = document.body; element = document.body;
} else if (typeof element === 'string') { } else if (typeof element === 'string') {
if (element === 'window') { if (element === 'window') {
return window; return window;
} else if (element === 'document') { } else if (element === 'document') {
return document; return document;
} }
@ -148,7 +148,7 @@ export class infoHelper {
} }
static getElementsInfo(elements: any[]): any { static getElementsInfo(elements: any[]): any {
let infos = {}; const infos = {};
elements.forEach(el => { elements.forEach(el => {
infos[el.id] = this.getInfo(el); infos[el.id] = this.getInfo(el);
}) })

Просмотреть файл

@ -17,7 +17,7 @@ export class manipulationHelper {
} }
static addElementTo(addElement, elementSelector, prepend = false): boolean { static addElementTo(addElement, elementSelector, prepend = false): boolean {
let parent = domInfoHelper.get(elementSelector); const parent = domInfoHelper.get(elementSelector);
if (parent && addElement) { if (parent && addElement) {
if (parent instanceof Node && addElement instanceof Node) { if (parent instanceof Node && addElement instanceof Node) {
if (prepend) parent.insertBefore(addElement, parent.firstChild); if (prepend) parent.insertBefore(addElement, parent.firstChild);
@ -31,16 +31,16 @@ export class manipulationHelper {
} }
static delElementFrom(delElement, elementSelector) { static delElementFrom(delElement, elementSelector) {
let parent = domInfoHelper.get(elementSelector); const parent = domInfoHelper.get(elementSelector);
if (parent && delElement) { if (parent && delElement) {
parent.removeChild(delElement); parent.removeChild(delElement);
} }
} }
static setDomAttribute(element, attributes) { static setDomAttribute(element, attributes) {
let dom: HTMLElement = domInfoHelper.get(element); const dom: HTMLElement = domInfoHelper.get(element);
if (dom) { if (dom) {
for (let key in attributes) { for (const key in attributes) {
dom.setAttribute(key, attributes[key]); dom.setAttribute(key, attributes[key]);
} }
} }
@ -53,15 +53,15 @@ export class manipulationHelper {
} }
private static copyElementAsRichText(element) { private static copyElementAsRichText(element) {
var selection = document.getSelection(); const selection = document.getSelection();
if (selection.rangeCount > 0) { if (selection.rangeCount > 0) {
selection.removeAllRanges(); selection.removeAllRanges();
} }
var range = document.createRange(); const range = document.createRange();
range.selectNode(element); range.selectNode(element);
selection.addRange(range); selection.addRange(range);
try { try {
var successful = document.execCommand('copy'); const successful = document.execCommand('copy');
selection.removeAllRanges(); selection.removeAllRanges();
return successful; return successful;
} catch (err) { } catch (err) {
@ -83,7 +83,7 @@ export class manipulationHelper {
} }
private static fallbackCopyTextToClipboard(text) { private static fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea"); const textArea = document.createElement("textarea");
textArea.value = text; textArea.value = text;
// Avoid scrolling to bottom // Avoid scrolling to bottom
@ -96,8 +96,8 @@ export class manipulationHelper {
textArea.select(); textArea.select();
try { try {
var successful = document.execCommand('copy'); const successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful'; const msg = successful ? 'successful' : 'unsuccessful';
console.log('Fallback: Copying text command was ' + msg); console.log('Fallback: Copying text command was ' + msg);
} catch (err) { } catch (err) {
console.error('Fallback: Oops, unable to copy', err); console.error('Fallback: Oops, unable to copy', err);
@ -107,7 +107,7 @@ export class manipulationHelper {
} }
static focus(selector, noScroll: boolean = false, option: enums.FocusBehavior = enums.FocusBehavior.FocusAtLast) { static focus(selector, noScroll: boolean = false, option: enums.FocusBehavior = enums.FocusBehavior.FocusAtLast) {
let dom = domInfoHelper.get(selector); const dom = domInfoHelper.get(selector);
if (!(dom instanceof HTMLElement)) if (!(dom instanceof HTMLElement))
throw new Error("Unable to focus on invalid element."); throw new Error("Unable to focus on invalid element.");
@ -117,22 +117,22 @@ export class manipulationHelper {
if (dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement) { if (dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement) {
switch (option) { switch (option) {
case enums.FocusBehavior.FocusAndSelectAll: case enums.FocusBehavior.FocusAndSelectAll:
dom.select(); dom.select();
break; break;
case enums.FocusBehavior.FocusAtFirst: case enums.FocusBehavior.FocusAtFirst:
dom.setSelectionRange(0, 0); dom.setSelectionRange(0, 0);
break; break;
case enums.FocusBehavior.FocusAtLast: case enums.FocusBehavior.FocusAtLast:
dom.setSelectionRange(-1, -1); dom.setSelectionRange(-1, -1);
break; break;
} }
} }
} }
static blur(selector) { static blur(selector) {
let dom = domInfoHelper.get(selector); const dom = domInfoHelper.get(selector);
if (dom) { if (dom) {
dom.blur(); dom.blur();
} }
@ -143,38 +143,38 @@ export class manipulationHelper {
if (parentElement && element && element instanceof HTMLElement) { if (parentElement && element && element instanceof HTMLElement) {
parentElement.scrollTop = element.offsetTop; parentElement.scrollTop = element.offsetTop;
} else if (element && element instanceof HTMLElement) { } else if (element && element instanceof HTMLElement) {
element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' }); element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
} }
} }
static smoothScrollTo(selector: Element | string, parentElement: HTMLElement, duration: number) { static smoothScrollTo(selector: Element | string, parentElement: HTMLElement, duration: number) {
const element = domInfoHelper.get(selector); const element = domInfoHelper.get(selector);
let to = element.offsetTop; const to = element.offsetTop;
if (scrollIds.get(parentElement)) { if (scrollIds.get(parentElement)) {
cancelAnimationFrame(scrollIds.get(parentElement)!); cancelAnimationFrame(scrollIds.get(parentElement)!);
} }
// jump to target if duration zero // jump to target if duration zero
if (duration <= 0) { if (duration <= 0) {
scrollIds.set( scrollIds.set(
parentElement, parentElement,
requestAnimationFrame(() => { requestAnimationFrame(() => {
parentElement.scrollTop = to; parentElement.scrollTop = to;
}), }),
); );
return; return;
} }
const difference = to - parentElement.scrollTop; const difference = to - parentElement.scrollTop;
const perTick = (difference / duration) * 10; const perTick = (difference / duration) * 10;
scrollIds.set( scrollIds.set(
parentElement, parentElement,
requestAnimationFrame(() => { requestAnimationFrame(() => {
parentElement.scrollTop += perTick; parentElement.scrollTop += perTick;
if (parentElement.scrollTop !== to) { if (parentElement.scrollTop !== to) {
manipulationHelper.smoothScrollTo(selector, parentElement, duration - 10); manipulationHelper.smoothScrollTo(selector, parentElement, duration - 10);
} }
}), }),
); );
} }
@ -193,13 +193,12 @@ export class manipulationHelper {
//copied from https://www.telerik.com/forums/trigger-tab-key-when-enter-key-is-pressed //copied from https://www.telerik.com/forums/trigger-tab-key-when-enter-key-is-pressed
static invokeTabKey() { static invokeTabKey() {
var currInput = document.activeElement; const currInput = document.activeElement;
if (currInput.tagName.toLowerCase() == "input") { if (currInput.tagName.toLowerCase() == "input") {
var inputs = document.getElementsByTagName("input"); const inputs = document.getElementsByTagName("input");
var currInput = document.activeElement; for (let i = 0; i < inputs.length; i++) {
for (var i = 0; i < inputs.length; i++) {
if (inputs[i] == currInput) { if (inputs[i] == currInput) {
var next = inputs[i + 1]; const next = inputs[i + 1];
if (next && next.focus) { if (next && next.focus) {
next.focus(); next.focus();
} }
@ -210,7 +209,7 @@ export class manipulationHelper {
} }
static disableBodyScroll() { static disableBodyScroll() {
let body = document.body; const body = document.body;
const oldBodyCache = {}; const oldBodyCache = {};
["position", "width", "overflow"].forEach((key) => { ["position", "width", "overflow"].forEach((key) => {
oldBodyCache[key] = body.style[key]; oldBodyCache[key] = body.style[key];
@ -228,9 +227,9 @@ export class manipulationHelper {
static enableBodyScroll(force: boolean | undefined) { static enableBodyScroll(force: boolean | undefined) {
if (force) { if (force) {
state.oldBodyCacheStack = []; state.oldBodyCacheStack = [];
} }
let oldBodyCache = state.oldBodyCacheStack.length > 0 ? state.oldBodyCacheStack.pop() : {}; const oldBodyCache = state.oldBodyCacheStack.length > 0 ? state.oldBodyCacheStack.pop() : {};
styleHelper.css(document.body, styleHelper.css(document.body,
@ -243,7 +242,7 @@ export class manipulationHelper {
} }
static hasScrollbar = () => { static hasScrollbar = () => {
let overflow = document.body.style.overflow; const overflow = document.body.style.overflow;
if (overflow && overflow === "hidden") return false; if (overflow && overflow === "hidden") return false;
return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight); return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);
} }
@ -256,7 +255,7 @@ export class manipulationHelper {
* @param fresh force get scrollBar size and don't use cache * @param fresh force get scrollBar size and don't use cache
* @returns * @returns
*/ */
static getScrollBarSize = (fresh: boolean = false) => { static getScrollBarSize = (fresh: boolean = false) => {
if (typeof document === "undefined") { if (typeof document === "undefined") {
return 0; return 0;
} }

Просмотреть файл

@ -4,18 +4,18 @@
export class State { export class State {
private static instance: State; private static instance: State;
//Stores references to dot net objects (components wrapped in DotNetObjectReference) //Stores references to dot net objects (components wrapped in DotNetObjectReference)
objReferenceDict: { [key: string]: any } = {}; objReferenceDict: { [key: string]: any } = {};
//All object references must later be disposed by JS code or by .NET code. //All object references must later be disposed by JS code or by .NET code.
disposeObj(objReferenceName) { disposeObj(objReferenceName) {
delete this.objReferenceDict[objReferenceName]; delete this.objReferenceDict[objReferenceName];
} }
//Stores callback for events based on a key. Needed when //Stores callback for events based on a key. Needed when
//Event needs to be removed - the callback can be retrieved and //Event needs to be removed - the callback can be retrieved and
//used to remove the event in question //used to remove the event in question
eventCallbackRegistry: { [key: string]: eventCallback} = {}; eventCallbackRegistry: { [key: string]: eventCallback } = {};
oldBodyCacheStack = []; oldBodyCacheStack = [];

Просмотреть файл

@ -2,7 +2,7 @@
export class styleHelper { export class styleHelper {
static addCls(selector: Element | string, className: string | Array<string>) { static addCls(selector: Element | string, className: string | Array<string>) {
let element = domInfoHelper.get(selector); const element = domInfoHelper.get(selector);
if (element) { if (element) {
if (typeof className === "string") { if (typeof className === "string") {
element.classList.add(className); element.classList.add(className);
@ -13,7 +13,7 @@ export class styleHelper {
} }
static removeCls(selector: Element | string, clsName: string | Array<string>) { static removeCls(selector: Element | string, clsName: string | Array<string>) {
let element = domInfoHelper.get(selector); const element = domInfoHelper.get(selector);
if (element) { if (element) {
if (typeof clsName === "string") { if (typeof clsName === "string") {
element.classList.remove(clsName); element.classList.remove(clsName);
@ -24,14 +24,14 @@ export class styleHelper {
} }
static addClsToFirstChild(element: Element | string, className: string): void { static addClsToFirstChild(element: Element | string, className: string): void {
var domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
if (domElement && domElement.firstElementChild) { if (domElement && domElement.firstElementChild) {
domElement.firstElementChild.classList.add(className); domElement.firstElementChild.classList.add(className);
} }
} }
static removeClsFromFirstChild(element: Element | string, className): void { static removeClsFromFirstChild(element: Element | string, className): void {
var domElement = domInfoHelper.get(element); const domElement = domInfoHelper.get(element);
if (domElement && domElement.firstElementChild) { if (domElement && domElement.firstElementChild) {
domElement.firstElementChild.classList.remove(className); domElement.firstElementChild.classList.remove(className);
} }
@ -52,20 +52,20 @@ export class styleHelper {
static css(element: HTMLElement, name: string | object, value: string | null = null) { static css(element: HTMLElement, name: string | object, value: string | null = null) {
if (typeof name === 'string') { if (typeof name === 'string') {
if (value === null) { if (value === null) {
let style = name; const style = name;
let cssAttributes = style.split(";"); const cssAttributes = style.split(";");
for (let i = 0; i < cssAttributes.length; i++) { for (let i = 0; i < cssAttributes.length; i++) {
let cssAttribute = cssAttributes[i]; const cssAttribute = cssAttributes[i];
if (!cssAttribute) continue; if (!cssAttribute) continue;
let attribute = cssAttribute.split(":"); const attribute = cssAttribute.split(":");
element.style.setProperty(attribute[0], attribute[1]); element.style.setProperty(attribute[0], attribute[1]);
} }
return; return;
} }
element.style.setProperty(name, value); element.style.setProperty(name, value);
} else { } else {
for (let key in name) { for (const key in name) {
if (name.hasOwnProperty(key)) { if (Object.prototype.hasOwnProperty.call(name, key)) {
element.style.setProperty(key, name[key]); element.style.setProperty(key, name[key]);
} }
} }

4774
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -26,9 +26,11 @@
"build:lib": "gulp build:library", "build:lib": "gulp build:library",
"build:doc": "gulp build:preview --max-old-space-size=81920", "build:doc": "gulp build:preview --max-old-space-size=81920",
"preinstall": "dotnet tool restore", "preinstall": "dotnet tool restore",
"changelog": "node ./scripts/print-changelog" "changelog": "node ./scripts/print-changelog",
"lint": "eslint ./components --ext .ts"
}, },
"devDependencies": { "devDependencies": {
"@ant-design/colors": "^6.0.0",
"@babel/core": "^7.8.7", "@babel/core": "^7.8.7",
"@commitlint/cli": "^11.0.0", "@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0", "@commitlint/config-conventional": "^11.0.0",
@ -38,13 +40,20 @@
"@types/less": "^3.0.3", "@types/less": "^3.0.3",
"@types/node": "^16.3.2", "@types/node": "^16.3.2",
"@types/resize-observer-browser": "^0.1.3", "@types/resize-observer-browser": "^0.1.3",
"@ant-design/colors": "^6.0.0", "@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"antd-theme-generator": "1.2.2", "antd-theme-generator": "1.2.2",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"babelify": "^8.0.0", "babelify": "^8.0.0",
"browserify": "^16.5.2", "browserify": "^16.5.2",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"eslint": "^8.57.0",
"eslint-config-semistandard": "^17.0.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-promise": "^6.1.1",
"fs-extra": "^9.0.0", "fs-extra": "^9.0.0",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-clean": "^0.4.0", "gulp-clean": "^0.4.0",