textchecker-element
Version:
Overlay text checker web compoentns.
174 lines • 7.07 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.attachTextArea = void 0;
const text_checker_element_1 = require("./text-checker-element");
const text_checker_popup_element_1 = require("./text-checker-popup-element");
const debounce = (fn, delay) => {
let timeoutId = null;
return function (...args) {
clearTimeout(timeoutId);
// @ts-ignore
var that = this;
timeoutId = setTimeout(function () {
// @ts-ignore
fn.apply(that, args);
}, delay);
};
};
const waiterForInit = (worker) => {
let initialized = false;
let _resolve = null;
const deferred = new Promise((resolve) => {
_resolve = resolve;
});
worker.addEventListener("message", function (event) {
if (event.data.command === "init") {
initialized = true;
_resolve && _resolve(initialized);
}
}, {
once: true
});
return {
ready() {
return deferred;
}
};
};
const createCompositionHandler = () => {
let onComposition = false;
return {
onComposition,
handleEvent: (event) => {
if (event.type === "compositionend") {
onComposition = false;
}
else if (event.type === "compositionstart") {
onComposition = true;
}
}
};
};
exports.attachTextArea = ({ textAreaElement, textAreaExt, workerUrl, handlePreLint, handlePostLint, lintingDebounceMs }) => {
const textChecker = new text_checker_element_1.TextCheckerElement({
targetElement: textAreaElement,
hoverPadding: 4
});
const textCheckerPopup = new text_checker_popup_element_1.TextCheckerPopupElement();
textAreaElement.before(textChecker);
document.body.append(textCheckerPopup);
const worker = new Worker(workerUrl);
const workerStatus = waiterForInit(worker);
const lintText = (message) => __awaiter(void 0, void 0, void 0, function* () {
yield workerStatus.ready();
return new Promise((resolve, _reject) => {
worker.addEventListener("message", function (event) {
if (event.data.command === "lint:result") {
resolve(event.data.result);
}
}, {
once: true
});
return worker.postMessage({
command: "lint",
text: message,
ext: textAreaExt
});
});
});
const fixText = (message, ruleId) => __awaiter(void 0, void 0, void 0, function* () {
yield workerStatus.ready();
return new Promise((resolve, _reject) => {
worker.addEventListener("message", function (event) {
if (event.data.command === "fix:result") {
resolve(event.data.result);
}
}, {
once: true
});
return worker.postMessage({
command: "fix",
text: message,
ruleId,
ext: textAreaExt
});
});
});
const compositionHandler = createCompositionHandler();
const update = debounce(() => __awaiter(void 0, void 0, void 0, function* () {
// stop lint on IME composition
if (compositionHandler.onComposition) {
return;
}
const text = textAreaElement.value;
handlePreLint && handlePreLint({ text });
const result = yield lintText(text);
handlePostLint && handlePostLint({ result });
const annotations = result.messages.map((message) => {
const card = {
id: message.ruleId + "::" + message.index,
message: message.message,
fixable: Boolean(message.fix)
};
return {
start: message.index,
end: message.index + 1,
onMouseEnter: ({ rectItem }) => {
textCheckerPopup.updateCard({
card: card,
rect: {
top: rectItem.boxBorderWidth +
rectItem.boxMarginTop +
rectItem.boxPaddingTop +
rectItem.boxAbsoluteY +
rectItem.top +
rectItem.height,
left: rectItem.boxAbsoluteX + rectItem.left,
width: rectItem.width
},
handlers: {
onFixIt() {
return __awaiter(this, void 0, void 0, function* () {
console.log("onFixIt");
const currentText = text;
const fixResult = yield fixText(currentText, message.ruleId);
console.log(currentText, "!==", fixResult.output);
if (currentText === text && currentText !== fixResult.output) {
textAreaElement.value = fixResult.output;
update();
textCheckerPopup.dismissCard(card);
}
console.log("fixResult", fixResult);
});
},
onIgnore() {
console.log("onIgnore");
},
onSeeDocument() {
console.log("onSeeDocument");
}
}
});
},
onMouseLeave() {
textCheckerPopup.dismissCard(card);
}
};
});
textChecker.updateAnnotations(annotations);
}), lintingDebounceMs);
textAreaElement.addEventListener("compositionstart", compositionHandler);
textAreaElement.addEventListener("compositionend", compositionHandler);
textAreaElement.addEventListener("input", update);
update();
};
//# sourceMappingURL=attach-textarea.js.map