Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dom-adapters): basic inline tool adapter implementation #74

Merged
merged 55 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
8994e03
Implmenet global CaretAdapter
gohabereg Jan 24, 2024
6fa8279
Handle native inputs
gohabereg Jan 28, 2024
4f0de03
Merge branch 'main' of github.com:editor-js/document-model into featu…
gohabereg Feb 13, 2024
3f93468
Pass input type to Input component props
gohabereg Jun 3, 2024
7cde75e
Use class to represent index
gohabereg Aug 26, 2024
0679745
Fix lint in dom-adapters
gohabereg Aug 26, 2024
1f89c57
fix linter
gohabereg Aug 26, 2024
a7ecfe3
Merge branch 'main' of github.com:editor-js/document-model into featu…
gohabereg Aug 26, 2024
a6a8aa6
added inline tool adapter
e11sy Aug 27, 2024
713b8b9
Merge remote-tracking branch 'origin/feature/global-caret-adapter' in…
e11sy Aug 27, 2024
a9db501
implement model updates
e11sy Aug 27, 2024
06bacaa
update from main
e11sy Aug 28, 2024
d858afc
lint fix
e11sy Aug 28, 2024
83701e7
fix index
e11sy Aug 28, 2024
96bf644
adapter renders inline tools
e11sy Aug 28, 2024
d364498
lint fix and clean up
e11sy Aug 28, 2024
a4e26c9
jsdoc
e11sy Aug 28, 2024
bc01d1b
clean up
e11sy Aug 28, 2024
240affe
jsdoc
e11sy Aug 28, 2024
6853d2a
jsdoc
e11sy Aug 28, 2024
a68e8ea
Merge branch 'main' into inline-tool-adapter
e11sy Aug 28, 2024
5d8bbd1
surround content replaced
e11sy Aug 28, 2024
5c49a09
suggestions
e11sy Aug 28, 2024
01df103
lint fix
e11sy Aug 28, 2024
dea8caf
jsdoc
e11sy Aug 28, 2024
cc00ff3
Merge branch 'main' into inline-tool-adapter
e11sy Aug 28, 2024
9057d1a
added bold and italic inline tools into core package
e11sy Aug 28, 2024
a84d732
naming
e11sy Aug 28, 2024
da5ca7c
naming
e11sy Aug 28, 2024
cf5b177
added inline toolbar and inlineToolAdapter init into core
e11sy Aug 28, 2024
6998adc
update packages and lock
e11sy Aug 28, 2024
e6c4f7c
Merge branch 'main' into inline-tool-adapter
e11sy Aug 28, 2024
185d3f4
build fix
e11sy Aug 29, 2024
6e5034c
implement inline tool adapter to core
e11sy Aug 29, 2024
a629a5b
clean up
e11sy Aug 29, 2024
c0c9b84
Merge branch 'main' into inline-tool-adapter
e11sy Aug 29, 2024
e7c0e80
jsdoc and naming improvements
e11sy Aug 29, 2024
59d8840
naming
e11sy Aug 29, 2024
a2d5e30
naming
e11sy Aug 29, 2024
1adf8c5
renaming
e11sy Aug 29, 2024
e39d5bc
fix hardcoded
e11sy Aug 29, 2024
7f66686
tools are initialized inside of the inline toolbar initialization
e11sy Aug 29, 2024
d52475c
fixed inline tool attaching
e11sy Aug 29, 2024
ff16243
jsdoc
e11sy Aug 29, 2024
e9626bb
naming fix
e11sy Aug 29, 2024
eb4411f
fixed imports
e11sy Aug 29, 2024
4ccc47b
lint fix
e11sy Aug 29, 2024
530b09d
try build fix
e11sy Aug 29, 2024
3c9238b
install dependencies
e11sy Aug 29, 2024
91a1fef
add sdk package
e11sy Aug 29, 2024
cee8b33
fix build for core
e11sy Aug 29, 2024
f9725a1
change package name in actions
e11sy Aug 29, 2024
98a5644
add references
e11sy Aug 29, 2024
be50940
typo
e11sy Aug 29, 2024
6db4d90
fix build
e11sy Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
"typescript": "^5.5.4"
},
"dependencies": {
"@editorjs/dom": "^1.0.0",
"@editorjs/dom-adapters": "workspace:^",
"@editorjs/editorjs": "^2.30.5",
"@editorjs/model": "workspace:^"
"@editorjs/model": "workspace:^",
"@editorjs/sdk": "workspace:^"
}
}
2 changes: 2 additions & 0 deletions packages/core/src/entities/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './BlockTool.js';
export * from './Config.js';
23 changes: 22 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { BlockAddedEvent, EditorJSModel, EventType } from '@editorjs/model';
import type { CoreConfig, CoreConfigValidated } from './entities/Config.js';
import { composeDataFromVersion2 } from './utils/composeDataFromVersion2.js';
import ToolsManager from './tools/ToolsManager.js';
import { BlockToolAdapter, CaretAdapter } from '@editorjs/dom-adapters';
import { BlockToolAdapter, CaretAdapter, InlineToolsAdapter } from '@editorjs/dom-adapters';
import type { BlockAPI, BlockToolData, API as EditorjsApi, ToolConfig } from '@editorjs/editorjs';
import type { BlockTool } from './entities/BlockTool.js';
import { InlineToolbar } from './ui/InlineToolbar/index.js';

