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

CharacterCount.limit does not match getCharacterCount() or state.doc.content.size #1839

Closed
stefan-schweiger opened this issue Sep 3, 2021 · 5 comments · Fixed by #2256
Closed
Labels
Type: Bug The issue or pullrequest is related to a bug

Comments

@stefan-schweiger
Copy link

stefan-schweiger commented Sep 3, 2021

Description
When the content of the editor contains something like a list the set limit for CharacterCount does not match any properties returned from the editor.

For example:
image

The limit is set to 20, but getCharacterCount() returns 22 and state.doc.content.size returns 24.

While I would expect the actual count to be 15 (chars + new line), I think at least the CharacterCount extension should match the limit to getCharacterCount. I've looked into the source code and it seems like the extension uses state.doc.content.size but for whatever reason the result is even more off.

CodeSandbox
I created a CodeSandbox to help you debug the issue:

@stefan-schweiger stefan-schweiger added Type: Bug The issue or pullrequest is related to a bug v2 labels Sep 3, 2021
@vedraan
Copy link

vedraan commented Sep 14, 2021

Also seeing this, my limit is set to 5000, but the actual count always goes up to 5002. Two characters seem to be getting lost somewhere.

As a very crude hide-a-bug "solution" which should go unnoticed to users due to a high limit I'm rendering the count as:
Math.min(editor.getCharacterCount(), limit) and adjusting validation to also allow some extra.

But this needs real fixing.

@hanspagel hanspagel removed the v2 label Sep 28, 2021
@philippkuehn philippkuehn mentioned this issue Oct 26, 2021
10 tasks
@gjccing
Copy link

gjccing commented Nov 23, 2021

The state.doc.content.size can not represent the total visible character in the input area.
The state.doc contains some block nodes and those block nodes' self sizes will be counted 2

In @stefan-schweiger demo content:

<ul>
    <li>
        123456
    </li>
    <li>
        12345678
    </li>
</ul>

Before starting to count its character, we should notice the listItem node's content is 'paragraph block*', so it has an extra paragraph in a listItem, so it has 3 block nodes, 2 extra block nodes, and 14 characters so the state.doc.content.size will be 24.

And below is the getCharacterCount() source code, which is why it returns 22:

public getCharacterCount(): number {
    return this.state.doc.content.size - 2
}

https://github.com/ueberdosis/tiptap/blob/main/packages/core/src/Editor.ts#L447-L449

And I found the editor.getText() returns value length maybe is what you expect the number of the character in the input area, it returns 16 characters:

123456

12345678

If you call it like this: editor.getText({ blockSeparator: '\n' }), its return value length will be 15, just your like your estimation.

@gjccing
Copy link

gjccing commented Nov 23, 2021

How about adding these three options to this extension:

{
  countThroughSerializer: boolean, // default: false
  blockSeparator: string // default: '\n\n'
  textSerializers: Record<string, TextSerializer>,
}
  • If countThroughSerializer is true, the extension will switch to use a method that works like editor.getText() for counting. The method used by the countThroughSerializer, its using serializer should merge with the serialize defined in the schema. I am not sure that should directly change the original logic, so I added it first.
  • The blockSeparator is the same as the editor.getText argument.
  • The textSerializers is the custom default serializer for counting.

@gjccing
Copy link

gjccing commented Nov 24, 2021

But the above change, still can't provide the counting number to show, I guess it has to write the number in editor.storage and listen to the onUpdate or onTransaction to update the number.

@gjccing
Copy link

gjccing commented Nov 25, 2021

I have added a pr for this problem.
It only adds the option countThroughSerializer because I don't want to make using way too complicated.

Below code is how to enable it:

CharacterCount.configure({
  limit,
  countThroughSerializer: true,
}),

Here is a new way to get the character number of this extension counting:

editor.storage.characterCount.currentCharacterCount

Welcome to any discussion and suggestions and hope this change would be helpful. 🙂

philippkuehn added a commit that referenced this issue Dec 8, 2021
…#1049, fix #1550, fix #1839, fix #2245

* fix a bug when exceeding the character limit

* find a better way to limit the doc size

* check paste events

* add storage method

* refactoring

* use textBetween instead of textContent

* return early if no limit is set

* add words method to storage

* show word count in charactercount demo

Co-authored-by: Philipp Kühn <philippkuehn@MacBook-Pro-von-Philipp.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug The issue or pullrequest is related to a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants