Atomic Text Blot in Quill - quill

Let's say I want to have an AtomicText blot that is similar to the default Link blot but is immutable and can only be removed as a whole. More specifically:
The cursor can be between the characters of AtomicText.
It is possible to select parts of AtomicText.
Deleting at least one character of AtomicText leads to the deletion of the whole AtomicText.
Adding characters to AtomicText is not possible once it has been created. Neither via keyboard events nor via copy and paste.
My idea was to make AtomicText extend from the Embed blot. In that case, the whole AtomicText blot is deleted when the cursor is right to its last character and backspace is pressed. But other operations do not work as expected. I assume I need to override some of the Blot methods to achieve the correct behavior but I am a bit at loss here.
Another idea is to listen to text-change events, determine if the cursor is inside an AtomicText blot and act accordingly. E.g., when pressing backspace, find the start and end position of the current AtomicText blot and remove all characters between these indexes. This seems to be a fragile approach.
Any pointers would be appreciated.
Similar questions/requests are the following:
How to make non selectable embed custom format in quilljs
How to add a non editable tag to content in Quill editor
Quill Editor: Restricted Editing based on tags/classes

I my experience setting contenteditable false is problematic. If you position the AtomicText blot at the end of the document you will not be able to append to it. Additionally, moving the cursor over the AtomicText positioned at the end will blur the editor.
I experienced a similar issue with a footnote blot. It's a sup tag that contains [\d+] and we don't want editors to modify the footnote but we do want them to be able to seamlessly move the cursor through them.
I have experimented with two other options in addition to the text-change listener mentioned by the OP. The first option is to attempt to position the cursor (via setSelection) in front or behind using selection-change event listeners. I found this to be problematic because it's possible to sneak characters in before the selection change event fires. I'm also not a fan of this approach because it causes the cursor to jump across the footnote. YMMV
Another option is to intercept keyboard input. You can add a keyboard listener (I used KeyboardJS) in a module that's initialized with quill. If the current selection is "inside" of your atomic text you can stop the input from proceeding to quill using e.preventDefault(). With this approach you'll also have to provide custom keyboard handlers in your quill configuration to override tab, enter, and possibly delete. Tabs are more of a challenge because there's a default tab handler provided by quill that takes precedence unless you override it. Within the custom handler you'll have to detect if the context is within your AtomicText. The context object will contain contain a format map that contains atomictext (your blot name) if it's in the context of AtomicText.
Note that if the user positions the cursor adjacent to your AtomicText, then from quill's perspective that's in the context of AtomicText. Our solution to that problem for input is to insert a zero width non breaking space, then allow the keyboard input to proceed. That "breaks" the cursor out of the AtomicText blot allowing insertion to proceed as expected. We then strip those characters out of the resulting HTML before saving the text.
Hope this helps.

In the blot create(value) function, add this:
node.setAttribute('contenteditable', false);

Related

Pressing a button to add an element to an array in LabVIEW

Is it possible to add an element to an array by pressing a button?
In such a way that the first press enters a '1' element, the second a '2' and so on.
Given how LabVIEW works, your question is borderline nonsensical. I'm going to try to untangle a few concepts that you seem to have conflated. I hope this doesn't come off as insulting -- I see genuine confusion and I'm hoping I can help.
First of all, what do you mean by "an array"? Do you mean the value on a wire or the value you see in a control on the front panel? LabVIEW's front panels are just the display of values computed in the block diagrams. In a running program, you never directly manipulate the values in any control. You can read the value, manipulate it, and then write it back to the control.
So, on the block diagram, yes, you can add an element to an array by using the "Build Array" node. And then you could display that value in an array indicator on the front panel.
You can have a button on the front panel that triggers an event. If that event code adds to an array, then you display that value in an indicator, then, yes, you can have a button that adds an element to an array. The code would look something like the code below. Notice that I never "add" an element to the array indicator. The array indicator simply updates every time the loop runs with whatever the computed value happens to be.
PS: the other frame of the event structure is just a "Stop" button handler.
The solution suggested by srm works fine.
Just a note: be careful with the tunnel options for the wires. If you add some other event cases on the Event Structure, you should disable the tunnel option: Use Default value. Otherwise, when this new event cases are handled, this reset the shift register array value.
See screeshot below

how to intercept winform textbox selection right click copy

I need to transform the copied selection in a winform textbox before copying to clipboard. I have the ctrl-c done, but the right click copy would seem to require overriding WinProc,and the link in an example in how to disable copy, Paste and delete features on a textbox using C# for WM_PASTE is no longer is valid. I would add failure may be a feature, because Ctrl-c could be transformed and right click copy could be the literal, both of which I need to do. I had hoped to radio button a state for a transformed or literal selection for choosing behavior.
My question was based on reading that the only way to do this was to handle a WM_COPY, but the better solution would be to implement a context menu strip for each text box as needed.
The right click context would then be handled by event handlers.

