Code Monkey home page Code Monkey logo

Comments (6)

easiwriter avatar easiwriter commented on June 20, 2024 1

from proton.

easiwriter avatar easiwriter commented on June 20, 2024

I have hit a similar problem and I think this is all down to the setter in public var attributedText: NSAttributedString

I have the following code:

 extension EditorView {
    func setAttributedText(_ text: NSAttributedString) {
        let selection = selectedRange
        attributedText = text
        selectedRange = selection
    }
 }

When this is called with text (for example) set to the value:

O{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001794d80; name = labelColor>";
    NSFont = "<UICTFont: 0x10bf38840> font-family: \"Helvetica Neue\"; font-weight: bold; font-style: normal; font-size: 34.00pt";
    NSParagraphStyle = "Alignment Center, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 10, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection Natural, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    WriteStyle = "Write_.StyleIdentifier(name: Optional(\"largeTitle\"), id: Optional(\"DD7AE374-223F-4B4C-B0B1-2BE741DC1C00\"))";
}ne{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001794d80; name = labelColor>";
    NSFont = "<UICTFont: 0x10c04fd30> font-family: \"Helvetica Neue\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
    NSParagraphStyle = "Alignment Left, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection LeftToRight, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    NSUnderline = 0;
}

It calls the setter which contains the lines:

 // Clear text before setting new value to avoid issues with formatting/layout when
 // editor is hosted in a scrollable container and content is set multiple times.
 richTextView.attributedText = NSAttributedString()

And that I think is the source of my problem - this, as it says, clears the text. The moment it does this it invokes textViewDidChangeSelection, which in turn ends up back in my code responding to the selection change. This all happens before the setter assigns the new value in:

richTextView.attributedText = newValue

Unfortunately my code has operated on the incorrect attributed string. This, I'm afraid, is a bit of a show stopper.

from proton.

rajdeep avatar rajdeep commented on June 20, 2024

@easiwriter, I am not sure if I am getting it fully. Just to share some context: this code, as comment states, is added to circumvent the issue of layout in UITextView. Please note that in case of simple text, this issue is not aggravated. However, when you have a large complex document with custom attributes and a lot of attachments, it has some inconsistent behaviour. In absence of this code, if there is some text with some formatting in the textview and then you reset some other text, in some cases, depending on the attributes it yields unexpected results - possibly trying to merge attributes at the same range. Furthermore, I observed that it also resulted in crashes in some specific cases as the layout calculations in that scenario get corrupted with old and new overlap.

Getting back to textViewDidChangeSelection invocation, if you notice when the text is cleared, the range is .zero and attributedText is also empty. Do you think you can have a check on your code to ignore or process based on this condition? Alternatively, if you help me understand what you are trying to do and the issue that this change causes, I may be able to provide additional info/callbacks that you can use so that you can ignore executing the code that you wish to prevent in such a case.

from proton.

rajdeep avatar rajdeep commented on June 20, 2024

also, not sure if this is relevant for you in this case, but you should know that the text is set only when Editor is already in a Window or when it moves to a Window. Please see the details here.

from proton.

easiwriter avatar easiwriter commented on June 20, 2024

I've added a flag which is set before assigning to attributedText such that any call backs to change selection are ignored. The code in the setter now gets to line 527 in the attributedText setter. At the line:

richTextView.attributedText = newValue

the newValue is correct.

A{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001784340; name = labelColor>";
    NSFont = "<UICTFont: 0x10ee37900> font-family: \"Helvetica Neue\"; font-weight: bold; font-style: normal; font-size: 34.00pt";
    NSParagraphStyle = "Alignment Center, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 10, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection Natural, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    WriteStyle = "Write_.StyleIdentifier(name: Optional(\"largeTitle\"), id: Optional(\"DAF9DAC4-5D4F-437A-B2B9-C8DCC6577DFC\"))";
}
{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001784340; name = labelColor>";
    NSFont = "<UICTFont: 0x11137a590> font-family: \"Helvetica Neue\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
    NSParagraphStyle = "Alignment Left, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection Natural, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    WriteStyle = "Write_.StyleIdentifier(name: Optional(\"body\"), id: Optional(\"51601A2C-0B6D-41B1-A05A-0219F541D050\"))";
}

The input text consists of the letter A followed by a newline. The app implements a style mechanism to control formatting. Instead of fiddling with formatting commands the user simply chooses a style from a menu. In the example above the letter A is formatted according to the attributes of LargeTitle. The style name is held as the custom attribute

WriteStyle = "Write_.StyleIdentifier(name: Optional(\"largeTitle\")

The second paragraph is set to the body style as shown by its style attribute.

This is where things go wrong. The newValue as I said is correct and the alignment of the second paragraph is Alignment Left. I had just changed this paragraph to use the body style.

However, the code below at RichTextView line 82 changes the alignment to Alignment Centre.

    override var attributedText: NSAttributedString! {
        willSet {
            // Remove all attachment subviews else we may run into PRTextStorage "in middle of editing" crash
            subviews.filter { $0 is AttachmentContentView }.forEach { $0.removeFromSuperview() }
        }
    }

Here is the text after this method is called

A{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001789840; name = labelColor>";
    NSFont = "<UICTFont: 0x113340ea0> font-family: \"Helvetica Neue\"; font-weight: bold; font-style: normal; font-size: 34.00pt";
    NSParagraphStyle = "Alignment Center, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 10, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection Natural, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    WriteStyle = "Write_.StyleIdentifier(name: Optional(\"largeTitle\"), id: Optional(\"DAF9DAC4-5D4F-437A-B2B9-C8DCC6577DFC\"))";
}
{
    NSColor = "<UIDynamicCatalogSystemColor: 0x600001789840; name = labelColor>";
    NSFont = "<UICTFont: 0x16d00c980> font-family: \"Helvetica Neue\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
    NSParagraphStyle = "Alignment Center, LineSpacing 1, ParagraphSpacing 0, ParagraphSpacingBefore 10, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1, LineBreakMode WordWrapping, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection Natural, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
    NSStrikethrough = 0;
    WriteStyle = "Write_.StyleIdentifier(name: Optional(\"body\"), id: Optional(\"51601A2C-0B6D-41B1-A05A-0219F541D050\"))";
}

I don't understand what is going on here because there is only one view, the one containing the text. The app only has a single EditorView. I can only assume that the code has somehow used the alignment of the first paragraph.

What is really don't understand is this is not new code. It was working OK before I took a rest for a few months, so I don't know if the changes to AttributedText (here and in the calling method) have been made during this period. If so this would account for the problems I'm now having.

from proton.

rajdeep avatar rajdeep commented on June 20, 2024

the code you have referenced here:

    override var attributedText: NSAttributedString! {
        willSet {
            // Remove all attachment subviews else we may run into PRTextStorage "in middle of editing" crash
            subviews.filter { $0 is AttachmentContentView }.forEach { $0.removeFromSuperview() }
        }
    }

has noting to do with attributedText or alignments of paragraph. This is specifically removing subviews added to the Editor via Attachment. If I understand it correctly, you are not using any attachments so this code should be of no consequence to you.

Over the past few months, I have been making a lot of updates to Proton which are primarily geared towards fixing bugs and performance issues. There may have been a change or a fix to a bug that is now causing a bug in your code or I might have accidentally fixed one bug and introduced another. I think we can do the following here:

  1. If it helps, please have a look at the Release Notes here for the time you were not actively developing the app and see if there's something obvious that shows up.
  2. If possible, please create a failing unit test case with your scenario and the expected output. If I have a failing test case, it will be much easier for me to provide a fix or advise if there's something that you may need to do differently.

Also, there is no code at all in Proton anywhere that changes the alignment of Paragraph to center. The only code around alignment that is there is in regards to the default paragraphStyle that you can set on the Editor which is automatically applied if the editor has some content and then entire content is deleted using backspace/select and delete.

from proton.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.