Horen
Horen

Reputation: 11382

Contenteditable / jQuery ampersand in href

I built a small WYSIWYG editor that runs in an iframe.
I insert links with jQuery and set its href like this:

$link.attr("href", url);

Later I get the source of the iframe and save it to a MySQL database.

My problem:
When I insert links with an ampersand e.g. http://www.example.org?foo=bar&bar=foo the browser converts it to http://www.example.org?foo=bar&bar=foo.
Then when I get the source the link contains the html entity & instead of the simple ampersand &.

Side note: I'm working with the links further on so I actually need the real link and cannot accept the html encoded ampersand.

Two questions:

  1. Is there any way to insert the link without having the browser convert it into html entities?
  2. If that is not possible and I have to replace those occurances later which other characters should I html_decode?

Upvotes: 2

Views: 321

Answers (1)

Barney
Barney

Reputation: 16456

This is valid behaviour within the HTML client — I would advise post processing if you need to get all links back to the server without HTML encoding. The best way to do this would be to use the same native DOM encoding to your advantage by getting each link's href, pasting into a DOM node as HTML, and reading it back out as text.

Before sending back to the server:

// The string you'll send back to the server
var iframeContentString;
// The contents of the iframe as HTML
var $iframeContents = $iframe.find( 'body' ).clone();
// A list of all hrefs
var anchorHrefs     = [];
// An empty node to use for HTML decoding using native methods
var $emptyNode      = $( 'x' );

// For each link, decode the href and store
$iframeContents.find( 'a' ).each( function storeDecodedHref( element ){
  // Assign the anchor's href to the empty node as HTML
  $emptyNode.html( element.href );

  // Store it as text
  anchorHrefs.push( $emptyNode.text() );

  // Replace the href with a string we can find with Regexp
  element.href = '@REPLACED@';
} );

// Store the href-free content as a string
iframeContentString = $iframeContents.html();

// Replace our Regexp flag with the saved link
iframeContentString.replace( /href="@REPLACED@"/g, function injectDecodedHref(){
  return anchorHrefs.unshift();
} );

This seems a bit over-engineered, but that's because I'm using the (jQuery wrapper for the) browser's own reliable DOM reading / encoding / decoding API — the same one that encoded the hrefs in the first place — and modifying the DOM contents for easy Regexp then, rather than going down the dangerous route of attempting to parse for the href attributes in Regexp (never attempt to parse HTML with Regexp!).

I wrote this on the fly without testing it, but hopefully the comments should help you read it as a guide and apply it to your specific situation.

Hope this works!

Upvotes: 2

Related Questions