Projects new and old

Workarounds and usability notes.

Re: Projects new and old

Postby John Robin Dove » Mon Jul 01, 2024 6:39 am

Thanks for the example. I still don't seem to be able to insert text programatically although I can now do it with the keyboard and I can also position the caret using the mouse. This code works but only if the user is not allowed to add colored words before the position of the last colored word added.
Code: Select all
  let values = this.getTheWord();
  let start = values[0]; //start is immediately in front of the word.
  let myWord = values[1];
  start = start * 1;
  console.log(start + " " + myWord);
  tbfunction_caretPosition("myText2", start);
  const start2 = ('0000' + start).slice(-5);
  const myID = "w" + start2;
  const newWord = '<span id=' + String.fromCharCode(34) + myID + String.fromCharCode(34) + ' onclick= "top.relay(' + String.fromCharCode(39) + myID + String.fromCharCode(39) + ')" class="blueWords"> ' + myWord + '</span>';
  start += this.offset;
  let htm = this.obj2.innerHTML
  let end = htm.length;
  let front = htm.substring(0, start);
  let back = htm.substring(start, end);
  htm = front + "ˆ" + back;  // ansi 136 - standalone circonflex accent not used in any languages that I know of but I remove all instances just in case and replace them with a space.
  let oldWord = "ˆ" + myWord
  htm = tbfunction_pgReplace(oldWord, newWord, htm);
  this.obj2.innerHTML = htm;
  this.offset += 73; //No of characters added. This is fixed.

Is there a way I could get the real position in the innerHTML instead of the apparent visible position?
John Robin Dove
 
Posts: 538
Joined: Thu Jan 23, 2014 4:35 am

Re: Projects new and old

Postby Clifton » Mon Jul 01, 2024 8:45 am

You could try the paramter "afterLast" to be able to colorize the words after previously colorized words.

The problem is the function is trying to avoid a situation where added content becomes nested <span> tags. Once the <span> tags are nested, they can no longer be manipulated programmatically and typing manually into the field becomes anomalous too.

<div contentEditable="true">
This is my content. <span class="blueWords">these are blue words. <span class="yellowWords">These are yellow words.</span></span> Continuing the dialog.
</div>


The above shows a "nested" condition. It will now be very unpredictable to manipulate the double nested words as ranges will consider them as one node. Plus setting the caret position inside the nested <span> tags is virtually impossible, though you can do it with the mouse manually.

But if you use "afterLast", the function will try and take your HTML and add an empty text node between it and any previous <span> tag and try and make it work. I have had some success with this.

I keep having additional ideas how to make this work even better and I will continue to work at it. I will let you know if I get another version you can work with.
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

Re: Projects new and old

Postby John Robin Dove » Mon Jul 01, 2024 9:33 am

Thanks Clifton,
I'm not sure how to use afterLast. I thought it might give me the real number of characters in the innerHTML if I did this: let pos = tbfunction_caretPosition("myText2", -1, "afterLast"); but it doesn't. I may have to settle for my offset system. It seems to work every time and allows you to create a colored word anywhere in the text even if the word selected is identical to a previous colored word, which I find pretty cool. :) I could also give instructions about creating colored words in the right order and make it impossible for the user to do otherwise.
John Robin Dove
 
Posts: 538
Joined: Thu Jan 23, 2014 4:35 am

Re: Projects new and old

Postby Clifton » Mon Jul 01, 2024 10:05 am

Usage of the "afterLast":
Suppose this block of text:
"The large cat went down the street looking for the small aligator."

tbfunction_caretPosition( [fieldName], /the/g, "afterLast", " big turtle and the ");


Result:
"The large cat went down the street looking for the big turtle and the small aligator."

The function puts the caret AFTER the LAST instance of the word "the" and then it ADDS the new content AFTER the caret position. The return from the function is the caret position when the function has completed it's task.
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

Re: Projects new and old

Postby Clifton » Mon Jul 01, 2024 2:56 pm

Hi John,

Give the updated version of the PowerPac v15.533.0 a try on your project.
This version can allow nested tags so you can set colors regardless of whether the tags get nested.

All of my tests with this version succeeded without incident in Chrome (also Edge) and Firefox. Of course, you may find some strange behavior on your end.

Also this version has a new parameter called selAddedContent and permits setting selection status of any content you insert using the function.

Let me know how it goes.
Clifton
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

Re: Projects new and old

Postby John Robin Dove » Tue Jul 02, 2024 4:08 am

