RTL text in Facebook posts re-orders words - javascript

I am from Tunisia, and am currently developing a PHP script called PHPFOX. In it, I want to integrate an ability to change the text-direction of a TextBox automatically. Specifically, when you go to Facebook and want to leave a comment, the TextBox's input direction will change based on what your chosen keyboard direction is.
In other words, if you have chosen the Arabic language for your keyboard, the TextBox automatically gets set to RTL direction.
Here is the code I'm using so far:
$('input').keyup(function() {
$this = $(this);
if ($this.val().length == 1) {
var x = new RegExp("[\x00-\x80]+"); // ASCII
//alert(x.test($this.val()));
var isAscii = x.test($this.val());
if(isAscii) {
$this.css("direction", "ltr");
} else {
$this.css("direction", "rtl");
}
}
});
Everything works fine for input. However, look what happens when I input a mixed LTR and RTL sentence in my site, then post it to Facebook:
Here is what I enter:
Here is what appears on Facebook:
See the difference? How do I solve this?

First off - the approach you're taking is brilliant, and I applaud you for it. Switching the direction of <input> via CSS to allow natural typing makes a huge amount of sense.
The reason your OUTPUT is coming out strangely, though, is due to the generated content which you are sending to Facebook. My guess is that since the last few characters of your text are in RTL, your input's CSS is still set to RTL.
Consider this example (result can bee seen here):
<div>
<b>LTR:</b> <span dir="ltr">This is some الفبای فارسی text</span>
<br /><br />
<b>RTL:</b> <span dir="rtl">This is some الفبای فارسی text</span>
</div>
Because the second <span> is displayed with dir="rtl", the text winds up getting re-ordered, with each LTR phrase treated as a single RTL "word".
What you might consider trying, in your example, is simply making sure that prior to submitting the post, you set your CSS direction back to LTR, which will produce the result I think you're looking for.
If you are interested, here is a blog post discussing the difference between HTML and Plain-Text style rendering of LTR and RTL text. It doesn't provide you any answers, but will point out more details about the problem itself.

Related

re announce a <p> under aria-live even if the text is same

I am implementing a search box. One of the scenarios is that the total count of results must be announced. To achieve this I put the <p> tag inside of an aria-live region, and it announces it as expected.
Expected scenario:
User types a string --> hits enter --> results appear and string is announced.
The edge case is if the user hits enter twice.
If the user presses enter again without any changes, nothing is updated since the count is still the same and nothing is announced.
I tried using this on enter click:
if (document.getElementById("header")) {
const currentText: string = document.getElementById("header").innerHTML;
document.getElementById("search-header").innerHTML = "";
document.getElementById("search-header").innerHTML = currentText;
}
But, it still did not announce.
Is there another way to accomplish this?
I ran into a similar situation recently. You've already implemented half of the solution (resetting the innerHTML to an empty string, then setting it to the currentText). The other half of the solution is to set the aria-relevant attribute to all.
By default the aria-relevant attribute is set to additions text, but that leaves out the removed option. Since you need the screen reader to pickup the change to an empty string (when you remove the text), you need to set the attribute to all (which is the same as additions text removed).
As a best practice the aria-relevant attribute should normally be left alone, but I haven't found another way to get the screen reader to make the same announcement twice.
In your case I would also add the aria-live property directly to the element with an id="search-header". It should look something like this:
<h6 id="search-header" aria-live="polite" role="status" aria-relevant="all">
X items found
</h6>
You can read more about the aria-relevant attribute here.
And, there's more information about aria-live regions here.
I faced the same issue. I modified the string with the addition of period, in the end, if the same string is added again to the aira-live div.
I compared the new text value with the existing one in tag, if the value is same then I added period (.) to the incoming string.
if (msg == $(".aria-live-div").text()){
msg = msg + "."
}

Using a Chrome extension to replace characters spanning more than one line in a Facebook status update

