Expand range to url - javascript

Im trying to use ranges to check if the mouse is over an url, but I dont know how to tell the range that expand to get the full url, not just each word in it.
Here is an example to show the problem: jsFiddle
I will use this code in an editable iframe. If an user write an url, I want to give him the possibility to open it although it isn't an anchor element but plain text. Im not sure if can achieve that, but i want to try it.

One problem is that the expand() method of Range is non-standard and only supported in WebKit. Another is that document.caretRangeFromPoint() is also WebKit-only. Yet another is that there is no way of specifying a regular expression to match when identifying a word.
One option is the new TextRange module of my Rangy library, which works in all major browsers and provides a more flexible expand() method of ranges. There's also a work-in-progress position module that provides a cross-browser implementation of document.caretRangeFromPoint() (which is standardized as document.caretPositionFromPoint()).
Unfortunately, the position module is flaky in Firefox, but I intend to fix it soon. Also, the following demo doesn't work in IE at the moment, for reasons I think related to jsFiddle. So overall this is far from satisfactory, but may give you some ideas.
Live demo: http://jsfiddle.net/q3AtL/5/

Related

Javascript code working in Mozilla Firefox but not in Google Chrome

I'm facing a little issue with my javascript code. In fact it's working in Firefox but not in Chrome, do you have any idea why I'm facing this issue?
Here is my code:
$('a').each(function(){
if($(this).css('background-image')=='url("linktothepng.png")'){
$(this).parent().remove();
}
});
Thank you for helping me, have a good day ;)
chrome will get it as url(linktothepng.png) (no quotes)
browsers parse css and format it their own way, it is not advisable to do text matches on those properties, just use a class with that background and check with hasClass() to prevent the inconsistency
The value returned by css('background-image') can be normalised in different ways by different browsers; they're all valid as long as they are equivalent CSS.
You could test for css('background-image').indexOf('linktothepng.png') != -1 which would work, assuming there isn't another image in use that has linktothepng.png as part of its name (which would require a more complicated test).
If possible though, you'd be better off only ever setting that background image by setting a class.
Easier to change.
Separates the meaning you are ascribing to that image from the fact that the image is how you are representing it.
Quicker to find, instead of replacing the test to something like if($(this).hasClass('the-class-you-use') remove the test and change the selector to $('a.the-class-you-use').

Javascript IE6 getElementsByTagName not working

I've got this example page where I'm trying to put the wmode of every youtube element inside the page to "transparent".
To do it I need to get all the "object > params" and "embed" tags in the page.
The page I link you works like charm in all the browser except for IE6 (haven't cheked the other IEs yet).
With IE6 I can't catch the "params" since document.getElementsByTagName('param') returns an empty object, but this doesn't happen with the "embed"!
It won't work with document.getElementsByTagName('object') as well
Here is the page http://dl.dropbox.com/u/4064417/provaJs.html
Any suggestion why it's not returning just the "param" tags?
Thank you in advance!
I recall some issue with <param/> tags and getElementsByTagName, but it's ages that I don't code in IE6. Instead of querying from document, trying to get the params calling getElementsByTagName from the <object /> itself and see if it helps:
var objects = document.getElementsByTagName("object");
for (var i = 0, object; object = objects[i++];) {
var params = object.getElementsByTagName("param");
alert(params.length);
}
I understand that you would like to keep your app backwards compatible, but this exercise runs counter-intuitive to the general direction of the industry and its efforts to put IE6 down to rest (even google has dropped support for IE6). Your time might be better invested if you focus on building a better web experience for pseudo-modern browsers instead of worrying about the legacy ones.
Food for thought - maybe use a browser detection script and encourage your users to upgrade so that they can experience your site in all of its modern glory :)
All that being said, ZER0's suggestion is dead-on. Find the "object" tags in the page, and then iterate through its children until you find the tag you're looking for. If you can't seem to grab the object tags with getElementsByTagName, you may very well have to iterate through the document.body.childNodes nodelist, checking for the typeof(N) or N.NodeName along the way.
If you must support browsers as old IE6, I would strongly recommend using a library such as jQuery rather than trying to access the DOM directly.
IE6 has a massive number of bugs and quirks that can break even the simplest and most innocuous of Javascript code. jQuery goes to great lengths to abstract these browser bugs and deficiencies away from the developer, allowing you to write code that works on all browsers.
For example rather than using document.getElementsByTagName('object'), you can use the jQuery code $('object'), which will give you the same end result, but will work around any bugs in whichever browser your end user is running.
jQuery does a whole lot more than just hide the browser bugs, of course, but if you're working with IE6, that alone is a good enough reason to use it.
(other libraries are of course available if you really don't like jQuery for some reason)

Store & Restore Highlighted Selection

I am writing a Chrome Extention where I need to store and restore the user's highlighted selection. The stored information will be stored on my server. I am wondering how I would do this?
I looked into using Range, but am unsure if this is the right way since the example below only worked in FireFox.
I found this example but it only works in FireFox :(
I think the technique on that page probably does work in Chrome: there's no reason why it shouldn't. When I save the selection and reload, I see the selection restore and then quickly disappear, so I suspect something in the page (possibly the ads) is destroying the selection somehow.
If you can't get that to work, you could try the serializer module of my Rangy library, although it's probably overkill for just Chrome.
In general, using the browser's Selection and Range APIs is definitely the way to go. They are now standardized and universally supported (with some quirks and bugs, naturally) in current browsers.

Understanding Firefox' Autocompletion Popup

I build my own Richlist-Suggest-Popup for the URLBar along the lines of Mozilla.
When reading their Source I don't understand how they simply do a setAttribute('image', image) as a richlistitem actually doesn't support this attribute.
As far as I know the richlistitem DOM is supposed to look the following:
richlistitem.autocomplete-richlistitem
vbox
hbox
image.ac-site-icon
label
Generating this on my own almost works, but I'm kind of sure that this is the wrong way.
Could anyone explain either how Mozilla provides this feature or show me an example how one would achieve the behaviour?
I highly recommend DOM Inspector and Inspect Context. Using these, you can see that there are a number of different XBL bindings for those list items, and one of them must be the one that lets you add an image using an image attribute. I hope this helps!

Javascript Absolute vs. Relative URI using .execCommand('insertHTML', false, html);

I've been using a rteEditor very sucefully until now.
The problem is in this line of code:
document.getElementById(rteName).contentWindow.document.execCommand('insertHTML', false, html);
I'm passing an ABSOLUTE path to the html var such as ("http://www.url.com/file.html").
But when it execute this insert command the output is ("../file.html");
Its possible to use a jQuery command instead?
Any Suggestions?
Have you tried using 'insertImage' instead of 'insertHTML'?
Edit:
'insertImage' just takes the url of the image and creates an img tag based on that.
You can get the image after inserting it with jQuery like this:
var img = $("img[src='imgUrl']");
with 'imgUrl' being the url of the image you add, and then add the needed attributes to that.
An example without using jQuery is here at line 123.
In my experience, working with native rich text editors (aka div's with contentEditable="true" or iframes with designMode set to on) is very difficult. The API is inconsistent across browsers and their behavior is often unexpected and buggy. Because of this I tend to use document.execCommand() as little as possible. Instead I tend to reply on direct DOM manipulation.
With that in mind, here's how I'd try to solve the problem you described:
Create the an in-memory image element and set the appropriate url.
Find the DOM node that contains user's cursor.
Insert the in-memory image element into the DOM node found in the previous step.
The code needed to implement the second step is somewhat tricky and varies hugely across browsers. I'll try to post a working example in the next day or two. I hope this helps in the mean time.
As far as I understand, and have experienced it myself, this is 1. inherent to the browser's HTML editing engine and 2. it happens only when the image that you are trying to insert, and the address you are running the HTML editor from are on the same domain.
As a solution, if your server/provider allows this, you could set up a second subdomain that points to www, for example
www2.example.com
and link to the image as
http://www2.example.com
this should have the result that the absolute link remains untouched.
upon saving the HTML, you just have to replace all occurrences of www2.example.com to www.example.com.
Another, maybe simpler, way would be to run the WYSIWYG editor on www2.example.com and inserting the proper absolute URLs.
I think because of security reasons, you can not specify complete url such as www.example.com.
I believe that you should be able to use jQuery.
You will probably want to use something along the lines of
$(rteName).find('body').html('<img src="http://www.example.com/" alt="...">
but probably with some changes to the selector(s).

Categories