@textbus/xnote
Version:
A high-performance rich text editor that supports multiplayer online collaboration.
1,153 lines (1,112 loc) • 326 kB
JavaScript
import { jsxs, jsx, Fragment } from '@viewfly/core/jsx-runtime';
import { withScopedCSS } from '@viewfly/scoped-css';
import { Injectable, InjectFlags, Injector, inject, createSignal, onUnmounted, getCurrentInstance, createRef, InjectionToken, withAnnotation, onUpdated, onMounted, onPropsChanged, ReflectiveInjector, createDynamicRef, jsx as jsx$1, viewfly, Fragment as Fragment$1, Context, watch } from '@viewfly/core';
import { Subject, fromEvent, Selection, Subscription, Attribute, Keyboard, Commander, Controller, useContext, onBreak, onContentInsert, ContentType, createVNode, merge, Slot, Component, Registry, Query, QueryStateType, Formatter, BehaviorSubject, onSlotApplyFormat, onSlotSetAttribute, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, onFocusIn, onFocusOut, onDestroy, onGetRanges, onParentSlotUpdated, Textbus, History, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, debounceTime, delay, tap, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
import { normalizeHex, hex2Hsl, hex2Rgb, hex2Hsv, hsl2Hex, hsl2Hsv, hsl2Rgb, rgb2Hsl, rgb2Hex, rgb2Hsv, hsv2Hex, hsv2Hsl, hsv2Rgb, any2Hsl, parseCss } from '@tanbo/color';
import { VIEW_CONTAINER, isMac, DomAdapter, Input, BrowserModule, SelectionBridge, VIEW_DOCUMENT, CollaborateSelectionAwarenessDelegate, isMobileBrowser, CollaborateCursor, Parser } from '@textbus/platform-browser';
import { createPortal, createApp, DomRenderer, HTMLRenderer, OutputTranslator } from '@viewfly/platform-browser';
import { useProduce } from '@viewfly/hooks';
import highlightjs from 'highlight.js';
import { v4 } from 'uuid';
import Katex from 'katex';
import { ViewflyAdapter, ViewflyVDomAdapter } from '@textbus/adapter-viewfly';
import { MessageBus, CollaborateModule } from '@textbus/collaborate';
var scopedId$q = "vf-7d288d";
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
let DropdownService = class DropdownService {
constructor() {
Object.defineProperty(this, "onSiblingOpen", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "siblingOpenEvent", {
enumerable: true,
configurable: true,
writable: true,
value: new Subject()
});
this.onSiblingOpen = this.siblingOpenEvent.asObservable();
}
notify(id) {
this.siblingOpenEvent.next(id);
}
};
DropdownService = __decorate([
Injectable({
provideIn: 'root'
}),
__metadata("design:paramtypes", [])
], DropdownService);
var DropdownContextService_1;
let i = 0;
let DropdownContextService = DropdownContextService_1 = class DropdownContextService {
constructor(dropdownService, injector) {
Object.defineProperty(this, "dropdownService", {
enumerable: true,
configurable: true,
writable: true,
value: dropdownService
});
Object.defineProperty(this, "injector", {
enumerable: true,
configurable: true,
writable: true,
value: injector
});
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: i
});
Object.defineProperty(this, "isOpen", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "onOpenStateChange", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "canHide", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
Object.defineProperty(this, "openStateChangeEvent", {
enumerable: true,
configurable: true,
writable: true,
value: new Subject()
});
Object.defineProperty(this, "timer", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "parentDropdownContextService", {
enumerable: true,
configurable: true,
writable: true,
value: this.injector.get(DropdownContextService_1, null, InjectFlags.SkipSelf)
});
this.onOpenStateChange = this.openStateChangeEvent.asObservable();
dropdownService.onSiblingOpen.subscribe(id => {
if (id === this.id) {
return;
}
this.isOpen = false;
this.openStateChangeEvent.next(false);
});
i++;
}
open() {
this.isOpen = true;
clearTimeout(this.timer);
this.timer = null;
this.openStateChangeEvent.next(true);
this.dropdownService.notify(this.id);
if (this.parentDropdownContextService) {
this.parentDropdownContextService.open();
}
}
hide(delay = true) {
if (!this.canHide) {
return;
}
if (this.parentDropdownContextService) {
this.parentDropdownContextService.hide();
}
if (delay) {
this.timer = setTimeout(() => {
this.isOpen = false;
this.openStateChangeEvent.next(false);
}, 200);
return;
}
this.isOpen = false;
this.openStateChangeEvent.next(false);
if (this.parentDropdownContextService) {
this.parentDropdownContextService.hide();
}
}
};
DropdownContextService = DropdownContextService_1 = __decorate([
Injectable(),
__metadata("design:paramtypes", [DropdownService,
Injector])
], DropdownContextService);
function Button(props) {
const dropdownContextService = inject(DropdownContextService, null);
const isActive = createSignal((dropdownContextService === null || dropdownContextService === void 0 ? void 0 : dropdownContextService.isOpen) || false);
if (dropdownContextService) {
const subscription = dropdownContextService.onOpenStateChange.subscribe(b => {
isActive.set(b);
});
onUnmounted(() => {
subscription.unsubscribe();
});
}
return withScopedCSS(scopedId$q, () => {
return (jsxs("button", Object.assign({ type: "button" }, props, { class: [
'btn',
{
active: props.ordinary ? false : isActive(),
highlight: props.highlight
},
props.class
], children: [jsx("span", { children: props.children }), props.arrow && jsx("span", { class: ['btn-arrow', 'xnote-icon-arrow-bottom'] })] })));
});
}
var scopedId$p = "vf-d552b9";
class Picker {
set hex(color) {
var _a;
const c = color ? normalizeHex(color) : null;
if (c) {
this.empty = false;
this._hex = c;
this._hsl = hex2Hsl(c);
this._rgb = hex2Rgb(c);
this._hsv = hex2Hsv(c);
this._rgba = Object.assign(Object.assign({}, this._rgb), { a: this.resetAlpha ? 1 : ((_a = this._rgba) === null || _a === void 0 ? void 0 : _a.a) || 1 });
}
else {
this.empty = true;
}
this.resetAlpha = true;
this.onChange();
}
get hex() {
return this.empty ? null : this._hex;
}
set hsl(color) {
var _a;
if (!color || typeof color.h !== 'number' || typeof color.s !== 'number' || typeof color.l !== 'number') {
this.empty = true;
}
else {
this.empty = false;
this._hsl = color;
this._hex = hsl2Hex(color);
this._hsv = hsl2Hsv(color);
this._rgb = hsl2Rgb(color);
this._rgba = Object.assign(Object.assign({}, this._rgb), { a: this.resetAlpha ? 1 : ((_a = this._rgba) === null || _a === void 0 ? void 0 : _a.a) || 1 });
}
this.resetAlpha = true;
this.onChange();
}
get hsl() {
return this.empty ? null : this._hsl;
}
set rgb(color) {
var _a;
if (!color || typeof color.r !== 'number' || typeof color.g !== 'number' || typeof color.b !== 'number') {
this.empty = true;
}
else {
this.empty = false;
this._rgb = color;
this._rgba = Object.assign(Object.assign({}, color), { a: this.resetAlpha ? 1 : ((_a = this._rgba) === null || _a === void 0 ? void 0 : _a.a) || 1 });
this._hsl = rgb2Hsl(color);
this._hex = rgb2Hex(color);
this._hsv = rgb2Hsv(color);
}
this.resetAlpha = true;
this.onChange();
}
get rgb() {
return this.empty ? null : this._rgb;
}
set rgba(color) {
if (!color ||
typeof color.r !== 'number' ||
typeof color.g !== 'number' ||
typeof color.b !== 'number' ||
typeof color.a !== 'number') {
this.empty = true;
}
else {
this.empty = false;
this._rgba = color;
this._hsl = rgb2Hsl(color);
this._hex = rgb2Hex(color);
this._hsv = rgb2Hsv(color);
}
this.onChange();
}
get rgba() {
return this.empty ? null : this._rgba;
}
set hsv(color) {
var _a;
if (!color || typeof color.h !== 'number' || typeof color.s !== 'number' || typeof color.v !== 'number') {
this.empty = true;
}
else {
this.empty = false;
this._hsv = color;
this._hex = hsv2Hex(color);
this._hsl = hsv2Hsl(color);
this._rgb = hsv2Rgb(color);
this._rgba = Object.assign(Object.assign({}, this._rgb), { a: this.resetAlpha ? 1 : ((_a = this._rgba) === null || _a === void 0 ? void 0 : _a.a) || 1 });
}
this.resetAlpha = true;
this.onChange();
}
get hsv() {
return this.empty ? null : this._hsv;
}
constructor(onChange, value) {
Object.defineProperty(this, "onChange", {
enumerable: true,
configurable: true,
writable: true,
value: onChange
});
Object.defineProperty(this, "_hex", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "_hsl", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_rgb", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_hsv", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_rgba", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "empty", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "resetAlpha", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
this.hex = value || '#f00';
}
}
function ColorPicker(props) {
const instance = getCurrentInstance();
const picker = new Picker(() => {
instance.markAsDirtied();
}, props.value);
const mainColors = [
'#000', '#333', '#444', '#555', '#666', '#777', '#888',
'#999', '#aaa', '#bbb', '#ccc', '#ddd', '#eee', '#fff',
];
const colors = [
'#fec6c2', '#fee5c3', '#fefcc3', '#baf6c4', '#c3ebfe', '#c3cbfe', '#e1caff',
'#fc8e88', '#fccc88', '#fcf888', '#76ec8a', '#88d8fc', '#97a4fb', '#c098f4',
'#ff6666', '#ffb151', '#fada3a', '#18c937', '#3aaafa', '#6373e2', '#a669f7',
'#f63030', '#f88933', '#deb12a', '#038e23', '#1276cc', '#3f52ce', '#8838ed',
'#c60000', '#d86912', '#b88811', '#086508', '#144c93', '#1b2eaa', '#6117bf',
];
const recentColors = createSignal(props.recentColors || []);
function addRecentColor() {
const color = picker.hex;
if (!color) {
return;
}
const colors = recentColors().filter(item => {
return item !== color;
});
colors.unshift(color);
if (colors.length >= 7) {
colors.length = 7;
}
recentColors.set(colors);
}
const paletteRef = createRef();
function bindPaletteEvent(ev) {
const update = (ev) => {
var _a;
const position = paletteRef.current.getBoundingClientRect();
const offsetX = ev.clientX - position.left;
const offsetY = ev.clientY - position.top;
let s = offsetX / 130 * 100;
let v = 100 - offsetY / 130 * 100;
s = Math.max(0, s);
s = Math.min(100, s);
v = Math.max(0, v);
v = Math.min(100, v);
picker.resetAlpha = false;
picker.hsv = {
h: picker.hsv.h,
s,
v
};
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
};
update(ev);
const unMouseMove = fromEvent(document, 'mousemove').subscribe(ev => {
update(ev);
});
const unMouseUp = fromEvent(document, 'mouseup').subscribe(() => {
unMouseMove.unsubscribe();
unMouseUp.unsubscribe();
});
}
const hueBarRef = createRef();
function bindHueBarEvent(ev) {
const update = (ev) => {
var _a;
const position = hueBarRef.current.getBoundingClientRect();
let offsetY = ev.clientY - position.top;
offsetY = Math.max(0, offsetY);
offsetY = Math.min(100, offsetY);
const h = 360 / 100 * offsetY;
picker.resetAlpha = false;
picker.hsv = {
h,
s: picker.hsv.s,
v: picker.hsv.v
};
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
};
update(ev);
const unMouseMove = fromEvent(document, 'mousemove').subscribe(ev => {
update(ev);
});
const unMouseUp = fromEvent(document, 'mouseup').subscribe(() => {
unMouseMove.unsubscribe();
unMouseUp.unsubscribe();
});
}
const alphaBarRef = createRef();
function bindAlphaEvent(ev) {
const update = (ev) => {
var _a;
const position = alphaBarRef.current.getBoundingClientRect();
let offsetX = ev.clientX - position.left;
offsetX = Math.max(0, offsetX);
offsetX = Math.min(position.width, offsetX);
picker.rgba = Object.assign(Object.assign({}, picker.rgba), { a: offsetX / position.width });
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
};
update(ev);
const unMouseMove = fromEvent(document, 'mousemove').subscribe(ev => {
update(ev);
});
const unMouseUp = fromEvent(document, 'mouseup').subscribe(() => {
unMouseMove.unsubscribe();
unMouseUp.unsubscribe();
});
}
function bindInputsEvent(ev) {
var _a;
const updateByHSL = (h, s, l) => {
var _a;
picker.hex = hsl2Hex({ h, s, l });
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
};
const updateByRGB = (r, g, b) => {
var _a;
picker.hex = rgb2Hex({ r, g, b });
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
};
const el = ev.target;
const model = el.getAttribute('data-model');
if (el.type === 'number') {
const min = +el.min;
const max = +el.max;
el.value = Math.max(+el.value, min) + '';
el.value = Math.min(+el.value, max) + '';
}
const { h, s, l } = picker.hsl;
const { r, g, b } = picker.rgb;
switch (model) {
case 'H':
updateByHSL(+el.value, s, l);
break;
case 'S':
updateByHSL(h, +el.value, l);
break;
case 'L':
updateByHSL(h, s, +el.value);
break;
case 'R':
updateByRGB(+el.value, g, b);
break;
case 'G':
updateByRGB(r, +el.value, b);
break;
case 'B':
updateByRGB(r, g, +el.value);
break;
case 'HEX':
if (/^#(([0-9a-f]){3}){1,2}$/i.test(el.value)) {
picker.hex = el.value;
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, picker);
}
break;
}
}
const isShowPalette = createSignal(false);
function selected() {
props.onSelected(picker);
addRecentColor();
isShowPalette.set(false);
}
function bindColorOptionsEvent(ev) {
const target = ev.target;
if (!target.hasAttribute('data-color')) {
return;
}
const c = target.getAttribute('data-color');
if (/^rgba/.test(c)) {
picker.rgba = parseCss(c);
}
else {
picker.hex = c;
}
props.onSelected(picker);
addRecentColor();
}
return withScopedCSS(scopedId$p, () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
return (jsxs("div", { onMousedown: ev => {
ev.stopPropagation();
}, class: {
'xnote-color-picker': true,
'xnote-color-picker-show-palette': isShowPalette()
}, children: [jsxs("div", { class: "xnote-color-picker-preset", onClick: bindColorOptionsEvent, children: [jsx("div", { class: "xnote-color-picker-swatches", style: "height: 50px", children: mainColors.map(color => {
var _a, _b, _c;
const hsl = (any2Hsl(color) || {});
return (jsx("div", { "data-color": color, class: {
'xnote-color-picker-current': hsl.l === ((_a = picker.hsl) === null || _a === void 0 ? void 0 : _a.l) && hsl.s === ((_b = picker.hsl) === null || _b === void 0 ? void 0 : _b.s) && hsl.h === ((_c = picker.hsl) === null || _c === void 0 ? void 0 : _c.h),
}, style: {
background: color
} }));
}) }), jsx("div", { class: "xnote-color-picker-swatches", style: "height: 118px;", children: colors.map(color => {
return (jsx("div", { "data-color": color, style: {
background: color
} }));
}) }), jsx("div", { class: "xnote-color-picker-recent-text", children: "\u5E38\u7528\u989C\u8272" }), jsx("div", { class: "xnote-color-picker-swatches", style: "height: 25px;", children: Array.from({ length: 7 }).map((_, index) => {
const colors = recentColors();
const color = colors[index] || '';
return (jsx("div", { "data-color": color || 'unknown', style: {
background: color
} }));
}) }), jsxs("div", { class: "xnote-color-picker-flex", children: [jsx("div", { class: "xnote-color-picker-swatches", children: jsx("div", { "data-color": "" }) }), jsxs("button", { type: "button", class: "xnote-color-picker-to-palette", onClick: () => {
isShowPalette.set(true);
}, children: ["\u8C03\u8272\u76D8", jsx("svg", { style: "vertical-align: middle;fill: currentColor;overflow: hidden;", viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { transform: "rotate(180, 512, 512)", d: "M497.92 165.12L422.4 89.6 0 512l422.4 422.4 75.52-75.52L151.04 512z" }) })] })] })] }), jsxs("div", { class: "xnote-color-picker-menu", children: [jsx("div", { class: "xnote-color-picker-back-btn-wrap", children: jsxs("button", { type: "button", class: "xnote-color-picker-back-btn", onClick: () => {
isShowPalette.set(false);
}, children: [jsx("svg", { style: "vertical-align: middle;fill: currentColor;overflow: hidden;", viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M497.92 165.12L422.4 89.6 0 512l422.4 422.4 75.52-75.52L151.04 512z" }) }), "\u8FD4\u56DE"] }) }), jsxs("div", { class: "xnote-color-picker-viewer", children: [jsxs("div", { class: "xnote-color-picker-viewer-left", children: [jsx("div", { class: [
'xnote-color-picker-palette',
{
'xnote-color-picker-palette-empty': picker.empty
}
], style: {
background: picker.empty ? '' : `linear-gradient(to right, #fff, hsl(${(_a = picker.hsv) === null || _a === void 0 ? void 0 : _a.h}, 100%, 50%))`
}, ref: paletteRef, onMousedown: bindPaletteEvent, children: jsx("div", { class: "xnote-color-picker-palette-point", style: {
left: `calc(${(_b = picker.hsv) === null || _b === void 0 ? void 0 : _b.s}% - 6px)`,
top: `calc(${100 - (((_c = picker.hsv) === null || _c === void 0 ? void 0 : _c.v) || 0)}% - 6px)`
} }) }), jsxs("div", { class: "xnote-color-picker-viewer-alpha", children: [jsx("div", { class: "xnote-color-picker-viewer-alpha-pointer", style: {
left: picker.empty ? '100%' : (((_d = picker.rgba) === null || _d === void 0 ? void 0 : _d.a) || 0) * 100 + '%',
} }), jsx("div", { class: "xnote-color-picker-viewer-alpha-bar", style: {
background: picker.empty ? '' : `linear-gradient(to right, transparent, ${picker.hex})`
}, onMousedown: bindAlphaEvent, ref: alphaBarRef })] })] }), jsxs("div", { class: "xnote-color-picker-viewer-right", children: [jsxs("div", { class: "xnote-color-picker-tools", children: [jsx("div", { class: "xnote-color-picker-value", children: jsx("div", { class: "xnote-color-picker-value-color", style: {
background: picker.empty ? '' : `rgba(${(_e = picker.rgba) === null || _e === void 0 ? void 0 : _e.r}, ${(_f = picker.rgba) === null || _f === void 0 ? void 0 : _f.g}, ${(_g = picker.rgba) === null || _g === void 0 ? void 0 : _g.b}, ${(_h = picker.rgba) === null || _h === void 0 ? void 0 : _h.a})`
} }) }), jsx("div", { class: "xnote-color-picker-hue-bar", ref: hueBarRef, onMousedown: bindHueBarEvent, children: jsx("div", { class: "xnote-color-picker-hue-pointer", style: {
top: `calc(${(((_j = picker.hsv) === null || _j === void 0 ? void 0 : _j.h) || 0) / 360 * 100}% - 4px)`
} }) })] }), jsx("div", { class: "xnote-color-picker-viewer-alpha-value", children: Number((_k = picker.rgba) === null || _k === void 0 ? void 0 : _k.a.toFixed(2)) })] })] }), jsxs("div", { class: "xnote-color-picker-inputs", onInput: bindInputsEvent, children: [jsxs("div", { class: "xnote-color-picker-hsl", children: [jsxs("div", { children: ["H ", jsx("input", { "data-model": "H", min: "0", max: "360", type: "number", value: (_l = picker.hsl) === null || _l === void 0 ? void 0 : _l.h })] }), jsxs("div", { children: ["S ", jsx("input", { "data-model": "S", min: "0", max: "100", type: "number", value: (_m = picker.hsl) === null || _m === void 0 ? void 0 : _m.s })] }), jsxs("div", { children: ["L ", jsx("input", { "data-model": "L", min: "0", max: "100", type: "number", value: (_o = picker.hsl) === null || _o === void 0 ? void 0 : _o.l })] })] }), jsxs("div", { class: "xnote-color-picker-rgb", children: [jsxs("div", { children: ["R ", jsx("input", { "data-model": "R", min: "0", max: "255", type: "number", value: (_p = picker.rgb) === null || _p === void 0 ? void 0 : _p.r })] }), jsxs("div", { children: ["G ", jsx("input", { "data-model": "G", min: "0", max: "255", type: "number", value: (_q = picker.rgb) === null || _q === void 0 ? void 0 : _q.g })] }), jsxs("div", { children: ["B ", jsx("input", { "data-model": "B", min: "0", max: "255", type: "number", value: (_r = picker.rgb) === null || _r === void 0 ? void 0 : _r.b })] })] }), jsx("div", { class: "xnote-color-picker-hex", children: jsxs("div", { children: ["HEX ", jsx("input", { "data-model": "HEX", type: "text", value: picker.hex })] }) })] }), jsx("div", { class: "xnote-color-picker-btn-wrap", children: jsx("button", { type: "button", class: "xnote-color-picker-btn", onClick: selected, children: "\u786E\u5B9A" }) })] })] }));
});
}
var scopedId$o = "vf-ac7e8d";
function ComponentToolbar(props) {
return withScopedCSS(scopedId$o, () => {
return (jsx("div", { class: "component-toolbar", style: props.style, children: jsx("div", { class: [
'toolbar',
{
active: props.visible
}
], style: props.innerStyle, children: props.children }) }));
});
}
var scopedId$n = "vf-ede279";
function Divider() {
return withScopedCSS(scopedId$n, () => {
return jsx("div", { class: "divider" });
});
}
var scopedId$m = "vf-d91ad6";
function DragResize(props) {
const isShow = createSignal(false);
const selection = inject(Selection);
const docContainer = inject(VIEW_CONTAINER);
const component = props.component;
const ref = createRef();
const sub = selection.onChange.subscribe(() => {
var _a;
const index = (_a = component.parent) === null || _a === void 0 ? void 0 : _a.indexOf(component);
if (selection.startSlot !== component.parent ||
selection.endSlot !== component.parent ||
selection.startOffset !== index ||
selection.endOffset !== index + 1) {
isShow.set(false);
return;
}
isShow.set(true);
const width = ref.current.offsetWidth;
const height = ref.current.offsetHeight;
sizeText.set(`${Math.round(width)}px * ${Math.round(height)}px`);
});
function selectComponent() {
selection.selectComponent(component, true);
}
onUnmounted(() => {
sub.unsubscribe();
});
const btnGroup = createRef();
const mask = createRef();
function drag(ev) {
docContainer.style.pointerEvents = 'none';
const ele = props.source.current;
const startRect = ele.getBoundingClientRect();
const startX = ev.clientX;
const startY = ev.clientY;
const startWidth = startRect.width;
const startHeight = startRect.height;
const startHypotenuse = Math.sqrt(startWidth * startWidth + startHeight * startHeight);
let endWidth = startWidth;
let endHeight = startHeight;
const handlers = Array.from(btnGroup.current.children);
const index = handlers.indexOf(ev.target);
const unMove = fromEvent(document, 'mousemove').subscribe(ev => {
const moveX = ev.clientX;
const moveY = ev.clientY;
const offsetX = moveX - startX;
const offsetY = moveY - startY;
let gainHypotenuse;
let proportion;
let sideX;
let sideY;
switch (index) {
case 0:
case 4:
sideX = startWidth + offsetX;
sideY = startHeight + offsetY;
gainHypotenuse = Math.sqrt(sideX * sideX + sideY * sideY);
proportion = gainHypotenuse / startHypotenuse;
if (index === 0) {
proportion = 1 - (proportion - 1);
}
endWidth = startWidth * proportion;
endHeight = startHeight * proportion;
break;
case 2:
sideX = startWidth + offsetX;
sideY = startHeight - offsetY;
gainHypotenuse = Math.sqrt(sideX * sideX + sideY * sideY);
proportion = gainHypotenuse / startHypotenuse;
endWidth = startWidth * proportion;
endHeight = startHeight * proportion;
break;
case 6:
sideX = startWidth - offsetX;
sideY = startHeight + offsetY;
gainHypotenuse = Math.sqrt(sideX * sideX + sideY * sideY);
gainHypotenuse = Math.sqrt(sideX * sideX + sideY * sideY);
proportion = gainHypotenuse / startHypotenuse;
endWidth = startWidth * proportion;
endHeight = startHeight * proportion;
break;
case 1:
endHeight = startHeight - offsetY;
break;
case 5:
endHeight = startHeight + offsetY;
break;
case 3:
endWidth = startWidth + offsetX;
break;
case 7:
endWidth = startWidth - offsetX;
break;
}
ele.style.width = endWidth + 'px';
ele.style.height = endHeight + 'px';
sizeText.set(`${Math.round(endWidth)}px * ${Math.round(endHeight)}px`);
});
const unUp = fromEvent(document, 'mouseup').subscribe(() => {
component.state.width = endWidth + 'px';
component.state.height = endHeight + 'px';
docContainer.style.pointerEvents = '';
unMove.unsubscribe();
unUp.unsubscribe();
});
}
const sizeText = createSignal(`${component.state.width}*${component.state.height}`);
return withScopedCSS(scopedId$m, () => {
return (jsxs("div", { class: "drag-resize", onClick: selectComponent, children: [jsx("div", { class: "container", ref: ref, children: props.children }), jsxs("div", { class: ['resize-tool', {
active: isShow()
}], children: [jsx("div", { class: "mask", ref: mask, children: sizeText() }), jsxs("div", { class: "btn-group", ref: btnGroup, onMousedown: drag, children: [jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" })] })] })] }));
});
}
var scopedId$l = "vf-0fd06a";
var scopedId$k = "vf-8a05e9";
const DropdownMenuContainer = new InjectionToken('DropdownMenuContainer');
const DropdownMenuPortal = withAnnotation({
providers: [
DropdownService
]
}, function DropdownMenuPortal(props) {
const dropdownContextService = inject(DropdownContextService);
const container = inject(DropdownMenuContainer, inject(VIEW_CONTAINER));
const menuRef = createRef();
let timer = null;
const delay = 10;
function update() {
const menuElement = menuRef.current;
menuElement.style.height = 'auto';
const containerRect = container.getBoundingClientRect();
if (props.abreast) {
const btnEle = props.triggerRef.current;
const screenHeight = document.documentElement.clientHeight;
const menuHeight = menuElement.scrollHeight;
const maxHeight = Math.min(screenHeight - 20, menuHeight);
menuElement.style.height = maxHeight + 'px';
const btnRect = btnEle.getBoundingClientRect();
let offsetTop = btnRect.top - maxHeight / 2;
if (offsetTop < 10) {
offsetTop = 10;
}
else if (offsetTop + maxHeight > screenHeight - 10) {
offsetTop = screenHeight - 10 - maxHeight;
}
menuElement.style.top = offsetTop - containerRect.top + 'px';
const triggerRect = props.triggerRef.current.getBoundingClientRect();
const leftDistance = triggerRect.left;
const isToLeft = leftDistance >= menuElement.offsetWidth + 20;
if (isToLeft && props.toLeft) {
menuElement.style.left = leftDistance - menuElement.offsetWidth - 20 - containerRect.left + 'px';
timer = setTimeout(() => {
menuElement.style.transform = 'translateX(10px)';
menuElement.style.opacity = '1';
}, delay);
}
else {
menuElement.style.left = triggerRect.right + 20 - containerRect.left + 'px';
timer = setTimeout(() => {
menuElement.style.transform = 'translateX(-10px)';
menuElement.style.opacity = '1';
}, delay);
}
}
else {
const triggerRect = props.triggerRef.current.getBoundingClientRect();
const documentClientHeight = document.documentElement.clientHeight;
const bottomDistance = documentClientHeight - triggerRect.bottom;
const isToTop = bottomDistance < 200 && triggerRect.top > bottomDistance;
let left = triggerRect.left - containerRect.left;
const clientWidth = document.documentElement.clientWidth;
const menuWidth = menuElement.offsetWidth;
const maxLeft = clientWidth - menuWidth - 20;
left = Math.min(maxLeft, left);
// left = Math.max(left, 20)
menuElement.style.left = left + 'px';
if (isToTop) {
const maxHeight = Math.max(menuElement.scrollHeight, menuElement.offsetHeight);
const height = Math.min(triggerRect.top - 20, maxHeight, 400);
menuElement.style.height = height + 'px';
menuElement.style.top = triggerRect.top - 20 - height - containerRect.top + 'px';
timer = setTimeout(() => {
menuElement.style.transform = 'translateY(10px)';
menuElement.style.opacity = '1';
}, delay);
}
else {
menuElement.style.height = Math.min(bottomDistance - 20, menuElement.scrollHeight) + 'px';
menuElement.style.top = triggerRect.bottom + 20 - containerRect.top + 'px';
timer = setTimeout(() => {
menuElement.style.transform = 'translateY(-10px)';
menuElement.style.opacity = '1';
}, delay);
}
}
}
onUpdated(() => {
update();
});
onUnmounted(() => {
clearTimeout(timer);
});
function onEnter() {
if (props.noTrigger) {
return;
}
dropdownContextService.canHide = false;
dropdownContextService.open();
}
function onLeave() {
if (props.noTrigger) {
return;
}
dropdownContextService.canHide = true;
dropdownContextService.hide();
}
function stopPropagation(ev) {
ev.stopPropagation();
}
return createPortal(withScopedCSS(scopedId$k, () => {
return (jsx("div", { onMouseenter: onEnter, onMousedown: stopPropagation, onMouseleave: onLeave, ref: menuRef, style: {
width: props.width
}, class: "dropdown-menu", children: jsx("div", { class: "dropdown-menu-content", style: {
padding: props.padding
}, children: props.children }) }));
}), container);
});
const Dropdown = withAnnotation({
providers: [DropdownContextService]
}, function Dropdown(props) {
const isShow = createSignal(false);
const dropdownContextService = inject(DropdownContextService);
const toggle = () => {
if (props.disabled) {
return;
}
if (dropdownContextService.isOpen) {
dropdownContextService.hide(false);
}
else {
dropdownContextService.open();
}
};
const triggerRef = createRef();
const dropdownRef = createRef();
const arrowRef = createRef();
onMounted(() => {
const sub = dropdownContextService.onOpenStateChange.subscribe(b => {
var _a;
(_a = props.onExpendStateChange) === null || _a === void 0 ? void 0 : _a.call(props, b);
isShow.set(b);
});
return () => sub.unsubscribe();
});
const subscription = new Subscription();
onMounted(() => {
if (props.trigger === 'none') {
return;
}
if (props.trigger === 'click') {
subscription.add(fromEvent(triggerRef.current, 'click').subscribe(toggle));
return;
}
const el = props.arrow ? arrowRef.current : dropdownRef.current;
let leaveSub;
const bindLeave = function () {
leaveSub = fromEvent(el, 'mouseleave').subscribe(() => {
if (props.disabled) {
return;
}
dropdownContextService.hide();
});
};
bindLeave();
subscription.add(fromEvent(el, 'mouseenter').subscribe(() => {
if (props.disabled) {
return;
}
if (leaveSub) {
leaveSub.unsubscribe();
}
bindLeave();
dropdownContextService.open();
}));
});
onUnmounted(() => {
subscription.unsubscribe();
});
return {
isShow(b) {
if (b) {
dropdownContextService.open();
}
else {
dropdownContextService.hide(false);
}
},
$render: withScopedCSS(scopedId$l, () => {
return (jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsx("div", { class: ['dropdown-btn-inner', {
'has-arrow': props.arrow
}], children: props.children }), props.arrow && jsx("div", { ref: arrowRef, class: "dropdown-btn-arrow", children: jsx(Button, { disabled: props.disabled, arrow: true }) })] }), isShow() &&
jsx(DropdownMenuPortal, { toLeft: props.toLeft, padding: props.padding, noTrigger: props.trigger === 'none', width: props.width, abreast: props.abreast, triggerRef: triggerRef, children: Array.isArray(props.menu) ?
props.menu.map(menu => {
return (jsx("div", { class: "dropdown-menu-item", onClick: () => {
var _a;
if (menu.disabled) {
return;
}
(_a = props.onCheck) === null || _a === void 0 ? void 0 : _a.call(props, menu.value);
}, children: menu.label }));
}) :
props.menu })] }));
})
};
});
var scopedId$j = "vf-c32a7b";
function Keymap(props) {
const arr = [];
const keymap = props.keymap;
if (keymap.modKey) {
arr.push(isMac() ? jsx("span", { class: "xnote-icon-command" }) : jsx("span", { children: "Ctrl" }));
}
if (keymap.shiftKey) {
if (arr.length) {
arr.push('+');
}
arr.push(isMac() ? jsx("span", { class: "xnote-icon-shift" }) : jsx("span", { children: "Shift" }));
}
if (keymap.altKey) {
if (arr.length) {
arr.push('+');
}
arr.push(isMac() ? jsx("span", { class: "xnote-icon-opt" }) : jsx("span", { children: "Alt" }));
}
if (keymap.key) {
if (arr.length) {
arr.push('+');
}
if (Array.isArray(keymap.key)) {
arr.push(jsx("span", { children: keymap.key.join('/') }));
}
else if (typeof keymap.key === 'object') {
arr.push(jsx("span", { children: keymap.key.name }));
}
else {
arr.push(jsx("span", { children: keymap.key }));
}
}
return withScopedCSS(scopedId$j, () => {
return (jsx("span", { class: "keymap", children: arr }));
});
}
var scopedId$i = "vf-acaa5f";
function MenuHeading(props) {
return withScopedCSS(scopedId$i, () => {
return (jsx("div", { class: "menu-heading", children: props.children }));
});
}
var scopedId$h = "vf-c3b9dc";
function MenuItem(props) {
const dropdownContextService = inject(DropdownContextService, null);
const isActive = createSignal((dropdownContextService === null || dropdownContextService === void 0 ? void 0 : dropdownContextService.isOpen) || false);
if (dropdownContextService) {
const subscription = dropdownContextService.onOpenStateChange.subscribe(b => {
isActive.set(b);
});
onUnmounted(() => {
subscription.unsubscribe();
});
}
function click() {
var _a;
if (props.disabled) {
return;
}
(_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, props.value);
}
return withScopedCSS(scopedId$h, () => {
return (jsxs("div", { class: ['menu-item', { disabled: props.disabled, active: props.arrow && isActive() }], onClick: click, children: [jsxs("div", { class: "menu-item-content", children: [jsxs("div", { children: [props.icon && jsx("span", { class: "menu-icon", children: props.icon }), props.children] }), jsx("div", { children: props.desc })] }), props.arrow ?
jsx("div", { class: "arrow", children: jsx("span", { class: "xnote-icon-arrow-right" }) }) :
jsx("div", { class: [
'menu-check',
{ checked: props.checked }
], children: jsx("span", { class: "xnote-icon-checkmark" }) })] }));
});
}
var scopedId$g = "vf-a23c47";
function Popup(props) {
const host = inject(VIEW_CONTAINER);
return createPortal(withScopedCSS(scopedId$g, () => {
return (jsx("div", { class: "popup", style: {
left: props.left + 'px',
top: props.top + 'px'
}, children: props.children }));
}), host);
}
var scopedId$f = "vf-b7a2c8";
function ToolbarItem(props) {
return withScopedCSS(scopedId$f, () => {
return (jsx("div", { class: "toolbar-item", children: props.children }));
});
}
var scopedId$e = "vf-2a8a65";
let RefreshService = class RefreshService {
constructor() {
Object.defineProperty(this, "onRefresh", {
enumerable: true,
configurable: true,
writable: true,
value: new Subject()
});
}
};
RefreshService = __decorate([
Injectable()
], RefreshService);
const textAlignAttr = new Attribute('textAlign', {
render(node, formatValue) {
node.styles.set('text-align', formatValue);
}
});
const textAlignAttrLoader = {
match(element) {
return !!element.style.textAlign;
},
read(element) {
return {
attribute: textAlignAttr,
value: element.style.textAlign
};
}
};
function registerTextAlignShortcut(textbus) {
const keyboard = textbus.get(Keyboard);
const commander = textbus.get(Commander);
keyboard.addShortcut({
keymap: {
key: 'lrej'.split(''),
modKey: true
},
action(key) {
const valueMap = {
l: 'left',
r: 'right',
e: 'center',
j: 'justify'
};
commander.applyAttribute(textAlignAttr, valueMap[key]);
}
});
}
function useReadonly() {
const controller = inject(Controller);
const is = createSignal(controller.readonly);
controller.onReadonlyStateChange.subscribe(() => {
is.set(controller.readonly);
});
return is;
}
const OutputInjectionToken = new InjectionToken('OutputInjectionToken');
function useOutput() {
return createSignal(inject(OutputInjectionToken));
}
const headingAttr = new Attribute('Heading', {
render(node, formatValue) {
node.classes.add('xnote-' + formatValue);
}
});
const headingAttrLoader = {
match(element) {
return /H[1-6]/.test(element.tagName) || /(^|\s)xnote-h[1-6](\s|$)/.test(element.className);
},
read(element) {
if (/H[1-6]/.test(element.tagName)) {
return {
attribute: headingAttr,
value: element.tagName.toLowerCase()
};
}
return {
attribute: headingAttr,
value: element.className.substring(6)
};
}
};
function registerHeadingShortcut(textbus) {
const keyboard = textbus.get(Keyboard);
const commander = textbus.get(Commander);
const selection = textbus.get(Selection);
keyboard.addShortcut({
keymap: {
key: '0123456'.split(''),
modKey: true
},
action(key) {
if (key === '0') {
commander.unApplyAttribute(headingAttr);
return;
}
commander.applyAttribute(headingAttr, 'h' + key);
}
});
keyboard.addZenCodingInterceptor({
match(content) {
return /^#{1,6}$/.test(content);
},
try(key) {
return key === ' ';
},
action(content) {
if (selection.commonAncestorComponent instanceof SourceCodeComponent) {
return false;
}
const commonAncestorSlot = selection.commonAnc