Hi Clifton, thanks for your efforts. I was able to install version 15.533.1 but I didn't find selAddedContent and unfortunately my makeBlueWord system no longer functions correctly in this version.
Code: Select all
<function name="makeBlueWord" event="" params="">
  <![CDATA[
  let values = this.getTheWord();
  let start = values[0]; //start is immediately in front of the word.
  let myWord = values[1];
  start = start * 1;
  //console.log(start + " " + myWord);
  tbfunction_caretPosition("myText2", start);
  const start2 = ('0000' + start).slice(-5);
  const myID = "w" + start2;
  const newWord = '<span id=' + String.fromCharCode(34) + myID + String.fromCharCode(34) + ' onclick= "top.relay(event,' + String.fromCharCode(39) + myID + String.fromCharCode(39) + ')" class="blueWords"> ' + myWord + '</span>';
 
  start-= 1; // This has become necessary. I don't think it should be. I think that somehow the innerHTML loses a line break at the beginning of the current paragraph.
 
  start += this.offset; //To do: if the user tries to insert a colored word BEFORE the last one created start will be anomalous so check that htm[start] + htm[start + 1] etc (use myWord.length) does correspond to myWord.
  tbfunction_caretPosition("myText2", start, "", "ˆ");
  let htm = this.obj2.innerHTML
  let oldWord = "ˆ" + myWord
  htm = tbfunction_pgReplace(oldWord, newWord, htm);
  this.obj2.innerHTML = htm;
  this.offset += 79; //No of characters added. This is fixed.
  ]]> 
  </function>
<function name="getTheWord" event="" params="">
  <![CDATA[
  const txt = tbfunction_pgTBObjGet("myText2", "text");
  let txtEnd = txt.length;
  let pos = tbfunction_caretPosition("myText2", -1);
  let ws = /\s/.test(txt[pos]);
    if (ws)
    {
    pos -= 1;
    }
  pos -= 1;
  let start;
  let end;
  ws = /\s/.test(txt[pos]);
    while (ws == false && pos > -1)
    {
    pos -= 1;
    ws = /\s/.test(txt[pos]);
    }
  pos += 1;
  start = pos;
  pos += 1;
  ws = /\s/.test(txt[pos]);
    while (ws == false && pos < txtEnd)
    {
    pos += 1;
    ws = /\s/.test(txt[pos]);
    }
  pos -= 1;
  end = pos;
  let str = txt[start];
  pos = start;
    while (pos < end + 1 && pos < txtEnd - 1)
    {
    pos += 1
    str = str + txt[pos]
    }
  //this.obj.setSelectionRange(start, end + 1);
  return [start, str];
  ]]>
  </function>


Here is the block of text I am using: The reading and writing classes however, were a great success. By the autumn almost every animal on the farm was literate in some degree.
As for the pigs, they could already read and write perfectly. The dogs learned to read fairly well, but were not interested in reading anything except the Seven Commandments. Muriel, the goat, could read somewhat better than the dogs, and sometimes used to read to the others in the evenings from scraps of newspaper which she found on the rubbish heap.
I am trying to add a link span around the first instance of could (they could already ...) but when I run my code the line break after degree gets taken out and if I try to add more spans the whole system goes haywire. This system worked perfectly in the previous version, as long as you didn't try to create a span before the last span added and I could add multiple spans without any errors occuring. So could I have 15.531.3 back please?
John
John Robin Dove
 
Posts: 538
Joined: Thu Jan 23, 2014 4:35 am

Re: Projects new and old

Postby Clifton » Thu Jul 04, 2024 7:12 am

Hi John,

I uploaded a new version with many fixes to caretPosition() and related functions and routines.

Please give v15.536.0 it a try and let me know how it goes. I have run it through many complex scenarios with great success. While there are a number of fixes in this release, the primary issue with all of this is relocating the caret after injecting HTML into the field. It is by no means as simple as just selecting a range—that is the easy part. But to place the caret inside previously injected HTML content is a very complicated task which finally uses the Javascript range function called setBaseAndExtent(). Locating the extent is where it gets challenging. You can read about this on MDN (https://developer.mozilla.org/en-US/docs/Web/API/Selection/setBaseAndExtent). Nevertheless, I find all of this useful in my own work in the near future.

I will use the code you provided a couple of days ago and run a few tests as well, but for now I have another project in the works.

Thank you for your feedback!
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

Re: Projects new and old

Postby Clifton » Thu Jul 04, 2024 7:23 am

Forgot to mention that the new version parses the parameter add_content for HTML and even allows use of links and onclick events in your HTML. I have successfully tested links to webpages in this version with the link using mouseover/out effects as well. Clicks can be used to generate feedback messages work well too.

I'm sure when you put to use, you will find some anomalies and I am interested in what you find. Fixing them may be another story, but ...
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

Re: Projects new and old

Postby John Robin Dove » Fri Jul 05, 2024 6:44 am

Hi Clifton,
Well done and thanks very much! I appreciate just how difficult and complex a task this is. At first I thought 100% of my problem was solved. It was about 99%. There seems to be just one thing that can produce an error: if the text contains more than one paragraph. In this case, if you start by selecting a word in the first paragraph, thereafter all blue words will be added correctly. If however you start by selecting a word in the second paragraph, the start position is anomalous. I think it is important to show exactly the text am I am using. The original from here https://gutenberg.net.au/ebooks01/0100011h.html (search for "The reading") is divided into paragraphs so the copied text is:
Code: Select all
The reading and writing classes, however, were a great success. By the autumn almost every animal on the farm was literate in some degree.

As for the pigs, they could already read and write perfectly. The dogs learned to read fairly well, but were not interested in reading anything except the Seven Commandments. Muriel, the goat, could read somewhat better than the dogs, and sometimes used to read to the others in the evenings from scraps of newspaper which she found on the rubbish heap. Benjamin could read as well as any pig, but never exercised his faculty. So far as he knew, he said, there was nothing worth reading. Clover learnt the whole alphabet, but could not put words together. Boxer could not get beyond the letter D. He would trace out A, B, C, D, in the dust with his great hoof, and then would stand staring at the letters with his ears back, sometimes shaking his forelock, trying with all his might to remember what came next and never succeeding. On several occasions, indeed, he did learn E, F, G, H, but by the time he knew them, it was always discovered that he had forgotten A, B, C, and D. Finally he decided to be content with the first four letters, and used to write them out once or twice every day to refresh his memory. Mollie refused to learn any but the six letters which spelt her own name. She would form these very neatly out of pieces of twig, and would then decorate them with a flower or two and walk round them admiring them.
I then get rid of any 'empty lines' etc like this:
Code: Select all
  <selection1>
  <function name="myUser" event="user" params="evt,value" useTB="true">
  <![CDATA[
  setLanguage(sharedActions.langNo);
  let txt = tbfunction_pgTBObjGet("myText", "text"); //selection1 is name of page
    if (txt.length > 0)
    {
    tbfunction_pgTimer("", "", "selection1", true);
    sharedActions.obj.scrollTop = 0;
    /*
    let found = txt.indexOf("\n");
      while (found > -1)
      {
      txt = tbfunction_pgReplace("\n", " ", txt, true);  //replaces all \n with space THIS DOES NOT WORK AND FREEZES THE BROWSER WINDOW!
      }
    ***/
    let found = txt.indexOf("ˆ");
      while (found > -1)
      {
      txt = tbfunction_pgReplace("^", " ", txt, true);  //(unlikely to be required) replaces all ^ with space
      }
    txt = tbfunction_pgReplace("\t", " ", txt, true);  //replaces all tabs with spaces because tabs will be used as separators.
    found = txt.indexOf("  ");
      while (found > -1)  //gets rid of all double spaces.
      {
      txt = tbfunction_pgReplace("  ", " ", txt, true);
      found = txt.indexOf("  ");
      }
    found = txt.indexOf("\n\n");
      while (found > -1)  //gets rid of all empty lines.
      {
      txt = tbfunction_pgReplace("\n\n", "\n", txt, true);
      found = txt.indexOf("\n\n");
      }
    found = txt.indexOf("..."); //converts 3 periods (full stops) to a single character (ansi 133 - In Arial it looks exactly the same).
      while (found > -1)
      {
      txt = tbfunction_pgReplace("...", "…", txt, true);
      } 
    tbfunction_pgTBObjSet("myText", "text", txt);
    sharedActions.pasted = true; //This makes it impossible to alter the text in the textarea by restricting key down to arrows only.
    sharedActions.makePages();
    sharedActions.getSentences();
    tbfunction_pgTBObjSet("myText", "blur", true);
    tbfunction_pgTBObjSet("shield", "visible", true);
    }
  ]]>
  </function> 
  </selection1>
so it may well be that I am creating the error myself. As you can see, I tried unsucessfully to convert crlfs to spaces. If I could do this sucessfully, I would be quite happy to settle for that. After the pasting and the functions shown above the text becomes:
Code: Select all
The reading and writing classes however, were a great success. By the autumn almost every animal on the farm was literate in some degree.
As for the pigs, they could already read and write perfectly. The dogs learned to read fairly well, but were not interested in reading anything except the Seven Commandments. Muriel, the goat, could read somewhat better than the dogs, and sometimes used to read to the others in the evenings from scraps of newspaper which she found on the rubbish heap. Benjamin could read as well as any pig, but never exercised his faculty. So far as he knew, he said, there was nothing worth reading. Clover learnt the whole alphabet, but could not put words together. Boxer could not get beyond the letter D. He would trace out A, B, C, D, in the dust with his great hoof, and then would stand staring at the letters with his ears back, sometimes shaking his forelock, trying with all his might to remember what came next and never succeeding. On several occasions, indeed, he did learn E, F, G, H, but by the time he knew them, it was always discovered that he had forgotten A, B, C, and D. Finally he decided to be content with the first four letters, and used to write them out once or twice every day to refresh his memory. Mollie refused to learn any but the six letters which spelt her own name. She would form these very neatly out of pieces of twig, and would then decorate them with a flower or two and walk round them admiring them.

John

PS I tried setting the new setAddedContent parameter to true and false but it did not seem to change anything.
John Robin Dove
 
Posts: 538
Joined: Thu Jan 23, 2014 4:35 am

Re: Projects new and old

Postby Clifton » Fri Jul 05, 2024 8:10 am

Can you post the before and after innerHTML of the contentEditable field you are manipulating?
Clifton
Site Admin
 
Posts: 781
Joined: Tue Jan 14, 2014 1:04 am

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 4 guests

cron