/**
* If no holder is provided via config, the editor will be appended to the element with this id
Expand Down Expand Up @@ -41,6 +42,21 @@ export default class Core {
*/
#caretAdapter: CaretAdapter;

/**
* Inline tool adapter is responsible for handling model formatting updates
* Applies format, got from inline toolbar to the model
* When model changed with formatting event, it renders related fragment
*/
#inlineToolsAdapter: InlineToolsAdapter;

/**
* @todo inline toolbar should subscripe on selection change event called by EventBus
* Inline toolbar is responsible for handling selection changes
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
* When model selection changes, it determines, whenever to show toolbar element,
* Which calls apply format method of the adapter
*/
#inlineToolbar: InlineToolbar;

/**
* @param config - Editor configuration
*/
Expand All @@ -55,6 +71,9 @@ export default class Core {

this.#toolsManager = new ToolsManager(this.#config.tools);
this.#caretAdapter = new CaretAdapter(this.#config.holder, this.#model);
this.#inlineToolsAdapter = new InlineToolsAdapter(this.#model, this.#caretAdapter);

this.#inlineToolbar = new InlineToolbar(this.#model, this.#inlineToolsAdapter, this.#toolsManager.getInlineTools(), config.holder!);

this.#model.initializeDocument({ blocks });
}
Expand Down Expand Up @@ -156,3 +175,5 @@ export default class Core {
return block;
}
}

export * from './entities/index.js';
20 changes: 18 additions & 2 deletions packages/core/src/tools/ToolsManager.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import type { InlineToolsConfig } from '@editorjs/sdk';
import type { BlockToolConstructor } from '../entities/BlockTool.js';
import { Paragraph } from './internal/paragraph/index.js';
import { Paragraph } from './internal/block-tools/paragraph/index.js';
import type { EditorConfig } from '@editorjs/editorjs';
import BoldInlineTool from './internal/inline-tools/bold/index.js';
import ItalicInlineTool from './internal/inline-tools/italic/index.js';

