Thursday, February 20, 2014

PerformancePoint JavaScript Issue with Non-IE Browsers (Firefox or Chrome)

PerformancePoint JavaScript Issue with Non-IE Browsers (Firefox or Chrome)


SharePoint 2010 PerformancePoint's JavaScript are using non-standard JavaScript method "Array.dequeue()". This will cause issues when using non-IE browsers such as Firefox or Chrome.

We saw this issue when developing custom web part using jQuery UI 1.10.4 and jQuery 1.9.1.

Part of the info from the Firefox debugger looks like

nodeQueue.dequeue is not a function

"__loadCompatLayer/DocumentFragment.prototype.getElementsByTagName
@http://xyz/ScriptResource.axd?d=BNrURcVUz0bJYWTaAYoTvEKuMaDhCruu9DTMN-iugGF_b6uVe3jZXu44p2ApuCPgncVvZ1Dlt3fSpssIXPaRuwY7igs1Tzy_PZn0nOzhilEgUr4mg1_ZRx_9vDzXqMHI4vDO67xxCCknvjpibnZTFcuhwEGgumoRQco7smihLrLSunihQWzMGhhRlIwSxj4hnopDBodp8MdmnUqvCt5p3cJXMF9h6sTFAMPApWSRYa06L_HQFPTCiWB-osM-nHLN0VsNXA2&t=ffffffffbc67a5f2:236getAll
@http://xyz/_layouts/mi.egr/js/jquery-1.9.1.js:6355.domManip
@http://xyz/_layouts/mi.egr/js/jquery-1.9.1.js:6138.append
@http://xyz/_layouts/mi.egr/js/jquery-1.9.1.js:5949jQuery.fn[name]
@http://xyz/_layouts/mi.egr/js/jquery-1.9.1.js:6342._createHandles
@http://xyz/_layouts/mi.egr/js/jquery-ui-1.10.4.custom.js:10469$.widget/</proxiedPrototype[prop]</<

The issues starts from using jQuery "append" or "appendTo" methods. When trying append a jQuery object with more than two html controls such as


$( "<a href='#1'></a><a href='#2'></a>") ).appendTo( this.element )
or
this.element .append($( "<a href='#1'></a><a href='#2'></a>"))


In jQuery 1.9.1 library, the method "domManip: function( args, table, callback )" is called and the following code executed
 
  if ( l ) {
   fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
   first = fragment.firstChild;
   if ( fragment.childNodes.length === 1 ) {
    fragment = first;
   }
   if ( first ) {
    table = table && jQuery.nodeName( first, "tr" );
    scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
    hasScripts = scripts.length;
 
function getAll( context, tag ) {
 var elems, elem,
  i = 0,
  found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
   typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
   undefined;
 if ( !found ) {
  for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
   if ( !tag || jQuery.nodeName( elem, tag ) ) {
    found.push( elem );
   } else {
    jQuery.merge( found, getAll( elem, tag ) );
   }
  }
 }
 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  jQuery.merge( [ context ], found ) :
  found;
}
 
When the appended ojbect is not a single HTML control, the "fragment" will be the root HTML document. When this happens, the PerformancePoint JavaScript loaded by "ScriptResource.axd" will excuted "__loadCompatLayer(w)" function which invoke the non-standard JavaScript funtion "dequeque".
 
 
To get around the issue, don't use "append" or "appendTo" to load multiple HTML control. Load one control at a time.
 
$( "<a href='#1'></a>") ).appendTo( this.element )
$( "<a href='#2'></a>") ).appendTo( this.element )