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: Add unique ids for each block #1493

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions cypress/plugins/index.js
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This supposed to be here?

*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
2 changes: 1 addition & 1 deletion dist/editor.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions example/example-dev.html
Expand Up @@ -192,6 +192,7 @@
data: {
blocks: [
{
id: "1bfa3a88-a6e3-4a13-8553-d8c85bf2497b",
type: "header",
data: {
text: "Editor.js",
Expand Down
8 changes: 8 additions & 0 deletions src/components/block/api.ts
Expand Up @@ -14,6 +14,14 @@ function BlockAPI(
block: Block
): void {
const blockAPI: BlockAPIInterface = {
/**
* Tool id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Tool id
* Block id

*
* @returns {string}
*/
get id(): string {
return block.id;
},
/**
* Tool name
*
Expand Down
14 changes: 14 additions & 0 deletions src/components/block/index.ts
Expand Up @@ -27,6 +27,11 @@ import SelectionUtils from '../selection';
* Interface describes Block class constructor argument
*/
interface BlockConstructorOptions {
/**
* Tool's id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Tool's id
* Block's id

*/
id: string;

/**
* Tool's name
*/
Expand Down Expand Up @@ -107,6 +112,11 @@ export default class Block {
};
}

/**
* unique identifier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* unique identifier
* Block unique identifier

*/
public id: string;

/**
* Block Tool`s name
*/
Expand Down Expand Up @@ -199,6 +209,7 @@ export default class Block {

/**
* @param {object} options - block constructor options
* @param {string} options.id - Tool's unique id
* @param {string} options.name - Tool name that passed on initialization
* @param {BlockToolData} options.data - Tool's initial data
* @param {BlockToolConstructable} options.Tool — Tool's class
Expand All @@ -207,13 +218,15 @@ export default class Block {
* @param {boolean} options.readOnly - Read-Only flag
*/
constructor({
id,
name,
data,
Tool,
settings,
api,
readOnly,
}: BlockConstructorOptions) {
this.id = id;
this.name = name;
this.class = Tool;
this.settings = settings;
Expand Down Expand Up @@ -550,6 +563,7 @@ export default class Block {
measuringEnd = window.performance.now();

return {
id: this.id,
tool: this.name,
data: finishedExtraction,
time: measuringEnd - measuringStart,
Expand Down
1 change: 1 addition & 0 deletions src/components/core.ts
Expand Up @@ -174,6 +174,7 @@ export default class Core {
* @type {{type: (*), data: {text: null}}}
*/
const defaultBlockData = {
id: _.generateUuidv4(),
type: this.config.defaultBlock,
data: {},
};
Expand Down
6 changes: 5 additions & 1 deletion src/components/modules/blockManager.ts
Expand Up @@ -219,11 +219,12 @@ export default class BlockManager extends Module {
*
* @returns {Block}
*/
public composeBlock({ tool, data = {} }: {tool: string; data?: BlockToolData}): Block {
public composeBlock({ tool, id = _.generateUuidv4(), data = {} }: {tool: string; id?: string; data?: BlockToolData}): Block {
const readOnly = this.Editor.ReadOnly.isEnabled;
const settings = this.Editor.Tools.getToolSettings(tool);
const Tool = this.Editor.Tools.available[tool] as BlockToolConstructable;
const block = new Block({
id,
name: tool,
data,
Tool,
Expand Down Expand Up @@ -252,12 +253,14 @@ export default class BlockManager extends Module {
* @returns {Block}
*/
public insert({
id = _.generateUuidv4(),
tool = this.config.defaultBlock,
data = {},
index,
needToFocus = true,
replace = false,
}: {
id?: string;
tool?: string;
data?: BlockToolData;
index?: number;
Expand All @@ -271,6 +274,7 @@ export default class BlockManager extends Module {
}

const block = this.composeBlock({
id,
tool,
data,
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/modules/paste.ts
Expand Up @@ -759,7 +759,7 @@ export default class Paste extends Module {
*
* @returns {void}
*/
private insertEditorJSData(blocks: Array<Pick<SavedData, 'data' | 'tool'>>): void {
private insertEditorJSData(blocks: Array<Pick<SavedData, 'id' | 'data' | 'tool'>>): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id seems unused.

Suggested change
private insertEditorJSData(blocks: Array<Pick<SavedData, 'id' | 'data' | 'tool'>>): void {
private insertEditorJSData(blocks: Array<Pick<SavedData, 'data' | 'tool'>>): void {

const { BlockManager, Sanitizer, Tools } = this.Editor;
const sanitizedBlocks = Sanitizer.sanitizeBlocks(blocks);

Expand Down
6 changes: 6 additions & 0 deletions src/components/modules/renderer.ts
Expand Up @@ -22,12 +22,14 @@ export default class Renderer extends Module {
*
* blocks: [
* {
* id : 'eab2b1cd-a3d3-48d1-aadb-bd821d8ec871',
* type : 'paragraph',
* data : {
* text : 'Hello from Codex!'
* }
* },
* {
* id : '391a1351-6ec6-473b-8b99-b20507e2d4c2',
* type : 'paragraph',
* data : {
* text : 'Leave feedback if you like it!'
Expand Down Expand Up @@ -63,12 +65,14 @@ export default class Renderer extends Module {
*/
public async insertBlock(item: OutputBlockData): Promise<void> {
const { Tools, BlockManager } = this.Editor;
const id = item.id;
const tool = item.type;
const data = item.data;

if (tool in Tools.available) {
try {
BlockManager.insert({
id,
tool,
data,
});
Expand All @@ -80,6 +84,7 @@ export default class Renderer extends Module {
/** If Tool is unavailable, create stub Block for it */
const stubData = {
savedData: {
id,
type: tool,
data,
},
Expand All @@ -94,6 +99,7 @@ export default class Renderer extends Module {
}

const stub = BlockManager.insert({
id,
tool: Tools.stubTool,
data: stubData,
});
Expand Down
3 changes: 2 additions & 1 deletion src/components/modules/saver.ts
Expand Up @@ -78,7 +78,7 @@ export default class Saver extends Module {

_.log('[Editor.js saving]:', 'groupCollapsed');

allExtractedData.forEach(({ tool, data, time, isValid }) => {
allExtractedData.forEach(({ id, tool, data, time, isValid }) => {
totalTime += time;

/**
Expand All @@ -105,6 +105,7 @@ export default class Saver extends Module {
}

blocks.push({
id,
type: tool,
data,
});
Expand Down
15 changes: 15 additions & 0 deletions src/components/utils.ts
Expand Up @@ -607,6 +607,21 @@ export function getValidUrl(url: string): string {
}
}

/**
* Creates a UUID v4 version
*
* @returns {string}
*/
export function generateUuidv4(): string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to name this method just as generateId() and make UUIDv4 "private". E.g.

export function generateId(): string {
    return uuidv4();
}

function uuidv4(): string {
  // your code
}

so that we could change the id generator algorithm

return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
// tslint:disable: no-bitwise
// tslint:disable-next-line: triple-equals
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);

return v.toString(16);
});
}

/**
* Opens new Tab with passed URL
*
Expand Down
5 changes: 5 additions & 0 deletions types/api/block.d.ts
Expand Up @@ -5,6 +5,11 @@ import {SavedData} from '../data-formats';
* @interface BlockAPI Describes Block API methods and properties
*/
export interface BlockAPI {
/**
* Tool name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Tool name
* Block unique identifier

*/
readonly id: string;

/**
* Tool name
*/
Expand Down
2 changes: 2 additions & 0 deletions types/data-formats/block-data.d.ts
Expand Up @@ -4,6 +4,7 @@ import {BlockToolData} from '../tools';
* Tool's saved data
*/
export interface SavedData {
id: string;
tool: string;
data: BlockToolData;
time: number;
Expand All @@ -13,6 +14,7 @@ export interface SavedData {
* Tool's data after validation
*/
export interface ValidatedData {
id?: string;
tool?: string;
data?: BlockToolData;
time?: number;
Expand Down
4 changes: 4 additions & 0 deletions types/data-formats/output-data.d.ts
Expand Up @@ -4,6 +4,10 @@ import {BlockToolData} from '../tools';
* Output of one Tool
*/
export interface OutputBlockData {
/**
* Unique Id of the block
*/
id?: string;
/**
* Too type
*/
Expand Down