I have created a Google Chrome extension to allow users to select text in a component. This works great for most sites. However, Facebook handles its status updates differently. It seems that even though you are filling in what seems to be a single text box, it is actually using a div > div > span > span construct for every single line in this text box. I have no idea why they chose to do this but it makes replacing multiple lines of text much more complex.
Is there a way to select multiple lines (or even contiguous portions of multiple lines) of text in a Facebook status update and replace the data?
The relevant portion of my code looks like this:
function replace_text(language){
let selection = window.getSelection();
string = selection.toString();
/* This section contains code that uses string.replace to replace characters in the string. */
document.execCommand("insertText", false, string);
}
Based on the way my code works now, if I replace text on a single line I have no problems. But, if I replace text that spans multiple lines I end up with a blank unusable input box. Undoubtedly it is because it is removing portions of the html code. How can I fix my code so that the replacement process works properly not only for other sites but also for Facebook?
As of this moment, the one common theme among all status updates (and comments) are that their texts reside within a single or set of span elements with the attribute data-text set to true. So let's target those:
document.querySelectorAll("span[data-text='true']");
For me, I've typed into the status field 3 lines and comment field 1 line of dummy text. So when I execute the above code into the console it returns an array of those four cumulative lines:
>>> (4) [span, span, span, span]
With that array, I can use the Array.prototype.forEach() method to iterate through the spans and replace the innerText:
document.querySelectorAll("span[data-text='true']").forEach(function(element) {
element.innerText = element.innerText.replace('Lorem ipsum','Hello world');
});
However, it is important to note that these changes are being made in the HTML itself and Facebook doesn't store all of its data directly in the HTML. Therefore it can cause undesirable events to occur when you type text into a field, unfocus, change the text in the field, and refocus that field. When you refocus I believe it grabs data of what the text was, before you unfocused that field, from an ulterior source like React's Virtual DOM. To deter it from doing that, the changes either need to be made after clicking the field (real or simulate) or as the user is typing using some sort of MutationObserver (src).

Autofill Text box on a Web Page (Javascript/VBScript)

I really need to know how I can autofill text boxes on a web page.
What I really want to achieve is the following:
1) Go to http://show.websudoku.com
2) Replace all the empty cells with a 0 (zero).
Is that possible?
To fill the empty spaces of the Sudoku grid at http://show.websudoku.com with zero's, here is some JavaScript to do that. It is formatted for use as a "Bookmarklet":
javascript:(function(){var x,k,f,j,r;x=document.forms;for(k=0;k<x.length;++k){f=x[k];for(j=0;j<f.length;++j){r=(f[j].className.toLowerCase()+f[j].type.toLowerCase()+f[j].value);if(r=="d0text"){f[j].value="0";}else if(r=="d0text0"){f[j].value="";}}}})();
The setup:
Create a new Bookmark/Favorite. For now, the URL for the favorite can be anything. An easy way to do this is to drag ANY link/url from the browser address bar, or any web-page link, to the "Favorites Bar" or to the Bookmarks/Favorites sidebar.
Select the new favorite, and rename it to any name you like.
Copy the JavaScript code from above to the clipboard. It must remain as 1 continuous single line, and it must begin with "javascript:(" and end with ")();"
Edit the properties of the new favorite.
Remove the "URL" that is currently in the favorite and replace it by pasting in the JavaScript code from above, into the "URL" text field for the favorite, then save the changes.
To use the bookmarklet:
From the browser, navigate to http://show.websudoku.com as you normally would.
Click the new favorite (Bookmarklet) that you just edited.
All empty spaces in the Sudoku grid will be filled with 0's. Click the new favorite (Bookmarklet) again, and the 0's will be removed leaving empty spaces once again.
Here is what the Javascript code looks like expanded, with indents:
javascript:(function(){
var x,k,f,j,r;
x=document.forms;
for(k=0;k<x.length;++k){
f=x[k];
for(j=0;j<f.length;++j){
r=(f[j].className.toLowerCase()+f[j].type.toLowerCase()+f[j].value);
if(r=="d0text"){
f[j].value="0";
}
else if(r=="d0text0"){
f[j].value="";
}
}
}
}
)();
* Spoiler alert *
In case you want to "cheat", the JavaScript here will "solve" the Sudoku:
javascript:(function(){var x,k,f,j,ecl,etl,en,ev,s,e,c,d,dl,dr,n;x=document.forms;for(k=0;k<x.length;++k){f=x[k];for(j=0;j<f.length;++j){e=f[j];r=(e.name.toLowerCase());if(r=="cheat"){c=e.value;break;}}for(j=0;j<f.length;++j){e=f[j];ecl=e.className.toLowerCase();etl=e.type.toLowerCase();en=e.name;ev=e.value;if(etl=="text"){if(ecl=="d0"){dr=en.substr(en.length-1,1);dl=en.substr(en.length-2,1);d=(((Number(dr)-1)*9)+Number(dl))-1;n=c.substr(d,1);if(ev.length==0){e.value=n;}else{e.value="";}}}}}})();
Setup and use is the same as described above.
While it's not much fun to solve it like that (OK, maybe it's a little fun the first couple times), and definitely not challenging, if you are in a real-real-real hurry, you can solve it in 1 click.
Note: I have only tested these 2 bookmarklets with IE9.

How to display underline in javascript string?