NVDA and JAWS reading order using React

When using NVDA on Firefox, it reads in row-wise order in React. How can I change the reading order?
Sample code:
<Row1>
<row-item-left>{some content1-left}</row-item-left>
<row-item-right>{some content1-right}</row-item-right>
<Row1>
<Row2>
<row-item-left>{some content2-left}</row-item-left>
<row-item-right>{some content2-right}</row-item-right>
<Row2>
Now it reads, "some content1-left, some content1-right, some content2-left, and some content2-right." I want it to read, "some content1-left, some content2-left, some content1-right," and, "some content2-right."
I use tabindex. It's working fine with tabs, but I don't want to focus elements Also it's not working with arrow keys. Please help me on this.
The reading order is always the same as it appears in the accessibility tree, and the accessibility tree is built from the DOM.
This basic rule can't be changed. CSS has no effect on reading order.
So if you want the content to be read column by column instead of row by row, you have no choice but rearrange your code so that it appears in the right order in the source:
<row-item-left>{some content1-left}</row-item-left> 
<row-item-left>{some content2-left}</row-item-left> 
<row-item-right>{some content1-right}</row-item-right> 
<row-item-right>{some content2-right}</row-item-right> 
I leave CSS experts tell you how you can achieve it.
Firstly accessibility isn't about what you want, never try to change expected behaviour.
When using a screen reader it is expected that items flow from left to right, top to bottom in 99% of cases (the way you would read the page normally).
The idea is that a screen reader user gets the same experience as someone who does not need to use one.
With regards to focus, never interfere with that either if it is something that is interactive (a clickable cell, link etc.).
If something is focusable it should also have a distinctive border (this helps users who use tab to navigate due to mobility issues know where their current cursor is placed on your site.) - just an extra tip, not relevant to your question.
The current read order is correct, do not interfere with it.
With regards to using arrow keys that may be useful, just use JavaScript to intercept the key presses and move focus accordingly (give that a go and post another question with a code example if you get stuck.)
Bear in mind you should also provide a way for people to disable this arrow key behaviour as they may have changed the key bindings on their screen reader and that would cause accessibility issues if your JavaScript interferes with their preferred key bindings.
I am not sure why you said you don't want to focus the element, if your custom HTML elements have focus in the first place then adjust those elements (as you must have added a tabindex=0 or some JS to those elements in the first place to make them focusable as <divs> are not focusable by default.)

WPF Avalon Edit Make text upper case

I am using C# WPF with Avalon Edit Text Box.
I am trying to make all of the text in the text box uppercase and I get an error with additional message 'No undo group should be open at this point'.
I am using the following code:
a.Text = a.Text.ToUpper();
where "a" is the AvalonEdit.TextEditor
Thank you.
Setting the TextEditor.Text property has the side-effect of clearing the undo stack (just as with the normal WPF TextBox). Clearing the undo stack is only allowed when there's no open undo group.
If you did not intend to clear the undo stack, use the methods on textEditor.Document instead to modify the document. You'll want to avoid replacing the whole text, because that would also reset the selection and caret position (after all, AvalonEdit can't know how your new text is related to the old text).
If you do want to clear the undo stack (e.g. you're switching the view to a different document), you'll have to figure out why an undo group is open. Most likely, your code is running from the event handler of an event that is called while the undo group is still open (e.g. document.TextChanged) -- you might want to switch to a different event instead (e.g. document.UpdateFinished is called after the undo group was closed).
If all you want to do is to upper-case text as it is being input, it's better to modify the text before it is added to the document: handle the TextArea.TextEntering event to cancel any lower-case input (set e.Handled = true;), and instead call TextArea.PerformTextInput() to repeat the text input process with the corresponding upper-case text instead.
For copy-paste, you could handle the attached DataObject.PastingEvent and modify the data to be pasted.

Protecting custom inline elements in WPF RichTextBox

I'm currently spiking with the WPF RichTextBox before I decide whether or not it can be used in a project of mine.
What I need is to have elements of text representing various objects (other texts or objects), a bit like a WIKI but not quite. Clicking on such a text will make stuff happen, like navigating to other texts or providing additional options.
Anyway, as these little text bits represent other objects I would like to protect them but I have succeeded with this only in part: The user cannot position a caret inside such a text element and edit/delete it but it is still possible to make a selection and delete/replace it, including my custom elements.
Have anyone travelled down this road with the RichTextBox? My latest experiment was to simply record all custom text elements when being part of a selection and then restoring them after the (destructive) edit. That fell apart because I can't find a way to re-insert my custom inline elements (derived from the Run class). The only way I've found to programmatically insert a Run (based) element at a specified position (TextPosition) is via its constructor.
Well, any hints would be greatly appreciated.
You are really looking for a FlowDocument, not a RichTextBox.

Resources