1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * Does nothing (static class). 26 * @constructor 27 * @class 28 * 29 * This class provides static methods to determine which standard plugins are 30 * installed in the browser. 31 * 32 * @private 33 */ 34 AjxPluginDetector = function() { 35 } 36 37 AjxPluginDetector.canDetectPlugins = 38 function() { 39 return AjxEnv.isIE || (navigator.plugins && navigator.plugins.length > 0); 40 }; 41 42 AjxPluginDetector.detectFlash = 43 function() { 44 if(AjxEnv.isIE) { 45 return AjxPluginDetector.detectActiveXControl('ShockwaveFlash.ShockwaveFlash.1'); 46 } else { 47 return AjxPluginDetector.detectPlugin('Shockwave','Flash'); 48 } 49 }; 50 51 AjxPluginDetector.detectPDFReader = 52 function(){ 53 if(AjxEnv.isIE){ 54 return ( AjxPluginDetector.detectActiveXControl('PDF.PdfCtrl.5') 55 || AjxPluginDetector.detectActiveXControl('AcroExch.Document') ); 56 }else{ 57 var hasPDFReader = false; 58 if(AjxEnv.isChrome){ 59 hasPDFReader = AjxPluginDetector.detectPlugin('Chrome PDF Viewer'); 60 }else if(AjxEnv.isFirefox){ 61 hasPDFReader = AjxPluginDetector.detectPlugin('Firefox PDF Plugin for Mac OS X'); 62 } 63 if(!hasPDFReader){ 64 hasPDFReader = AjxPluginDetector.detectPlugin('Adobe Acrobat'); 65 } 66 return hasPDFReader; 67 } 68 }; 69 70 AjxPluginDetector.detectDirector = 71 function() { 72 if(AjxEnv.isIE) { 73 return AjxPluginDetector.detectActiveXControl('SWCtl.SWCtl.1'); 74 } else { 75 return AjxPluginDetector.detectPlugin('Shockwave','Director'); 76 } 77 }; 78 79 AjxPluginDetector.detectQuickTime = 80 function() { 81 if(AjxEnv.isIE) { 82 return AjxPluginDetector.detectQuickTimeActiveXControl(); 83 } else { 84 return AjxPluginDetector.detectPlugin('QuickTime'); 85 } 86 }; 87 88 // If quicktime is installed, returns the version as an array: [major, minor, build] 89 AjxPluginDetector.getQuickTimeVersion = 90 function() { 91 if(AjxEnv.isIE) { 92 var object = new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1"); 93 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: Quicktime is " + object.IsQuickTimeAvailable(0) ? "available" : "not available"); 94 if (object.IsQuickTimeAvailable(0)) { 95 try { 96 var version = Number(object.QuickTimeVersion).toString(16); 97 var result = []; 98 for(var i = 0; i < 3; i++) { 99 result[i] = Number(version.charAt(i)); 100 } 101 return result; 102 } catch(e) { 103 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: Error while checking QuickTimeVersion: " + e); 104 } 105 } 106 return null; 107 } else { 108 var match = AjxPluginDetector.matchPluginName(/QuickTime Plug-in (\d+)\.?(\d+)?\.?(\d+)?/); 109 if (match) { 110 DBG.println("AjxPluginDetector: able to find match for QuickTime plugin with version: " + match); 111 var result = []; 112 for(var i = 0; i < 3; i++) { 113 result[i] = Number(match[i + 1] || 0); 114 } 115 return result; 116 } else { 117 DBG.println("AjxPluginDetector: unable to find match for QuickTime plugin with version"); 118 return null; 119 } 120 } 121 }; 122 123 /** 124 * This code is part of JQuery's Flash plugin. 125 * http://jquery.lukelutman.com/plugins/flash/ 126 * 127 * @return Flash plugin version 128 */ 129 AjxPluginDetector.getFlashVersion = 130 function() { 131 var flashVersion = "0,0,0"; 132 // ie 133 try { 134 try { 135 // avoid fp6 minor version lookup issues 136 // see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ 137 var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6'); 138 try { 139 axo.AllowScriptAccess = 'always'; 140 } 141 catch(e) { 142 return '6,0,0'; 143 } 144 } catch(e) { 145 } 146 flashVersion = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; 147 // other browsers 148 } catch(e) { 149 try { 150 if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) { 151 flashVersion = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]; 152 } 153 } catch(e) { 154 } 155 } 156 return flashVersion; 157 }; 158 159 AjxPluginDetector.detectReal = 160 function() { 161 if(AjxEnv.isIE) { 162 return AjxPluginDetector.detectActiveXControl('rmocx.RealPlayer G2 Control') || 163 AjxPluginDetector.detectActiveXControl('RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)') || 164 AjxPluginDetector.detectActiveXControl('RealVideo.RealVideo(tm) ActiveX Control (32-bit)'); 165 } else { 166 return AjxPluginDetector.detectPlugin('RealPlayer'); 167 } 168 }; 169 170 AjxPluginDetector.detectWindowsMedia = 171 function() { 172 if(AjxEnv.isIE) { 173 return AjxPluginDetector.detectActiveXControl('MediaPlayer.MediaPlayer.1'); 174 } else { 175 return AjxPluginDetector.detectPlugin('Windows Media'); 176 } 177 }; 178 179 AjxPluginDetector.detectPlugin = 180 function() { 181 DBG.println(AjxDebug.DBG1, "-----------------------<br>AjxPluginDetector: Looking for plugin: [" + AjxPluginDetector._argumentsToString(AjxPluginDetector.detectPlugin.arguments) + "]"); 182 var names = AjxPluginDetector.detectPlugin.arguments; 183 var allPlugins = navigator.plugins; 184 var pluginsArrayLength = allPlugins.length; 185 for (var pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ ) { 186 // loop through all desired names and check each against the current plugin name 187 var numFound = 0; 188 for(var namesCounter=0; namesCounter < names.length; namesCounter++) { 189 // if desired plugin name is found in either plugin name or description 190 if (allPlugins[pluginsArrayCounter]) { 191 if( (allPlugins[pluginsArrayCounter].name.indexOf(names[namesCounter]) >= 0)) { 192 // this name was found 193 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: found name match '" + allPlugins[pluginsArrayCounter].name + "'"); 194 numFound++; 195 } else if (allPlugins[pluginsArrayCounter].description.indexOf(names[namesCounter]) >= 0) { 196 // this name was found 197 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: found description match '" + allPlugins[pluginsArrayCounter].description + "'"); 198 numFound++; 199 } 200 } 201 } 202 // now that we have checked all the required names against this one plugin, 203 // if the number we found matches the total number provided then we were successful 204 if(numFound == names.length) { 205 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: Found plugin!<br>-----------------------"); 206 return true; 207 } else if (numFound) { 208 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: Found partial plugin match, numFound=" + numFound); 209 } 210 } 211 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: Failed to find plugin.<br>-----------------------"); 212 return false; 213 }; 214 215 AjxPluginDetector.matchPluginName = 216 function(regExp) { 217 var allPlugins = navigator.plugins; 218 var pluginsArrayLength = allPlugins.length; 219 for (var pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ ) { 220 var match = allPlugins[pluginsArrayCounter].name.match(regExp); 221 if (match) { 222 return match; 223 } 224 } 225 return null; 226 }; 227 228 AjxPluginDetector.detectActiveXControl = 229 function(progId) { 230 try { 231 new ActiveXObject(progId); 232 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: found ActiveXObject '" + progId + "'"); 233 return true; 234 } catch (e) { 235 DBG.println(AjxDebug.DBG1, "AjxPluginDetector: unable to find ActiveXObject '" + progId + "'"); 236 return false; 237 } 238 }; 239 240 AjxPluginDetector.detectQuickTimeActiveXControl = 241 function(progId) { 242 try { 243 var object = new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1"); 244 return object.IsQuickTimeAvailable(0); 245 } catch (e) { 246 return false; 247 } 248 }; 249 250 // Util method to log arguments, which to my surprise are not actually an array. 251 AjxPluginDetector._argumentsToString = 252 function(args) { 253 var array = []; 254 for (var i = 0, count = args.length; i < count; i++) { 255 array[i] = args[i]; 256 } 257 return array.join(',') 258 };