I have the following javascript code:
var result = ("Please enter your name","Andrew");
and i wanted to underline the word "name" in the above message.
This is trivial but i have no clue after searching for escape code representation for underline. Or is the above possible in javascript ?
If the example code given had a typo and should've read like this:
var result = window.prompt("Please enter your name","Andrew");
then the answer is that you can't format the text or change the labels on the buttons or anything. This applies to the built-in alert() and confirm() as well as to prompt().
It's a bit more work, but you can implement your own equivalent dialog by building one from HTML using a transparent <div> to cover the rest of your page so that users can't interact with the rest of the page until the dialog closes. (Or use a translucent <div> to make it more obvious to the user that the rest of the page is "disabled".)
I would not bother coding this from scratch when there are lots of JS libraries that do it for you. The jQuery dialog is pretty easy to use, to name just one option.
If this is ending up on a web page you should just be able to use:
var result = ("Please enter your <u>name</u>","Andrew");
...but I'm not exactly sure what it is you're intending to do. Can you add more detail to your question?
var result = ("Please enter your <u>name</u>","Andrew");

Title Attribute on Disabled Elements in Firefox

I am building a very dynamic web-based application using a lot of Javascript to handle user events. I am in the process of making things a little more usable and came across a problem that I've never had before.
I am using jQuery, so factor that in to your answers. Thanks in advance.
I have a set of button elements defined as:
<input type="button" title="My 'useful' text here." disabled="disabled" />
I have these buttons with a default style of:
div#option_buttons input {
cursor: help;
}
Then, using jQuery I run something like this as a click-event on a select box:
window.current_column = '';
$('select.report_option_columns').live('click', function() {
var column = $(this).val();
if ( column == window.current_column ) {
// clear our our previous selections
window.current_column = '';
// make this option no longer selected
$(this).val('');
$('div#option_buttons input').attr('disabled','disabled');
$('div#option_buttons input').attr(
'title',
'You must select a column from this list.'
);
$('div#option_buttons input').css('cursor', 'help');
} else {
window.current_column = column;
$('div#option_buttons input').attr('disabled','');
$('div#option_buttons input').attr(
'title',
'Add this option for the column "' + column + '"'
);
$('div#option_buttons input').css('cursor', 'default');
}
});
So, as you can see, when a column is selected in the select box (not shown here), I want the button to be enabled and behave like a button would (with my own click-events). But when a column is not selected (including the default load), I want the button disabled. The usability developer in me wanted to give the users subtle contextual clues as to what they can do to enable the button through the native rendering of the title attribute as a lightweight tooltip. I do this already in other areas of the application (this is a crazy beast of a project) and our usability tests have shown that the users are at least capable of recognizing that when the cursor changes to "help" that they can hover over the element and get some information about what is going on.
But this is the first time I've ever tried this with a form element. Apparently when I put disabled="disabled" in the element, it completely ignores the title attribute and will never display the tool tip.
Now, I know I have a few options (at least the ones I could think of):
Write my own custom tool tip plug-in that is a little bit more robust.
Don't "disable" the element, but style it as disabled. This was the option I was leaning on the most (in terms of ease to develop) but I hate having to do this.
Leave the button as enabled but don't process the click event. I don't like this option as much because I like to leave things natively styled as they should logically be. A disabled button "feels" the most correct and the look of a disabled button is instantly recognizable as a disabled button.
So, with all that said, am I missing something? Is there something easy that I can do that I just haven't thought of? Google searches have failed me on this topic, so I thought I'd toss this out on StackOverflow to get some fresh eyes on this.
**Edit**
I just found another StackOverflow question on this same topic, though that person used a very different set of terms describing his problem (probably why I didn't find it).
The url to the question is: Firefox does not show tooltips on disabled input fields
Both of the answers on that question are pretty good, though I'd like to see if anyone has any other suggestions. Maybe something more jQuery specific? Thanks again.
I had a similar problem and I just surrounded the disabled element in another element and interacted with that div, i was using tipTip to show tooltip for disabled checkbox
<div style="cursor: pointer;" class="disabled" title="Do something to make it work" >
<input disabled="disabled" type="checkbox">
</div>
There are several validation plugins that are very robust. You can find them in the jQuery plugins area.
Another option for you though which I happen to love and tends to be trending now adays is using the "Tipsy" plugin. You can put little '?' icons to the right of your text fields and people can mouse over them to get a "facebook-like" tool tip. This plugin is very sharp and I highly recommend it.
Good luck!
I haven't tested whether or not that solves the problem with the missing title, but you could also disable the button(s) using jquery on $(document).ready()
regards,
harpax
If that doesn't break your design totally, you can replace your button by a "span", "p",... tag with "My 'useful' text here."
And swap it with the button only when the user makes the correct move.

Categories