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

toPlainText method from any Embeddable return text that cannot be used outside of the editor #2065

Closed
1 task done
CatHood0 opened this issue Jul 25, 2024 · 13 comments
Closed
1 task done
Assignees
Labels
bug Something isn't working

Comments

@CatHood0
Copy link
Collaborator

CatHood0 commented Jul 25, 2024

Is there an existing issue for this?

The question

I watch this code on Line class:

  int _getNodeText(Leaf node, StringBuffer buffer, int offset, int remaining) {
    final text = node.toPlainText();
    if (text == Embed.kObjectReplacementCharacter) {
      buffer.write(Embed.kObjectReplacementCharacter); 
      return remaining - node.length;
    }

    final end = math.min(offset + remaining, text.length);
    buffer.write(text.substring(offset, end));
    return remaining - (end - offset);
  }

It's really useful the Embed can be copied and paste multiple times, but, it's difficult if you have just a CustomBlockEmbed with just plainText and this text is not copied on the clipboard as plainText. I don't know if i already fully explain what is exactly the issue, then you can see this #2050 to undertand better this.

If you try to copy any Embed , you can see the text is just empty even the Embed contains data as String or the toPlainText from the EmbedBuilder is overrided. I fixed this partially adding this part of code:

    if (text == Embed.kObjectReplacementCharacter) {
      final nodeValue = node.value;
      if (nodeValue is Embeddable && !['video','image','custom','formula','table'].contains(nodeValue.type) && nodeValue.data != null && nodeValue.data is String) {
        buffer.write(nodeValue.data);
      } else {
        buffer.write(Embed.kObjectReplacementCharacter);
      }
      return remaining - node.length;
    }

But i prefer the root error. Could anyone suggest where should i take a look?

@CatHood0 CatHood0 added the help wanted Extra attention is needed label Jul 25, 2024
@CatHood0 CatHood0 self-assigned this Jul 25, 2024
@CatHood0
Copy link
Collaborator Author

@EchoEllet are you familiar with these parts of code?

@CatHood0 CatHood0 changed the title toPlainText method from any Embeddable is not being called on cut or copy selection toPlainText method from any Embeddable return text that cannot be used outside of the editor Jul 25, 2024
@CatHood0 CatHood0 added bug Something isn't working and removed help wanted Extra attention is needed labels Jul 25, 2024
@EchoEllet
Copy link
Collaborator

@EchoEllet are you familiar with these parts of code?

I didn't work on them, and I was planning to before. I moved some parts to different files for organization.

@CatHood0
Copy link
Collaborator Author

CatHood0 commented Jul 25, 2024

I didn't work on them, and I was planning to before

I fix partially to copy just the plain text for custom embeds, but, this could break the feature that let the editor paste the Embed to the editor

@singerdmx
Copy link
Owner

toPlainText is more of debugging purpose like dumping the log

@singerdmx
Copy link
Owner

Copy/paste embed was not supported in the beginning. This is more of enhancement.
And you don't have to rely on toPlainText method to do that.
I mean you can either change the behavior of toPlainText or just create some new method.

@CatHood0
Copy link
Collaborator Author

CatHood0 commented Jul 25, 2024

I mean you can either change the behavior of toPlainText or just create some new method.

At this case, the OP has an issue where he cannot copy the plain text from his custom implementation of a Embeddable. I tried to see if there's a issue on toPlainText but seems this cannot be the case.

@singerdmx
Copy link
Owner

Honestly copy/paste was barely working in the beginning, let alone copy/paste embed.
I suggest to deal with this problem with a new method instead of using toPlainText

@CatHood0
Copy link
Collaborator Author

I suggest to deal with this problem with a new method instead of using toPlainText

I will try to do this. Thanks for the suggestion

@singerdmx
Copy link
Owner

If we can get copy/paste of embed working, it would be a significant new feature

@singerdmx
Copy link
Owner

@CatHood0 toPlainText returns string. I wonder if we should define a method that returns more than just string since string is pretty limited in the info it can convey.

@CatHood0
Copy link
Collaborator Author

CatHood0 commented Jul 25, 2024

@singerdmx I already added a method to make the same of toPlainText, but it need to ve overrided by the developer to get any custom data. But, i'm getting unexpected behaviors. I don't know why any custom Embeddable doesn't have the functions that i overrided.

Embeddable class looks like:

class Embeddable {
  const Embeddable(this.type, this.data);

  /// The type of this object.
  final String type;

  /// The data payload of this object.
  final dynamic data;

  /// Get the plain text from the [Embeddable] data
  ///
  /// By default it's false 
  bool pasteAsPlaintext() => false;

  Map<String, dynamic> toJson() {
    return {type: data};
  }

  static Embeddable fromJson(Map<String, dynamic> json) {
    final m = Map<String, dynamic>.from(json);
    assert(m.length == 1, 'Embeddable map must only have one key');

    return Embeddable(m.keys.first, m.values.first);
  }
}

I tried this custom embed

class ContentTagEmbed extends CustomBlockEmbed {
  const ContentTagEmbed(
    String value,
  ) : super(timeStampType, value);

  static const String timeStampType = 'content_tag';

  @override
  bool pasteAsPlaintext() => true;

  static ContentTagEmbed fromDocument(Document document) => ContentTagEmbed(jsonEncode(document.toDelta().toJson()));

  Document get document => Document.fromJson(jsonDecode(data));
}

But always return false. I could be missing something?

If you wonder how is working now _getNodeText from Line class it's now:

  int _getNodeText(Leaf node, StringBuffer buffer, int offset, int remaining) {
    final text = node.toPlainText();
    if (text == Embed.kObjectReplacementCharacter) {
      final embed = node.value as Embeddable; 
      if (embed.pasteAsPlaintext()) {
        buffer.write(embed.data);
      } else {
        buffer.write(Embed.kObjectReplacementCharacter);
      }
      return remaining - node.length;
    }

    final end = math.min(offset + remaining, text.length);
    buffer.write(text.substring(offset, end));
    return remaining - (end - offset);
  }

@singerdmx
Copy link
Owner

Maybe @EchoEllet knows

@CatHood0
Copy link
Collaborator Author

I'm thinking the option where we could have a service (like Clipboard) to this new feature to make more easy extend from it or just override the default operations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants