Can't get word on click - javascript

I have a script that get the word by getselection method when click, not by user selection, and then show an alert box with the word it's working well with some words, for example:
Si potrebbe comumente
It works with "potrebbe", but not with "Si".... It means, it works when the word is in the middle of the line, but not with the first or last word of the line...
This only happen when after apply the CheckKnowWords function, without apply this function, it works 100%.
The code is to big to post here, so, to prevent visual polution, I create this jsfiddle link: https://jsfiddle.net/fabiobraglin/ww7uLvd1/
ON FIREFOX
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
ON CHROME:
Uncaught InvalidStateError: Failed to execute 'surroundContents' on 'Range': The Range has partially selected a non-Text node.
When use:
range.surroundContents(newNode);

Firefox seems to have a number of issues with this code.
1) An error is thrown in some cases
According to the documentation on MDN for Range.surroundContents:
An exception will be thrown, however, if the Range splits a non-Text
node with only one of its boundary points.
It also suggests another method that will work regardless. Instead of
range.surroundContents(newNode);
you can use
newNode.appendChild(range.extractContents());
range.insertNode(newNode);
This will make it so that you will not get errors on beginning and ending words, like Si, or mondo.
2) The popup and title show the entire html
They should show the text instead (e.g. senza instead of <span style="border-radius: 4px;border: 1px solid #ffcccc; background: #ffcccc;">senza</span>). To fix this, you can replace innerHTML with innerText.
More issues
There are a few more issues I found, but this is where it gets tricky. MDN has a warning that Selection.modify is non-standard and doesn't have plans to become standard, so you will get weird behavior between browsers, such as:
In Firefox, punctuation is being included at the end of the word (e.g. forti, or IATA).). In Chrome, this doesn't happen. Also, words with punctuation in them seem to work fine in Chrome but not in Firefox (e.g. the word L'indice looks fine in Chrome but comes up as indice in Firefox).
In Firefox, clicking on a word that follows a recognized word will instead select the recognized word. For example, if you clikc on ognuno where it says viaggo che ognuno di, it will catch the word che, but this doesn't happen in Chrome.
The word Henley is unique in that it is in bold tags. In the phrase britannica Henley & Partners, if you click on either Henley or & in Chrome you will get britannica. In Firefox you will get Henley.
You might want to consider changing the technique for finding the word. For example, you're already going through and highlighting all words you're interested in by wrapping them in a span. Instead of using Range and Selection, you could use the click event to figure out which span you're in, then get the text within that. If your initial checking also excludes punctuation and "words" like &, then you could just select the entire inner text.
Another minor issue I noticed is the HTML uses an unescaped & instead of &. It probably isn't affecting this example, but in general you'll run into less problems if you properly escape HTML (I think it's mainly just <, > and &, but there's plenty of tools and documentation on that elsewhere).
Here's an updated fiddle solving the first two issues, but they may be obsolete if you end up doing some refactoring to solve the other issues.

updated the fiddle. https://jsfiddle.net/ww7uLvd1/8/ Always use split(/\s+/) while trying to split with space

Related

innerText auto truncating long text inside a DOM element

I am trying to access the content inside a td element through the JavaScript innerText property (inside an excel VBA macro). It works perfectly for all cases except for this one case where the text inside the td element is very long (greater than 85982 characters).
Upon inspection of the text extracted by innerText, I found that innerText seems to be truncating the text after a certain length. Note that this doesn't happen for other cases where the text size is small.
Also, it seems that Mozilla's textContent property has a similar problem as well. I tried accessing the truncated part of the text using the developer console in Firefox for the aforementioned DOM element, but it seems that text isn't there in the extracted content (but the not truncated text is there - just like with innerText).
Does anyone know how to bypass this restriction? Is there some internal limit on these functions?
Here's my VBA code that has this problem:
MyInnerText = objElement.ChildNodes(3).innerText
Here's an equivalent code run in the Firefox console which has the same problem:
var t = document.getElementsByName("chapter11")[0].parentNode.children[3].textContent;
t.match("some text that is in the part being truncated.");
For Firefox, this problem seems to go away if I inspect the element, and click "Show all 3396" nodes. After those nodes are visible, the textContent does not truncate the text anymore.
Please do note that I want to be able to extract the text from inside a VBA script using the Internet Explorer object.
It turns out that the problem was caused due to an integer overflow. The index for the string I was looking for was larger than the capacity of the type Integer in VBA, so VBA silently set it to zero.
As for the reason behind why I wasn't able to find the text inside FireFox, that is still a mystery.

Strange json.stringify fail

Strange is not the error itself but the way it happens. In my content editor while editing everything gets saved with unique id's in a javascript object and after you save in the end it gets json stringified. That work's for 99,99% of my users perfect but sometimes json.stringify didn't escape the quotes and its always happens with the same beginning. I really don't have a clue how this happens. Here is a picture of the javascript object:
http://cl.ly/image/3B3Z2e413M3r
Off course the marked line is the error but the whole thing (no escaped quotes) only occures if the content starts with this line. I should mention if you load a wysiwyg element in the editor there is a pre equipped < h3 >...< /h3 > and a < p >...< /p > with some sample data. (the h3 is not centered per default)
<h3 style="text-align: center;">Sample Headline</h3>
My problem is that i can't reproduce it. If i align my heading to get the same code, everything works well. Users got the last chrome version and there is no other plugin then jQuery.
Any ideas would be great because iam exhausted...
Cliffnotes:
json.stringify failes to escape quotes and....
everytime the error occurs to a user i see that it starts with the aligned heading so i guess it has something to do with it
Thanks a lot. :)
What you have shown is a normal JS object and not a JSON (so it has nothing to do with JSON.stringify()). The quotes must be only escaped in string literals in code, so that interpreter did not confuse it with delimiting quotes.
After it's parsed - they are stored in memory as-is without any escape characters.
Example: http://jsfiddle.net/83GUe/
Guide: open developer tools, press Run and see the Scope variables
Conclusion: what you provided on a screenshot is a 100% expected and correct behaviour.

textarea attribute wrap=hard does not work on pasted text, any workarounds?

I have a textarea
<textarea id="id-textarea-readme" wrap="hard"></textarea>
which works realy fine, until someone writes his text in "notepad" and puts it in there via c&p , the words are wrapped correctly but no "extra" linebreaks are made (which is kind of the purpose of "hard")
Is there any workaround to make this work? any JS or a trick to trigger the linebreaks?
The wrap=hard attribute is nonstandard and does not work consistently across browsers. Modify the design so that you do not need to rely on such client-side operations. Textarea elements should be expected to yield actual user input, containing line breaks when user actually hit Enter. If you need to split long lines for further processing, do it server-side.
In my tests, IE wraps even in copy and paste. Firefox, on the other hand, introduces hard line breaks only when it wraps at whitespace but not when it wraps inside a “word”, so that for cols=5, the input 0123456789 (whether direct or copypaste) gets displayed as two lines but sent as one line, whereas 01234 56789 gets sent as two lines. I would expect to find other browsers incompatibilities as well.
the copy & paste issue probably comes from native OS linebreak/return/newline issues.
you could just listen for change or paste on the textarea DOM element and parse with javascript? that'd be my conceptual guess, here's a generic example in jquery:
$("textarea").on("change", function(event){
$this.replace(/\n\r?/g, '\n');
});

How can I replace newline characters using javascript in IE8?

