Skip to content

Commit

Permalink
modify structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Xheldon committed Mar 2, 2021
1 parent 8a9faf9 commit f8efcf9
Show file tree
Hide file tree
Showing 20 changed files with 310 additions and 107 deletions.
12 changes: 10 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,13 @@
},
"rules": {
"eqeqeq": [1, "allow-null"]
}
}
},
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"parserOptions": {
"project": ["./tsconfig.json"]
}
}
]
}
39 changes: 39 additions & 0 deletions app/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { EditorView } from 'prosemirror-view';
import { EditorState, Plugin } from 'prosemirror-state';
import { schemas } from '@schemas';
import { plugins } from '@plugins';
/*
editor single intance
*/
export default class Editor {
view: EditorView;
constructor(options: any) {
this.view = this.initView(options);
}

initView(options: any) {
const state = EditorState.create({
schema: schemas,
plugins: plugins.concat(new Plugin({
props: {
handleClick(view: EditorView, pos: number): boolean {
return false;
}
}
}))
});
return new EditorView({ mount: document.getElementById(options.root) }, {
state,
editable(view): boolean {
// Note: At the beginning, i want to design the structure like notion, such as not make the whole document contenteditable make the atom block instead to
// but there is a problem which make the plugin view not update, so i have to return it back, sad.
return true;
},
attributes(state) {
return {
style: 'box-sizing: border-box;'
}
}
});
}
}
55 changes: 21 additions & 34 deletions app/index.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,38 @@
import { EditorState, Plugin } from 'prosemirror-state';

import { EditorView } from 'prosemirror-view';
import {Fragment, Slice} from 'prosemirror-model';
import {findWrapping, ReplaceAroundStep} from 'prosemirror-transform';

import { render } from 'react-dom';
import { Provider } from 'react-redux';
import ReactRootApp from '@components/index';


import { schemas } from '@schemas';
import { plugins } from '@plugins';
import Editor from './editor';

import './style.scss';

declare global {
interface Window {
d(): void,
v: EditorView
NEDITOR: any
}
}
interface NotionEditorInterface {
editor: any;
}
class NotionEditor implements NotionEditorInterface {
editor: any;
constructor(options = {}) {
this.editor = null;
this.active(options);
}

const root = document.getElementById('n-editor');

const state = EditorState.create({
schema: schemas,
plugins: plugins.concat(new Plugin({
props: {
handleClick(view: EditorView, pos: number): boolean {
return false;
}
}
}))
});

const view = new EditorView({ mount: root }, {
state,
editable(view): boolean {
// Note: At the beginning, i want to design the structure like notion, such as not make the whole document contenteditable make the atom block instead to
// but there is a problem which make the plugin view not update, so i have to return it back, sad.
return true;
},
attributes(state) {
return {
style: 'box-sizing: border-box;'
}
active(options: any) {
this.editor = new Editor(options);
}
});
}

// Note: This should init by Client, we mock it.
document.addEventListener('DOMContentLoaded', () => window.NEDITOR = new NotionEditor({
title: 'NotionEditor',
root: 'n-editor'
// other config
}));
// react view
render(ReactRootApp(), document.getElementById('n-component'));
33 changes: 3 additions & 30 deletions app/modules/base/schema.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import {DOMOutputSpec, Node } from 'prosemirror-model';
import { defaultSchemaAttrs } from '@utils/schema-helper'

export const doc = {
content: '(block | section)+'
};

export const section = {
attrs: {
class: {
default: 'n-section'
},
type: {
default: 'section'
},
...defaultSchemaAttrs('section'),
style: {
default: 'display: flex;'
}
Expand All @@ -23,29 +19,6 @@ export const section = {
}
};

// textblock 是唯一能够直接包含 text 的元素
export const textBlock = {
attrs: {
class: {
default: 'n-text-block'
},
type: {
default: 'text-block'
},
style: {
default: ''
},
'n-atom': {
default: ''
}
},
group: 'textBlock',
content: 'inline*',
toDOM(node: Node): DOMOutputSpec {
return ['div', node.attrs, 0]
}
};

export const text = {
group: 'inline'
group: 'inline',
};
15 changes: 15 additions & 0 deletions app/modules/blockquote/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defaultParseDom, defaultSchemaAttrs } from '@utils/schema-helper';
import { DOMOutputSpec, Node } from 'prosemirror-model';

export const blockquote = {
attrs: {
...defaultSchemaAttrs('blockquote')
},
content: 'block+',
group: 'block',
parseDOM: [
{ tag: 'blockquote' },
defaultParseDom('blockquote')
],
toDOM(node: Node): DOMOutputSpec { return ['div', node.attrs, 0] }
};
27 changes: 27 additions & 0 deletions app/modules/code-block/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defaultParseDom, defaultSchemaAttrs } from '@utils/schema-helper';
import { Node, DOMOutputSpec } from 'prosemirror-model';

