Skip to main content

Bug Tracker

Side navigation

#930 closed bug (fixed)

Opened February 08, 2007 02:22PM UTC

Closed September 15, 2007 01:31PM UTC

jQuery/Packer/ActiveX Activation

Reported by: anonymous Owned by:
Priority: minor Milestone: 1.2.1
Component: core Version: 1.2
Keywords: clean flash activex packer Cc:
Blocked by: Blocking:
Description

Background

Inserting an ActiveX control (i.e. flash movie, quicktime movie) with an external javascript (i.e. jQuery) should avoid the ugly grey box and having to click to activate.

Bug

ActiveX controls inserted using the packed version of jQuery have the grey box and must be activated. See: jQuery/Packer/ActiveX Bug for more info.

Solution

I've narrowed the problem down to the jQuery.clean method, which uses a temporary div's innerHTML to convert html strings into DOM elements. Doing the conversion from unpacked code fixes the problem, so I'd like to suggest adding a

convert
hook inside jQuery.clean (see below for patch).

Without the hook, the entire

jQuery.clean
method has to be overwritten. With the hook, the bug could then be fixed by overwriting jQuery.clean.convert from outside of the packed code (i.e. via a plugin, or by copying and pasting
 jQuery.clean.convert = function(html) {...} 
at the bottom of jquery-latest.packed.js).


clean: function(a) {
	var r = [];
	
+	if(!jQuery.clean.convert)
+		jQuery.clean.convert = function(html) {
+			var n = document.createElement('div');
+			div.innerHTML = html;
+			return n;
+		};

	jQuery.each( a, function(i,arg){
		if ( !arg ) return;

		if ( arg.constructor == Number )
			arg = arg.toString();
		
		 // Convert html string into DOM nodes
		if ( typeof arg == "string" ) {
			// Trim whitespace, otherwise indexOf won't work as expected
-			var s = jQuery.trim(arg), div = document.createElement("div"), tb = [];
+			var s = jQuery.trim(arg), div, tb = [];

			var wrap =
				 // option or optgroup
				!s.indexOf("<opt") &&
				[1, "<select>", "</select>"] ||
				
				(!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) &&
				[1, "<table>", "</table>"] ||
				
				!s.indexOf("<tr") &&
				[2, "<table><tbody>", "</tbody></table>"] ||
				
			 	// <thead> matched above
				(!s.indexOf("<td") || !s.indexOf("<th")) &&
				[3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
				
				[0,"",""];

			// Go to html and back, then peel off extra wrappers
-			div.innerHTML = wrap[1] + s + wrap[2];
+			div = jQuery.clean.convert(wrap[1] + s + wrap[2]);
			
			// Move to the right depth
			while ( wrap[0]-- )
				div = div.firstChild;
			
			// Remove IE's autoinserted <tbody> from table fragments
			if ( jQuery.browser.msie ) {
				
				// String was a <table>, *may* have spurious <tbody>
				if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) 
					tb = div.firstChild && div.firstChild.childNodes;
					
				// String was a bare <thead> or <tfoot>
				else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
					tb = div.childNodes;

				for ( var n = tb.length-1; n >= 0 ; --n )
					if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
						tb[n].parentNode.removeChild(tb[n]);
				
			}
			
			arg = div.childNodes;
		}

		if ( arg.length === 0 )
			return;
		
		if ( arg[0] == undefined )
			r.push( arg );
		else
			r = jQuery.merge( r, arg );

	});

	return r;
},

Attachments (0)
Change History (5)

Changed February 08, 2007 09:09PM UTC by john comment:1

I think you meant to do:

n.innerHTML = html;

instead of:

div.innerHTML = html;

Changed February 11, 2007 01:16PM UTC by anonymous comment:2

Yes, you're right John :-)

Changed April 11, 2007 04:35PM UTC by tamlyn comment:3

Are there plans to integrate this bug fix into the core? It seems it would only use a very few bytes and would have the benefit of allowing the highly useful flash plugin to run on jquery unpatched.

Changed July 25, 2007 09:37PM UTC by pixeline comment:4

I would like to know if this bug will be solved any time soon, as the jqUploader plugin relies on the nice jquery.flash.js plugin. It would be great, as stated above, not to have to patch jquery core in order for this to run.

thanks !

Changed September 15, 2007 01:31PM UTC by john comment:5