/**
* Works with tools
*/
export default class ToolsManager {
#tools: EditorConfig['tools'];

/**
* @param tools - Tools configuration passed by user
*/
constructor(private tools: EditorConfig['tools']) {
constructor(tools: EditorConfig['tools']) {
this.#tools = tools;
}

/**
Expand All @@ -24,4 +30,14 @@ export default class ToolsManager {
throw new Error(`Unknown tool: ${toolName}`);
}
}

/**
* Returns inline tools got from the EditorConfig tools
*/
public getInlineTools(): InlineToolsConfig {
return {
bold: BoldInlineTool,
italic: ItalicInlineTool,
};
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BlockToolAdapter } from '@editorjs/dom-adapters';
import type { BlockTool, BlockToolConstructorOptions } from '../../../entities/BlockTool.js';
import type { BlockTool, BlockToolConstructorOptions } from '../../../../entities/BlockTool.js';

/**
* Base text block tool
Expand Down
72 changes: 72 additions & 0 deletions packages/core/src/tools/internal/inline-tools/bold/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { FormattingActionWithRange, InlineTool } from '@editorjs/sdk';
import type { InlineFragment, TextRange } from '@editorjs/model';
import { FormattingAction } from '@editorjs/model';
import { IntersectType } from '@editorjs/model';
import { make } from '@editorjs/dom';

/**
* Bold Tool
*
* Inline Toolbar Tool
*
* Makes selected text bolder
*/
export default class BoldInlineTool implements InlineTool {
/**
* Specifies Tool as Inline Toolbar Tool
* @returns {boolean}
*/
public static isInline = true;

/**
* Type of behaviour of the tool if new selection range intersect with existing fragment
* If two fragment intersect, they should be merged
*/
public intersectType: IntersectType = IntersectType.Extend;

/**
* Renders wrapper for tool without actual content
* @returns Created html element
*/
public createWrapper(): HTMLElement {
return make('b');
}

/**
* Returns formatting action and range for it to be applied
* @param index - index of current text selection
* @param fragments - all fragments of the bold inline tool inside of the current input
*/
public getAction(index: TextRange, fragments: InlineFragment[]): FormattingActionWithRange {
return {
action: this.isActive(index, fragments) ? FormattingAction.Unformat : FormattingAction.Format,
range: index,
};
};

/**
* Returns state of the bold inline tool
* @param index - index of current selection
* @param fragments - all fragments of the bold inline tool inside of the current input
* @returns true if tool is active, false otherwise
*/
public isActive(index: TextRange, fragments: InlineFragment[]): boolean {
let isActive = false;

fragments.forEach((fragment) => {
/**
* Check if current index is inside of model fragment
*/
if (index[0] >= fragment.range[0] && index[1] <= fragment.range[1]) {
isActive = true;

/**
* No need to check other fragments if state already chaned
*/
return;
}
});

return isActive;
}
}
72 changes: 72 additions & 0 deletions packages/core/src/tools/internal/inline-tools/italic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { FormattingActionWithRange, InlineTool } from '@editorjs/sdk';
import type { InlineFragment, TextRange } from '@editorjs/model';
import { FormattingAction } from '@editorjs/model';
import { IntersectType } from '@editorjs/model';
import { make } from '@editorjs/dom';

/**
* Italic Tool
*
* Inline Toolbar Tool
*
* Makes selected text italic
*/
export default class ItalicInlineTool implements InlineTool {
/**
* Specifies Tool as Inline Toolbar Tool
* @returns {boolean}
*/
public static isInline = true;

/**
* Type of behaviour of the tool if new selection range intersect with existing fragment
* If two fragment intersect, they should be merged
*/
public intersectType: IntersectType = IntersectType.Extend;

/**
* Renders wrapper for tool without actual content
* @returns Created html element
*/
public createWrapper(): HTMLElement {
return make('i');
}

/**
* Returns formatting action and range for it to be applied
* @param index - index of current text selection
* @param fragments - all fragments of the bold inline tool inside of the current input
*/
public getAction(index: TextRange, fragments: InlineFragment[]): FormattingActionWithRange {
return {
action: this.isActive(index, fragments) ? FormattingAction.Unformat : FormattingAction.Format,
range: index,
};
};

/**
* Returns state of the bold inline tool
* @param index - index of current selection
* @param fragments - all fragments of the bold inline tool inside of the current input
* @returns true if tool is active, false otherwise
*/
public isActive(index: TextRange, fragments: InlineFragment[]): boolean {
let isActive = false;

fragments.forEach((fragment) => {
/**
* Check if current index is inside of model fragment
*/
if (index[0] >= fragment.range[0] && index[1] <= fragment.range[1]) {
isActive = true;

/**
* Don't need to check other fragments if state already chaned
*/
return;
}
});

return isActive;
}
}
Loading
Loading