export const code_block = {
attrs: {
...defaultSchemaAttrs('code-block'),
},
content: 'text*',
group: 'block',
code: true,
defining: true,
marks: '',
parseDOM: [
defaultParseDom('code-block'),
{
tag: 'pre',
preserveWhitespace: 'full' as "full",
getAttrs: (node: HTMLElement) => ({
params: node.getAttribute('data-params') || ''
})
}
],
toDOM(node: Node): DOMOutputSpec {
// Note: use 'div' instead
return ['pre', node.attrs.params ? {'data-params': node.attrs.params} : {}, ['code', 0]]
}
}
Empty file removed app/modules/code/schema.ts
Empty file.
9 changes: 9 additions & 0 deletions app/modules/hard-break/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DOMOutputSpec } from 'prosemirror-model'

export const hard_break = {
inline: true,
group: 'inline',
selectable: false,
parseDOM: [{ tag: 'br' }],
toDOM(): DOMOutputSpec { return ['br'] }
}
28 changes: 28 additions & 0 deletions app/modules/heading/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Node } from 'prosemirror-model';
import { defaultParseDom, defaultSchemaAttrs } from "@utils/schema-helper"

export const heading = {
attrs: {
...defaultSchemaAttrs('heading'),
level: {
default: 1,
}
},
content: '(text | image)*',
group: 'block',
defining: true,
parseDOM: [
{ tag: 'h1', attrs: { level: 1 } },
{ tag: 'h2', attrs: { level: 2 } },
{ tag: 'h3', attrs: { level: 3 } },
{ tag: 'h4', attrs: { level: 4 } },
{ tag: 'h5', attrs: { level: 5 } },
{ tag: 'h6', attrs: { level: 6 } },
defaultParseDom('heading'),
],
toDOM(node: Node) {
return ['div', {
'data-type': node.attrs.level,
}, 0]
}
}
15 changes: 15 additions & 0 deletions app/modules/hr/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defaultParseDom, defaultSchemaAttrs } from '@utils/schema-helper';
import { DOMOutputSpec } from 'prosemirror-model';


export const hr = {
attrs: {
...defaultSchemaAttrs('hr'),
},
group: 'block',
parseDOM: [
{ tag: 'hr' },
defaultParseDom('hr'),
],
toDOM(): DOMOutputSpec { return ['div', ['hr']] }
}
24 changes: 24 additions & 0 deletions app/modules/image/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DOMOutputSpec, Node } from 'prosemirror-model';
import { defaultSchemaAttrs } from '@utils/schema-helper';

export const image = {
inline: true,
attrs: {
...defaultSchemaAttrs('image'),
src: {},
alt: { default: '' },
title: { default: '' }
},
group: "inline",
draggable: true,
parseDOM: [{
tag: "img[src]", getAttrs(dom: HTMLElement) {
return {
src: dom.getAttribute("src"),
title: dom.getAttribute("title"),
alt: dom.getAttribute("alt")
}
}
}],
toDOM(node: Node): DOMOutputSpec { return ["img", node.attrs] }
};
47 changes: 26 additions & 21 deletions app/modules/list/schema.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { Node, DOMOutputSpec } from "prosemirror-model";

import {hasType, defaultParseDom, defaultSchemaAttrs} from '@utils/schema-helper';
export const ul = {
attrs: {
class: {
default: 'n-unordered-list'
},
type: {
default: 'un-order-list'
},
style: {
default: ''
}
...defaultSchemaAttrs('bullet-list'),
},
group: 'block',
defining: true,
content: 'textBlock block*',
content: 'list_item+',
parseDOM: [
defaultParseDom('bullet-list'),
],
toDOM(node: Node): DOMOutputSpec {
//TODO: only put partial attrs on dom
return [
Expand All @@ -32,19 +27,14 @@ export const ul = {

export const ol = {
attrs: {
class: {
default: 'n-ordered-list'
},
type: {
default: 'order-list'
},
style: {
default: ''
}
...defaultSchemaAttrs('order-list'),
},
group: 'block',
defining: true,
content: 'textBlock block*',
content: 'list_item+',
parseDOM: [
defaultParseDom('order-list')
],
toDOM(node: Node): DOMOutputSpec {
//TODO: only put partial attrs on dom
return [
Expand All @@ -59,3 +49,18 @@ export const ol = {
]
}
};

export const list_item = {
attrs: {
...defaultSchemaAttrs('list-item'),
},
group: 'list_item',
defining: true,
content: 'paragraph block*',
parseDOM: [
defaultParseDom('list-item')
],
toDOM(node: Node): DOMOutputSpec {
return ['div', node.attrs, 0];
}
}
Loading

0 comments on commit f8efcf9

Please sign in to comment.