I've searched Stackoverflow for hours and hours, and nobody's solution works in Internet Explorer 8.
I am provided with a plaintext document like this:
This is a legal agreement ("Agreement") between you and ...
License
Subject to you continued and ongoing compliance with the terms and conditions set ...
Restrictions
Except as otherwise explicitly provided in this Agreement, ...
Ownership
Except for this license granted to you, as between you and ...
Disclaimer of Warranties
Use at your own risk. ...
And I need to replace the newline characters (linebreaks, carriage returns, whatever you want to call them) with double linebreaks (<br/><br/>) to make the text look more normal.
The nl2br function from jQuery convert line breaks to br (nl2br equivalent) works fine in most browsers. However, a client of mine uses IE8.
Go ahead and try the nl2br function using IE8 (or a modern Internet Explorer set to IE8 mode); it doesn't work.
Does anyone know why it doesn't work in IE8? And how to accomplish the goal?
P.S. I put some code here http://jsfiddle.net/L2Ufj/2/ and oddly enough it works in IE8 via jsfiddle, but if you copy it to somewhere else and run it for real, it won't work in IE8.
One way to get round this in IE8 is to convert the line-breaks into a 'token' that IE8 will recognise before it is rendered on the page. Then once it's rendered, in a success handler for example you can search for that token and replace with <br> or whatever you wish:
e.g.
Pre render (I've used < br > as my token but you can use anything)
textToEdit = textToEdit.replace(/\n/g, '<br>');
Post render (Search for your token and replace with <br> or whatever you wish)
renderedTextWrapper.innerHTML = renderedTextWrapper.innerHTML.replace(/<br>/g, '<br>');
When you retrieve element's innerHTML, IE will convert the innerHTML to a "standard-format" (by collapsing multi-spaces into one, removing linebreak, etc...) before giving you the result.
Thus, you can not find any linebreak character in the innerHTML you get with IE. What a bad news.
I think the most feasible & easy approach is to store your text inside <textarea> tag instead of normal <div>. IE will leave <textarea> alone when you get it's value instead of innerHTML:
originalText=document.getElementById('EULA_content').value
Of course, when you get the newText, you should append it to another div element.

Chrome rendering an alert() box with the last 2 words on 2 separate lines. How to fix?

I have the following JS that produces an alert box:
alert("You have selected the maximum number of funds available for comparison. Please ensure only five funds have been selected for your basket");
Chrome is rendering the alert box like this:
with the last 2 words wrapping onto separate lines.
Has anyone seen this before? Any ideas how to fix this?!
Wanted to add another screenshot since I am able to reproduce this error:
--Jeremy
This seems to be a bug with older verisons of Chrome.
http://code.google.com/p/chromium/issues/detail?id=83670
In Chrome 12 on linux it works fine, so I can't easily reproduce/debug. Have you tried putting in your own line breaks, say after every 70 characters like:
alert("You have selected the maximum number of funds \n"+
"available for comparison. Please ensure only five \n"+
"funds have been selected for your basket.");
I understand hard-coding linebreaks is a bad idea in general (in some cases they will be poor choices) or if the text ever changes the line breaks will have to be adjusted by you.
As a programmer/developer you can't fully account for chrome not working properly. Except maybe avoiding alert box entirely, and sending the error message another way (e.g., ajax or a custom alert from say jquery).
#DaveDev, here is the image you requested. I think it looks good enough.
The code is from #dr jimbob's answer.
I recommend to you that you, as a programmer, controll the length of each string. You can cut the line, by yourself, with a '\n' character, and control every line for yourself.
I suspect there is a line end in your document, because testing it in my Chrome (12, windows 7), the alert displays like it should. Are you using HTMLTidy or some HTML formatter?
[edit] Okay, seems to be a genuine Chrome issue. Here some related issues #code.google.com for Chrome
Lengthy alerts have weird line break in them
Long text messages get truncated on the Javascript Alert box
javascript alert popup truncates strings every 132 chars
The solution I have stumbled upon is to add +"\ " (backslash space) at the end of the string. Each of my text lines ends with a \n in any case, so effectively my string now ends with "\n\ "Then it seems I can use as many \n's that I want. Don't ask me why it works. Perhaps it will work for you? Just call me persistent!

Categories