|
function getXMLDOMObject() {
// ref. http://d.hatena.ne.jp/defint/20080802/1217646509
var aryDOMProgIDs = [
"MSXML2.DOMDocument.4.0",
"MSXML2.DOMDocument.3.0",
"MSXML2.DOMDocument",
"MSXML.DOMDocument",
"Microsoft.XmlDom"];
var objDOM = null;
for (var i=0; i<aryDOMProgIDs.length; i++) {
try {
objDOM = new ActiveXObject(aryDOMProgIDs[i]);
break;
} catch (objException) {
// エラー処理は不要
}
}
return objDOM;
}
var ActionSupport = (function() {
var _isJQueryOk = true;
var _isXmlDom = true;
var _isActiveX = true;
var _isFireFox = true;
// IEのバージョンで動作分岐
var agent = navigator.userAgent
var msieIndex = agent.indexOf("MSIE",0);
var ieVersion = agent.substring( msieIndex+5, agent.indexOf( ";", msieIndex) );
if ( (ieVersion+0) < 6.0 ) {
_isJQueryOk = false;
_isXmlDom = false;
}
if ( -1 != agent.indexOf( "Windows NT 5.0" ) ) {
_isXmlDom = true;
}
// ActiveXの有無=IEか否かをチェック。
// ※以前は if( window.ActiveXObject ) で判別できたが、IE11から !== が必要。
// ref. http://bugs.jquery.com/ticket/14475
_isActiveX = (window.ActiveXObject !== undefined);
// FireFoxか否かをチェック。
// clickアクションへのbind動作が微妙に異なるので。
_isFireFox = (agent.indexOf('firefox') != -1)
return {
isJQueryOk : function() { return _isJQueryOk; },
isXmlDom : function() { return _isXmlDom; },
isActiveXAsIE : function() { return _isActiveX; },
isIE : function() { return _isActiveX; }, // これは上のメソッドと同値。
isFireFox : function() { return _isFireFox; }
};
})();
//
// XML + XSLT の汎用ファンクション。IE / Google Chrome 対応。
// クラス(っぽいもの)化。そしてIE11対応(IE判別)。 at 2014.08.10
//
// …本当は、ajaxベースの戻り値をそのまま利用したいのだが、XSLTとの相性が悪くて何とも。。。
// なのでDOM / XMLHttpRequest 利用はそのままに、deferredを利用して ajax っぽく実装してみる。
//
// [使い方]
// var xmlDeferred = XmlXslt.loadDom( url_of_xml );
// var xsl1Deferred = XmlXslt.loadDom( url_of_xslt1 );
// var xsl2Deferred = XmlXslt.loadDom( url_of_xslt2 );
//
// $.when( xmlDeferred, xsl1Deferred, xsl2Deferred )
// .done( function( xml, xslt1, xslt2 ){
// var str_or_documentfragment = XmlXslt.transformToStrOrDocumentFragment( xml, xslt1 );
// // ↑IEの場合は文字列が、それ以外なら DocumentFragmentが返る。
// $( target ).html( str_or_documentfragment );
// });
//
var XmlXslt = (function() {
var xsltProc_uniquHere = null;
if( !ActionSupport.isActiveXAsIE() ) {
// IE以外は XSLTProcessor() ベースで実施。
xsltProc_uniquHere = new XSLTProcessor();
}
return {
loadDom :
function( xmlFileName ) {
var objXml;
var xmlReq;
var deferred = $.Deferred();
if( ActionSupport.isActiveXAsIE() ){
// IE用
objXml = getXMLDOMObject();
// objXml.async = true; 非同期のままとする。
objXml.onreadystatechange = function () {
if( objXml.readyState == 4 ){ // 読み込み完了。Not 4 なら処理継続中。
// 原因は不明だが、IEの場合は status がundefinedになっている。。。
// ので、エラーチェックは諦める(延々、読み込み中のまま)。
deferred.resolve( objXml );
}
};
objXml.load( xmlFileName );
} else {
// それ以外(Google Chromeとか)
// IE以外は jQueryベースで実施。
// ※当初 XMLHttpRequest() ベースで実施していたのだが、
// onreadystatechange がうまく動作しなかったので諦めた。
// ※本クラスでは、XSLTの都合上DOM(XML)オブジェクトを返却する必要があるので、
// ajax実行結果に対して、jqXHRからresponseXMLを取り出している。
var jqXHR = $.ajax({
type : "GET",
url : xmlFileName,
dataType : "xml"
});
jqXHR.then(
function( data ){ deferred.resolve( jqXHR.responseXML ); },
function( data ){ deferred.reject( null ); }
);
}
return deferred.promise();
},
transformToStrOrDocumentFragment :
function( objXml, objXslt ) { // 両引数とも、DOM or XMLHttpRequest() オブジェクトであること。
// ref. http://shoichimasuhara.hatenablog.com/entry/20090604/1244106114
if ( objXml != null ) {
if( xsltProc_uniquHere == null ) {
// IE用
// →Stringが返る。
return objXml.transformNode( objXslt );
} else {
// それ以外(Google Chromeとか)
// →documentFragmentが返る。
xsltProc_uniquHere.importStylesheet( objXslt );
return xsltProc_uniquHere.transformToFragment( objXml, document);
}
} else {
return null;
}
}
};
})();
|