Skip to content

Commit

Permalink
feat: support using in web component(#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
imzbf committed Aug 15, 2024
1 parent f7ab889 commit b792873
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 25 deletions.
4 changes: 3 additions & 1 deletion packages/MdEditor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ const Editor = defineComponent({
scrollAuto: props.scrollAuto
});

const rootRef = ref<HTMLDivElement>();
const codeRef = ref<ContentExposeParam>();

// 快捷键监听
useOnSave(props, ctx);
// provide 部分prop
useProvide(props);
useProvide(props, rootRef);
// 插入扩展的外链
useExpansion(props);
// 错误捕获
Expand Down Expand Up @@ -69,6 +70,7 @@ const Editor = defineComponent({
setting.fullscreen || setting.pageFullscreen ? `${prefix}-fullscreen` : ''
]}
style={props.style}
ref={rootRef}
>
{props.toolbars.length > 0 && (
<ToolBar
Expand Down
5 changes: 3 additions & 2 deletions packages/MdEditor/components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ export default defineComponent({
const triggerHeight = triggerInfo.height;
const triggerWidth = triggerInfo.width;

const relativecrollLeft = document.querySelector(props.relative)?.scrollLeft || 0;
const relativeWidth = document.querySelector(props.relative)?.clientWidth || 0;
const rootNode = triggerEle.getRootNode() as Document | ShadowRoot;
const relativecrollLeft = rootNode.querySelector(props.relative)?.scrollLeft || 0;
const relativeWidth = rootNode.querySelector(props.relative)?.clientWidth || 0;

let left =
triggerLeft - overlayEle.offsetWidth / 2 + triggerWidth / 2 - relativecrollLeft;
Expand Down
7 changes: 4 additions & 3 deletions packages/MdEditor/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ export default defineComponent({
emits: ['onClose'],
setup(props: ModalProps, ctx) {
const themeRef = inject('theme') as ComputedRef<Themes>;

const rootRef = inject('rootRef') as ComputedRef<HTMLDivElement>;
const modalVisible = ref(props.visible);

const modalClass = ref([`${prefix}-modal`]);

const modalRef = ref();
const modalHeaderRef = ref();

const bodyRef = ref<HTMLElement>();
const bodyRef = ref<ShadowRoot | Element>();

// 创建的弹窗容器,存放在document.body末尾
const containerRef = shallowRef<HTMLDivElement>();
Expand Down Expand Up @@ -207,7 +207,8 @@ export default defineComponent({
});

onMounted(() => {
bodyRef.value = document.body;
const rootNode = rootRef.value?.getRootNode() as ShadowRoot;
bodyRef.value = rootNode instanceof Document ? document.body : rootNode;
});

return () => {
Expand Down
15 changes: 12 additions & 3 deletions packages/MdEditor/composition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,19 @@ export const useOnSave = (props: EditorProps, context: EditorContext) => {
*
* @param props 预览组件的props
*/
export const useProvidePreview = (props: MdPreviewProps) => {
export const useProvidePreview = (
props: MdPreviewProps,
rootRef: Ref<HTMLDivElement | undefined>
) => {
const { editorId } = props;
const hljsUrls = configOption.editorExtensions.highlight;
const hljsAttrs = configOption.editorExtensionsAttrs.highlight;

provide('editorId', editorId);

// 提供一个顶层元素的引用
provide('rootRef', rootRef);

provide(
'theme',
computed(() => props.theme)
Expand Down Expand Up @@ -201,8 +207,11 @@ export const useProvidePreview = (props: MdPreviewProps) => {
*
* @param props
*/
export const useProvide = (props: EditorProps) => {
useProvidePreview(props);
export const useProvide = (
props: EditorProps,
rootRef: Ref<HTMLDivElement | undefined>
) => {
useProvidePreview(props, rootRef);
// tab=2space
provide('tabWidth', props.tabWidth);
};
Expand Down
11 changes: 7 additions & 4 deletions packages/MdEditor/layouts/Content/composition/useAutoScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ const useAutoScroll = (
// 编译事件
const rebindEvent = () => {
clearScrollAuto();
const cmScroller = document.querySelector<HTMLDivElement>(

const rootNode = codeMirrorUt.value?.view.contentDOM.getRootNode() as
| Document
| ShadowRoot;
const cmScroller = rootNode.querySelector<HTMLDivElement>(
`#${editorId} .cm-scroller`
);

const previewEle = document.querySelector<HTMLElement>(
const previewEle = rootNode.querySelector<HTMLElement>(
`[id="${editorId}-preview-wrapper"]`
);
const htmlEle = document.querySelector<HTMLElement>(
const htmlEle = rootNode.querySelector<HTMLElement>(
`[id="${editorId}-html-wrapper"]`
);

Expand Down
3 changes: 2 additions & 1 deletion packages/MdEditor/layouts/Content/composition/useCopyCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { prefix } from '~/config';

const useCopyCode = (props: ContentPreviewProps, html: Ref<string>, key: Ref<string>) => {
const editorId = inject('editorId') as string;
const rootRef = inject('rootRef') as Ref<HTMLDivElement>;
const ult = inject('usedLanguageText') as ComputedRef<StaticTextDefaultValue>;

// 向页面代码块注入复制按钮
const initCopyEntry = () => {
document
rootRef.value
.querySelectorAll(`#${editorId} .${prefix}-preview .${prefix}-code`)
.forEach((codeBlock: Element) => {
// 恢复进程ID
Expand Down
5 changes: 3 additions & 2 deletions packages/MdEditor/layouts/Content/composition/useMermaid.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { watch, inject, ComputedRef, onMounted, shallowRef, nextTick } from 'vue';
import { watch, inject, ComputedRef, onMounted, shallowRef, nextTick, Ref } from 'vue';
import { prefix, configOption } from '~/config';
import { appendHandler } from '~/utils/dom';
import { randomId } from '@vavt/util';
Expand All @@ -12,6 +12,7 @@ import { ContentPreviewProps } from '../ContentPreview';
*/
const useMermaid = (props: ContentPreviewProps) => {
const theme = inject('theme') as ComputedRef<string>;
const rootRef = inject('rootRef') as Ref<HTMLDivElement>;
const { editorExtensions, editorExtensionsAttrs, mermaidConfig } = configOption;

const mermaidRef = shallowRef(editorExtensions!.mermaid!.instance);
Expand Down Expand Up @@ -82,7 +83,7 @@ const useMermaid = (props: ContentPreviewProps) => {
const replaceMermaid = () => {
nextTick(() => {
if (!props.noMermaid && mermaidRef.value) {
const mermaidSourceEles = document.querySelectorAll<HTMLElement>(
const mermaidSourceEles = rootRef.value.querySelectorAll<HTMLElement>(
`div.${prefix}-mermaid`
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ const template = {

export const useTaskState = (props: ContentPreviewProps, html: Ref<string>) => {
const editorId = inject('editorId') as string;
const rootRef = inject('rootRef') as Ref<HTMLDivElement>;

let removeListener = () => {};

const addListener = () => {
const tasks = document.querySelectorAll(`#${editorId} .task-list-item.enabled`);
const tasks = rootRef.value.querySelectorAll('.task-list-item.enabled');

const listener = (e: Event) => {
e.preventDefault();
Expand Down
2 changes: 1 addition & 1 deletion packages/MdEditor/layouts/Content/markdownIt/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const codetabs = (md: markdownit, _opts: CodeTabsPluginOps) => {

labels += `<li>
<input type="radio" name="${prefix}-codetab-label-${_opts.editorId}-${idx}" class="${className}" ${checked}>
<label onclick="document.querySelectorAll('.${className}').forEach(e => e.click())">${
<label onclick="this.getRootNode().querySelectorAll('.${className}').forEach(e => e.click())">${
tab || getLangName(token)
}</label>
</li>`;
Expand Down
6 changes: 4 additions & 2 deletions packages/MdEditor/layouts/Modals/Clip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
nextTick,
ComputedRef,
watch,
ExtractPropTypes
ExtractPropTypes,
Ref
} from 'vue';
import { LooseRequired } from '@vue/shared';
import { StaticTextDefaultValue } from '~/type';
Expand Down Expand Up @@ -40,6 +41,7 @@ export default defineComponent({
setup(props: ClipProps) {
const ult = inject('usedLanguageText') as ComputedRef<StaticTextDefaultValue>;
const editorId = inject('editorId') as string;
const rootRef = inject('rootRef') as Ref<HTMLDivElement>;
// 传递下来的图片裁剪构造函数
let Cropper = configOption.editorExtensions.cropper!.instance;

Expand Down Expand Up @@ -90,7 +92,7 @@ export default defineComponent({
nextTick(() => {
cropper = new Cropper(uploadImgRef.value, {
viewMode: 2,
preview: `.${prefix}-clip-preview-target`
preview: rootRef.value.querySelector(`.${prefix}-clip-preview-target`)
// aspectRatio: 16 / 9,
});
});
Expand Down
4 changes: 2 additions & 2 deletions packages/MdEditor/utils/scroll-auto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ const scrollAuto = (pEle: HTMLElement, cEle: HTMLElement, codeMirrorUt: CodeMirr
startTop = getTopByLine(lineNumer);
scale = (scrollDOM.scrollTop - startTop) / (pMaxScrollLength - startTop);

const _startEle = document.querySelector<HTMLElement>(`[data-line="${lineNumer}"]`);
const _startEle = cEle.querySelector<HTMLElement>(`[data-line="${lineNumer}"]`);

if (startTop > 0 && _startEle) {
startEleOffetTop = _startEle.offsetTop;
Expand Down Expand Up @@ -374,7 +374,7 @@ const scrollAuto = (pEle: HTMLElement, cEle: HTMLElement, codeMirrorUt: CodeMirr
) {
const lineNumer = getLineNumber(pMaxScrollLength, cMaxScrollLength);

const _startEle = document.querySelector<HTMLElement>(`[data-line="${lineNumer}"]`);
const _startEle = cEle.querySelector<HTMLElement>(`[data-line="${lineNumer}"]`);

eleStartOffsetTop = _startEle
? _startEle.offsetTop - getComputedStyleNum(_startEle, 'margin-top')
Expand Down
7 changes: 4 additions & 3 deletions packages/MdPreview/MdPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineComponent, onBeforeUnmount } from 'vue';
import { defineComponent, onBeforeUnmount, ref } from 'vue';
import { prefix } from '~/config';
import bus from '~/utils/event-bus';
import { useProvidePreview, useExpansionPreview } from '~/composition';
Expand All @@ -16,9 +16,9 @@ const MdPreview = defineComponent({
// ID不允许响应式(解构会失去响应式能力),这会扰乱eventbus
// eslint-disable-next-line vue/no-setup-props-destructure
const { editorId, noKatex, noMermaid, noHighlight } = props;

const rootRef = ref<HTMLDivElement>();
// provide 部分prop
useProvidePreview(props);
useProvidePreview(props, rootRef);
// 插入扩展的外链
useExpansionPreview(props);

Expand All @@ -40,6 +40,7 @@ const MdPreview = defineComponent({
`${prefix}-previewOnly`
]}
style={props.style}
ref={rootRef}
>
<ContentPreview
modelValue={props.modelValue}
Expand Down

0 comments on commit b792873

Please sign in to comment.