description: == Background ==\ Inserting an ActiveX control (i.e. flash movie, quicktime movie) with an external javascript (i.e. jQuery) '''should''' avoid the ugly grey box and having to [http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp click to activate].\ \ == Bug ==\ ActiveX controls inserted using the packed version of jQuery have the grey box and must be activated. See: [http://jquery.lukelutman.com/plugins/flash/activex/ jQuery/Packer/ActiveX Bug] for more info.\ \ == Solution ==\ I've narrowed the problem down to the jQuery.clean method, which uses a temporary div's innerHTML to convert html strings into DOM elements. Doing the conversion from unpacked code fixes the problem, so I'd like to suggest adding a {{{convert}}} hook inside jQuery.clean (see below for patch).\ \ Without the hook, the entire {{{jQuery.clean}}} method has to be overwritten. With the hook, the bug could then be fixed by overwriting jQuery.clean.convert from outside of the packed code (i.e. via a plugin, or by copying and pasting {{{ jQuery.clean.convert = function(html) {...} }}} at the bottom of jquery-latest.packed.js).\ \ \ \ \ {{{\ \ clean: function(a) {\ var r = [];\ \ + if(!jQuery.clean.convert)\ + jQuery.clean.convert = function(html) {\ + var n = document.createElement('div');\ + div.innerHTML = html;\ + return n;\ + };\ \ jQuery.each( a, function(i,arg){\ if ( !arg ) return;\ \ if ( arg.constructor == Number )\ arg = arg.toString();\ \ // Convert html string into DOM nodes\ if ( typeof arg == "string" ) {\ // Trim whitespace, otherwise indexOf won't work as expected\ - var s = jQuery.trim(arg), div = document.createElement("div"), tb = [];\ + var s = jQuery.trim(arg), div, tb = [];\ \ var wrap =\ // option or optgroup\ !s.indexOf("<opt") &&\ [1, "<select>", "</select>"] ||\ \ (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) &&\ [1, "<table>", "</table>"] ||\ \ !s.indexOf("<tr") &&\ [2, "<table><tbody>", "</tbody></table>"] ||\ \ // <thead> matched above\ (!s.indexOf("<td") || !s.indexOf("<th")) &&\ [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||\ \ [0,"",""];\ \ // Go to html and back, then peel off extra wrappers\ - div.innerHTML = wrap[1] + s + wrap[2];\ + div = jQuery.clean.convert(wrap[1] + s + wrap[2]);\ \ // Move to the right depth\ while ( wrap[0]-- )\ div = div.firstChild;\ \ // Remove IE's autoinserted <tbody> from table fragments\ if ( jQuery.browser.msie ) {\ \ // String was a <table>, *may* have spurious <tbody>\ if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) \ tb = div.firstChild && div.firstChild.childNodes;\ \ // String was a bare <thead> or <tfoot>\ else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )\ tb = div.childNodes;\ \ for ( var n = tb.length-1; n >= 0 ; --n )\ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )\ tb[n].parentNode.removeChild(tb[n]);\ \ }\ \ arg = div.childNodes;\ }\ \ if ( arg.length === 0 )\ return;\ \ if ( arg[0] == undefined )\ r.push( arg );\ else\ r = jQuery.merge( r, arg );\ \ });\ \ return r;\ },\ \ }}}== Background == \ Inserting an ActiveX control (i.e. flash movie, quicktime movie) with an external javascript (i.e. jQuery) '''should''' avoid the ugly grey box and having to [http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp click to activate]. \ \ == Bug == \ ActiveX controls inserted using the packed version of jQuery have the grey box and must be activated. See: [http://jquery.lukelutman.com/plugins/flash/activex/ jQuery/Packer/ActiveX Bug] for more info. \ \ == Solution == \ I've narrowed the problem down to the jQuery.clean method, which uses a temporary div's innerHTML to convert html strings into DOM elements. Doing the conversion from unpacked code fixes the problem, so I'd like to suggest adding a {{{convert}}} hook inside jQuery.clean (see below for patch). \ \ Without the hook, the entire {{{jQuery.clean}}} method has to be overwritten. With the hook, the bug could then be fixed by overwriting jQuery.clean.convert from outside of the packed code (i.e. via a plugin, or by copying and pasting {{{ jQuery.clean.convert = function(html) {...} }}} at the bottom of jquery-latest.packed.js). \ \ \ \ \ {{{ \ \ clean: function(a) { \ var r = []; \ \ + if(!jQuery.clean.convert) \ + jQuery.clean.convert = function(html) { \ + var n = document.createElement('div'); \ + div.innerHTML = html; \ + return n; \ + }; \ \ jQuery.each( a, function(i,arg){ \ if ( !arg ) return; \ \ if ( arg.constructor == Number ) \ arg = arg.toString(); \ \ // Convert html string into DOM nodes \ if ( typeof arg == "string" ) { \ // Trim whitespace, otherwise indexOf won't work as expected \ - var s = jQuery.trim(arg), div = document.createElement("div"), tb = []; \ + var s = jQuery.trim(arg), div, tb = []; \ \ var wrap = \ // option or optgroup \ !s.indexOf("<opt") && \ [1, "<select>", "</select>"] || \ \ (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) && \ [1, "<table>", "</table>"] || \ \ !s.indexOf("<tr") && \ [2, "<table><tbody>", "</tbody></table>"] || \ \ // <thead> matched above \ (!s.indexOf("<td") || !s.indexOf("<th")) && \ [3, "<table><tbody><tr>", "</tr></tbody></table>"] || \ \ [0,"",""]; \ \ // Go to html and back, then peel off extra wrappers \ - div.innerHTML = wrap[1] + s + wrap[2]; \ + div = jQuery.clean.convert(wrap[1] + s + wrap[2]); \ \ // Move to the right depth \ while ( wrap[0]-- ) \ div = div.firstChild; \ \ // Remove IE's autoinserted <tbody> from table fragments \ if ( jQuery.browser.msie ) { \ \ // String was a <table>, *may* have spurious <tbody> \ if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) \ tb = div.firstChild && div.firstChild.childNodes; \ \ // String was a bare <thead> or <tfoot> \ else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 ) \ tb = div.childNodes; \ \ for ( var n = tb.length-1; n >= 0 ; --n ) \ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length ) \ tb[n].parentNode.removeChild(tb[n]); \ \ } \ \ arg = div.childNodes; \ } \ \ if ( arg.length === 0 ) \ return; \ \ if ( arg[0] == undefined ) \ r.push( arg ); \ else \ r = jQuery.merge( r, arg ); \ \ }); \ \ return r; \ }, \ \ }}}
milestone: → 1.2.1
need: → Review
resolution: → fixed
status: newclosed
version: → 1.2

We now provide a minified version of jQuery - you should recommend that your users use that instead (if you want to avoid activation.)