slightning-coco-widget
Version:
SLIGHTNING 的 CoCo 控件框架。
234 lines (233 loc) • 11.2 kB
JavaScript
import * as CoCo from "../../coco";
import { convertToCoCo } from "../convert/to-coco";
import { decorate } from "../export";
function isEditorWindow(window) {
return /^https?:\/\/coco\.codemao\.cn\/editor\/((#|\?).*)?$/.test(window.location.href);
}
function getEditorWindow() {
if (isEditorWindow(window)) {
return window;
}
try {
if (parent != window && isEditorWindow(parent)) {
return parent;
}
}
catch (__ignore) { }
try {
if (opener instanceof Window && isEditorWindow(opener)) {
return opener;
}
}
catch (__ignore) { }
return null;
}
function getEditorWorkName() {
var _a, _b, _c;
return (_c = (_b = (_a = getEditorWindow()) === null || _a === void 0 ? void 0 : _a.document.querySelector("input[placeholder=\"请输入作品名称\"]")) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : null;
}
function getEditorRunButton() {
var _a, _b;
return (_b = (_a = getEditorWindow()) === null || _a === void 0 ? void 0 : _a.document.querySelector("[class^=\"style_playButton\"]")) !== null && _b !== void 0 ? _b : null;
}
function editorIsRunningWork() {
var _a, _b;
return /[\s]*停[\s]*止[\s]*/.test((_b = (_a = getEditorRunButton()) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : "");
}
export const CoCoAdapter = {
getSuperWidget(types) {
return class extends (types.options.visible ? CoCo.VisibleWidget : CoCo.InvisibleWidget) {
constructor(props) {
super(props);
if (types.options.visible) {
const propertiesSet = new Set();
function addProperties(properties) {
for (const property of properties) {
if ("contents" in property) {
addProperties(property.contents);
continue;
}
propertiesSet.add(Array.isArray(property) ? property[0] : property.key);
}
}
addProperties(types.properties);
let isSettingProperty = false;
return new Proxy(this, {
set(target, p, newValue, receiver) {
if (!isSettingProperty && typeof p == "string" && propertiesSet.has(p)) {
isSettingProperty = true;
CoCo.VisibleWidget.prototype.setProps.call(target, {
[p]: newValue
});
isSettingProperty = false;
return true;
}
return Reflect.set(target, p, newValue, receiver);
}
});
}
}
};
},
exportWidget(types, widget, config) {
[types, widget] = decorate(types, widget, config, ["CoCo"]);
CoCo.exportWidget(...convertToCoCo(types, widget));
},
Logger: class CoCoLogger {
constructor(types, widget) {
this.widget = widget;
this.super = types.options.visible ? CoCo.VisibleWidget : CoCo.InvisibleWidget;
}
log(messages) {
this.super.prototype.widgetLog.call(this.widget, messages);
}
info(messages) {
this.super.prototype.widgetLog.call(this.widget, `[信息] ${messages}`);
}
warn(messages) {
this.super.prototype.widgetWarn.call(this.widget, messages);
}
error(messages) {
this.super.prototype.widgetError.call(this.widget, messages);
}
},
emit(key, ...args) {
CoCo.InvisibleWidget.prototype.emit.call(this, key, ...args);
},
utils: {
inNative() {
return location.href == "file:///android_asset/www/index.html";
},
inEditor() {
return /^https?:\/\/coco\.codemao\.cn\/editor\/(editor-player.html)?((#|\?).*)?$/.test(location.href);
},
inEditorWindow() {
return isEditorWindow(window);
},
inEditorPlayer() {
return /^https?:\/\/coco\.codemao\.cn\/editor\/editor-player.html((#|\?).*)?$/.test(location.href);
},
editor: {
getWindow: getEditorWindow,
getWorkName: getEditorWorkName,
getRunButton: getEditorRunButton,
isRunningWork: editorIsRunningWork,
runWork() {
var _a;
if (!editorIsRunningWork()) {
(_a = getEditorRunButton()) === null || _a === void 0 ? void 0 : _a.click();
}
},
stopWork() {
var _a;
if (editorIsRunningWork()) {
(_a = getEditorRunButton()) === null || _a === void 0 ? void 0 : _a.click();
}
},
saveWork() {
return new Promise((resolve, reject) => {
var _a;
const editorWindow = getEditorWindow();
if (editorWindow == null) {
reject(new Error("找不到编辑器窗口"));
return;
}
const saveButton = Array.from((_a = editorWindow.document.querySelectorAll(".coco-button.coco-button-circle")) !== null && _a !== void 0 ? _a : []).find((element) => element.querySelector("[class*=\"Header_saveText\"]") != null);
if (!(saveButton instanceof HTMLElement)) {
reject(new Error("找不到保存按钮"));
return;
}
saveButton.click();
const handle = setInterval(() => {
if (Array.from(saveButton.classList).some((className) => className.startsWith("Header_saving"))) {
return;
}
clearInterval(handle);
resolve();
}, 100);
});
},
reopenWork() {
const workName = getEditorWorkName();
if (workName == null) {
throw new Error("找不到作品名称");
}
const editorWindow = getEditorWindow();
if (editorWindow == null) {
throw new Error("找不到编辑器窗口");
}
const openButton = Array.from(editorWindow.document.querySelectorAll(".coco-menu-item")).find((element) => { var _a; return ((_a = element.children[0]) === null || _a === void 0 ? void 0 : _a.textContent) == "打开"; });
if (!(openButton instanceof HTMLElement)) {
throw new Error("找不到打开按钮");
}
openButton.click();
const handle = setInterval(() => {
var _a;
const worksElement = editorWindow.document.querySelector("[class*=\"MyProject_main\"]");
if (!(worksElement instanceof HTMLElement)) {
return;
}
clearInterval(handle);
const workNameElement = Array.from(worksElement.querySelectorAll("[class*=\"MyProject_name\"]")).find((element) => element.textContent == workName);
if (workNameElement == undefined) {
throw new Error("找不到作品");
}
(_a = workNameElement.parentElement) === null || _a === void 0 ? void 0 : _a.click();
setTimeout(() => {
const saveButton = Array.from(editorWindow.document.querySelectorAll(".coco-button.coco-button-primary.coco-button-circle")).find((element) => element.textContent == "保存");
if (saveButton instanceof HTMLElement) {
saveButton.click();
}
}, 150);
}, 100);
},
importWidget(widget) {
return new Promise((resolve, reject) => {
var _a, _b, _c, _d;
if (typeof widget == "string") {
widget = new Blob([widget], { type: "text/javascript" });
}
if (widget instanceof Blob) {
widget = new File([widget], "widget.js", { type: "text/javascript" });
}
if (!(widget instanceof File)) {
reject(new Error("参数错误,widget 必须是 File 或 Blob 或字符串"));
return;
}
const widgetInputLabelElement = Array.from((_c = (_b = (_a = getEditorWindow()) === null || _a === void 0 ? void 0 : _a.document) === null || _b === void 0 ? void 0 : _b.querySelectorAll(".coco-upload-button-content")) !== null && _c !== void 0 ? _c : []).find((element) => element.textContent == "导入自定义控件");
if (!(widgetInputLabelElement instanceof HTMLElement)) {
reject(new Error("找不到自定义控件导入按钮"));
return;
}
const widgetInputElement = (_d = widgetInputLabelElement.parentElement) === null || _d === void 0 ? void 0 : _d.querySelector("input[type=file]");
if (!(widgetInputElement instanceof HTMLInputElement)) {
reject(new Error("找不到自定义控件导入按钮"));
return;
}
const dataTransfer = new DataTransfer();
dataTransfer.items.add(widget);
widgetInputElement.files = dataTransfer.files;
widgetInputElement.dispatchEvent(new Event("change", { bubbles: true }));
setTimeout(() => {
var _a;
const replaceButton = document.querySelector(".coco-button.coco-button-primary.coco-button-dangerous.coco-button-circle");
if (replaceButton instanceof HTMLButtonElement && ((_a = replaceButton.childNodes[0]) === null || _a === void 0 ? void 0 : _a.textContent) == "覆盖") {
replaceButton.click();
}
resolve();
}, 150);
});
}
},
getImageURLByFileName(fileName) {
var _a, _b;
return (_b = (_a = CoCo.widgetRequire("utils")) === null || _a === void 0 ? void 0 : _a.getWidgetImageUrl(fileName)) !== null && _b !== void 0 ? _b : null;
},
getAudioURLByFileName() {
return null;
},
getVideoURLByFileName() {
return null;
}
}
};