Generic PDF Reader Plugin Detector




Download PluginDetect and DummyPDF here...

In order to do generic pdf detection in a browser, you will need several things:

1) download the DummyPDF file (just right click and Save As). The DummyPDF file is used by PluginDetect in order to do NOTF (not on the fly) detection.

2) download the PluginDetect script itself. The download page will allow you to customize the PluginDetect script to include whatever features you desire. [Or, you can simply use the sample PluginDetect script used by the detector at the top of this page.]

3) write the Javascript code that calls the appropriate PluginDetect commands. [Or, you can use the sample script used by the detector at the top of this page.] Make sure that the DummyPDF input argument in your Javascript code specifies the correct filename and path.



Background info

PluginDetect's Generic PDF Reader Detector will try to determine if your browser can display a PDF document. It will do so regardless of whether your browser is using the Adobe PDF Reader plugin, a non-Adobe PDF plugin, or a PDF viewer that is built in to the browser.

The Generic PDF detector covers a number of different cases:

1) Non - Internet Explorer browsers + Adobe Reader plugin: can be detected by PluginDetect. We simply check the mimetypes array to verify that "application/pdf" is present and enabled.

2) Non - Internet Explorer browsers + non-Adobe PDF Reader plugins: can be detected by PluginDetect. We simply check the mimetypes array to verify that "application/pdf" is present and enabled.

3) Internet Explorer + Adobe Reader plugin: can be detected by PluginDetect for IE 6+. We instantiate the ActiveX object to verify the plugin presence. The Adobe Reader plugin is an approved control in IE 7+, and hence no security popup appears in the browser when the ActiveX control is instantiated. In order to do this detection, ActiveX has to be enabled and ActiveX filtering has to be disabled.

4) Internet Explorer + non-Adobe PDF Reader plugins: can be detected by PluginDetect, but only if the detectNonAdobeIE input argument is true, and if ActiveX is enabled, and ActiveX Filtering is disabled. In this case, unfortunately, it is very possible that Internet Explorer may trigger a security popup.
   The popup may occur because a 1x1 <object> tag containing a PDF was inserted into the web page, and the <object> tag was not security approved yet to display PDF documents. Either the plugin authors need to give security pre-approval to their plugin (like Adobe does for their plugin), or the user will have to give security approval by clicking on the popup.
   The plugin authors could make their PDF reader plugin more easily detectable via Javascript in IE if they wanted to, but most of them have not bothered to do so. It does not appear to be a high priority for them. [Though there are some exceptions to this rule.]
   Note: due to the unconventional techniques used to detect non-Adobe Reader plugins for Internet Explorer, there is no guarantee that this detection is future proofed. Future versions of IE may or may not allow detection. But so far, up to and including Internet Explorer 10, things appear to work.

5) Non - Internet Explorer browsers + built-in PDF viewer: can be detected by PluginDetect. In cases such as this, the navigator.mimetypes array may or may not have an "application/pdf" item. If there is no "application/pdf" item in the array, PluginDetect will try to instantiate an empty PDF file [1 pixel by 1 pixel] in the web page. If the instantiation works, then the browser probably supports PDF documents.

6) Any Browser + disabled PDF viewer(s):
if all the PDF Readers within your browser are disabled, then PluginDetect will most likely not be able to detect them. Despite this, it is still possible that a standalone PDF Reader application is on your computer, and can be used to display PDF documents. [Obviously, PluginDetect cannot directly detect a standalone application, since PluginDetect only runs within the browser environment.] It is also possible that when you click on a link to a PDF document in a web page, your browser will download the PDF, and cause the standalone PDF Reader to display the document.



2 Kinds of PDF Readers: Plugin vs Built-in

Many browsers require you to install a plugin in order to display PDF documents. Adobe Reader and Foxit Reader, for example, provide exactly such a plugin. There are other browsers, however, that come with a built-in PDF viewer:

   1) Chrome 6+ has a built-in PDF viewer. You have to enable it in the browser. When you do, the "application/pdf" item will be present in the mimetypes array.

   2) Firefox 19+ has a built-in viewer.

   3) Safari/Mac has a built-in PDF viewer.

   4) Safari/iPad has a built-in PDF viewer.

   5) There are other browsers as well that have (or will have) native PDF support.

In cases where the browser has a built-in PDF viewer, but no "application/pdf" mimetype in the navigator.mimeTypes[ ] array, detection of PDF support requires inserting a small dummy PDF <object> tag into the web page. This detection usually occurs "not on the fly" (NOTF).



OTF vs NOTF

We say that PDF detection is performed either "on the fly" (OTF) or "not on the fly" (NOTF) in your script. If a PluginDetect command is able to initiate detection, complete that detection, and return the final detection results, then we know that OTF detection has occurred.

On the other hand, if a PluginDetect command is only able to initiate detection, but is unable to return the final detection results, then we know that NOTF detection is occurring. NOTF detection is required for certain browser/platform/PDF Reader combinations.

For a more complete discussion of OTF and NOTF, see this page.



A few PluginDetect commands for PDF Reader detection

PluginDetect.getVersion('PDFReader', DummyPDF, detectNonAdobeIE): [Returns null]
   Returns null only because PluginDetect will not attempt to detect any plugin version. The reason is that there are multiple vendors for PDF readers, and they use different version numbers. Also, a plugin version is irrelevant when the browser has built-in PDF support and thus requires no plugin.

PluginDetect.isMinVersion('PDFReader', minVersion, DummyPDF, detectNonAdobeIE): [Returns number]

   Returns 0 if plugin is installed & enabled. The plugin version is unknown. You can view PDF documents using the browser (with the plugin) and/or the PDF Reader standalone application [depending on the browser settings and the standalone application settings.]

   Returns -0.15 (Internet Explorer only) if plugin is installed but not enabled for <object>/<embed> tags. The plugin version is unknown. You can view PDF documents using the browser (with the plugin) and/or the PDF Reader standalone application [depending on the browser settings and the standalone application settings.] When the browser displays a PDF, however, it will not be able to use <object>/<embed> tags to display that PDF. This result occurs for Internet Explorer when the PDF Reader ActiveX control is disabled in the add-ons menu, or when the <object>/<embed> tag is not security approved to display a PDF (ie. a security popup occurs).

   Returns -0.5 if plugin detection has been initiated but is not yet completed. At this point in time, it is unknown whether a PDF Reader plugin is installed or not. Detection is occurring NOTF (Not On The Fly), so you will have to wait until the detection has completed. Only certain plugins (on certain browsers and platforms) require NOTF.
   In order to handle NOTF detection, it is recommended that you use the onDetectionDone( ) method. This method will call an event handler after plugin detection has fully completed. The handler can call the isMinVersion( ), getVersion( ) and getInfo( ) methods to obtain the final plugin detection results.

   Returns -1 if plugin is not installed / not enabled. You cannot view PDF documents within the browser because there is no PDF Reader browser plugin. It is still possible, however, that a PDF Reader standalone application is installed on your computer and can display PDF documents. [But PluginDetect cannot detect standalone applications - it can only detect browser plugins.]

   Returns -1.5 (Internet Explorer only) if plugin status is unknown. PluginDetect is unable to determine if a PDF Reader plugin is installed or not because ActiveX is disabled, or ActiveX Filtering is enabled, or detectNonAdobeIE is false/undefined and Adobe Reader was not detected. [Note 1: a PDF Reader plugin can display a PDF document with or without ActiveX in Internet Explorer. Without ActiveX, however, we cannot detect the presence of the plugin and we cannot use <object/embed> tags to display a PDF.] [Note 2: if detectNonAdobeIE is false/undefined and Adobe Reader was not detected, then it is possible that a non-Adobe PDF Reader plugin is installed in the browser. But we have no way of knowing that since no attempt was made to detect any non-Adobe PDF plugins.]

   Returns -3 if you supplied a bad input argument to the isMinVersion( ) method.

PluginDetect.onDetectionDone('PDFReader', f, DummyPDF, detectNonAdobeIE): [Returns number]
   This method will initiate plugin detection if needed, and will execute the event handler f after the plugin detection results become available. The event handler f automatically receives the PluginDetect object as an input argument such that we have f(PluginDetect){ ... }. You are free to use the getVersion( ), isMinVersion( ) and getInfo( ) methods inside event handler f.
   onDetectionDone( ) is capable of doing both OTF and NOTF plugin detection. NOTF detection is required for certain browser/platform/PDF Reader combinations. You must specify the DummyPDF input argument in order for NOTF detection to occur.
   Returns 1 if plugin detection is done (OTF) and handler f has been executed.
   Returns 0 if plugin detection is not done yet (NOTF) and handler f has not been called yet. Handler f will be called after detection has been completed.
   Returns -1 if error (plugin name input argument not specified correctly).

PluginDetect.onBeforeInstantiate('PDFReader', f):
   Executes the event handler f immediately before PluginDetect attempts to instantiate the plugin. [By instantiate, we mean that an instance of the plugin is inserted into your web page. This will cause the plugin to start up and run, assuming it is installed.] The event handler automatically receives the PluginDetect object as an input argument such that we have f(PluginDetect){ ... }.
  Sometimes during detection, it may be necessary for PluginDetect to instantiate (or attempt to instantiate) the plugin. Should this attempt be neccessary, the event handler f will run first, and then the plugin will attempt to instantiate. [Note: If the plugin is installed and enabled, then it instantiates. If it is not installed or not enabled, then it will not instantiate. Either way, the handler f will run before the attempt is made.]
  In order for the onBeforeInstantiate( ) method to work correctly, you must place it BEFORE detection is started for the plugin. In other words, use it before getVersion(pluginName), isMinVersion(pluginName), and onDetectionDone(pluginName). As an example:
       var PD = PluginDetect;
       var F1 = function($){ ... };        // $ input arg is the PluginDetect object
       PD.onBeforeInstantiate('PDFReader', F1);
       var F2 = function($){ var version = $.getVersion('PDFReader'); alert(version); };
       PD.onDetectionDone('PDFReader'', F2, 'empty.pdf');

PluginDetect.onWindowLoaded( f ):
   Executes the event handler f after the browser window has fully loaded. The event handler f automatically receives the PluginDetect object as an input argument such that we have f(PluginDetect){ ... }. You are free to use getVersion( ), isMinVersion( ), onDetectionDone and onBeforeInstantiate( ) inside event handler f.

Event handler f without user input arguments: If the user does not specify any input arguments for event handler f, then the relevant PluginDetect methods are in the format of
       PluginDetect.onDetectionDone(pluginName, f, ...)
       PluginDetect.onWindowLoaded(f)
       PluginDetect.onBeforeInstantiate(pluginName, f)

When the handler f is executed it automatically receives the PluginDetect object as input such that we have f(PluginDetect){ ... }.

Event handler f with user input arguments: You may specify up to 3 inputs (ie. arg1, arg2, and arg3) for the event handler. The trick is to use an array such as [f, arg1, arg2, arg3]. The relevant PluginDetect methods are in the format of
       PluginDetect.onDetectionDone(pluginName, [f, arg1, arg2, arg3], ...)
       PluginDetect.onWindowLoaded( [f, arg1, arg2, arg3] )
       PluginDetect.onBeforeInstantiate(pluginName, [f, arg1, arg2, arg3])

When the handler f is executed it automatically receives the PluginDetect object as input such that we have f(PluginDetect, arg1, arg2, arg3){ ... }.



PluginDetect.getInfo('PDFReader', DummyPDF): [object or null]
   Returns null if no information is available for this plugin.
   Returns an object with several useful properties. The properties are listed below. To simplify matters, we assign this object to a variable:
    var INFO = PluginDetect.getInfo('PDFReader', DummyPDF);

INFO.OTF: [number]
   Returns 0 if PDF Reader detection has been performed on the fly (OTF).
   Returns 1 if PDF Reader detection is being performed not on the fly (NOTF) but is not completed yet.
   Returns 2 if PDF Reader detection has been performed not on the fly (NOTF) and is complete.

INFO.DummyPDFused: [Boolean]
   Returns true if the DummyPDF file was loaded/used by the PDF Reader plugin during detection. The DummyPDF was temporarily inserted into the web page as an <object> tag.
   Returns false if the DummyPDF was not loaded/used by the PDF Reader plugin during detection. This occurs when the DummyPDF was not needed to accomplish the detection, or when the PDF Reader plugin is not installed/not enabled in the browser.



minVersion: [string or number input argument]
Use a value of '0' here because PluginDetect does not know or care what the PDF reader plugin version is.

DummyPDF: [string input argument, optional but strongly recommended] 
This is the path/filename to an empty PDF document that is temporarily inserted into a web page. It is used by PluginDetect to see if a browser has PDF capability. You may download the DummyPDF file here. You are free to rename the DummyPDF file to whatever you wish, as long as the .pdf extension remains the same. We tried to make the file as small as possible.
   The path of the DummyPDF can be relative or absolute. If the path is relative, then it is relative to your HTML web page only! If your Javascript code is in an external Javascript file, then the path of DummyPDF is NOT relative to the Javascript file - it is still relative to the HTML web page. For example,
           DummyPDF = 'empty.pdf' means the file is in the same folder as your web page.
           DummyPDF = 'ABC/empty.pdf' means the file is in a subfolder ABC.
   Because DummyPDF is usually used during NOTF detection, it is recommended that you use DummyPDF as an input argument to the onDetectionDone( ) method.

detectNonAdobeIE: [input argument, optional]
This input tells PluginDetect whether or not it should try to detect any non-Adobe PDF Readers installed in Internet Explorer.
   When the input is 0 or false, then PluginDetect will only try to detect the Adobe PDF Reader for Internet Explorer. The disadvantage to doing this is that any non-Adobe PDF Readers in IE will not be detected. The advantage is that there will/should be no security popups in the browser as a result of this plugin detection.
   When the input is 1 or true, then PluginDetect will try to detect both Adobe and non-Adobe PDF Readers installed in Internet Explorer. You need to specify the DummyPDF input argument in this case. The disadvantage here is that the detection of any non-Adobe PDF Readers in IE may produce a security popup in the browser.
   You only need to specify this input argument in the very first PluginDetect method( ) that deals with PDFReader detection. (If you do not specify any input value at all, then a default value of false is assumed.) All subsequent PluginDetect methods will remember your initial input.




Limitations of PDF Reader detection

When you install a PDF Reader on your computer, you have 2 ways of viewing PDF documents:

i) You can use the standalone PDF Reader application to view PDF documents.

or

ii) You can use a browser with the PDF Reader plugin to view PDF documents. A PDF document can appear directly inside the browser window, or inside a web page via a <frame> tag/<iframe> tag/<object> tag/<embed> tag.


The problem here is that PluginDetect can only detect the plugin. It cannot detect the standalone application. (But the presence of the plugin implies the presence of the standalone)

For example, a user may adjust the PDF Reader preferences and the browser settings so that the plugin is totally disabled. In this case, PluginDetect will not be able to detect the PDF Reader plugin, yet the user will still be able to view PDF documents in the standalone application.




Example using onDetectionDone( )

In order to be able to detect PDF capability on the widest variety of browsers, you should use the onDetectionDone( ) method. An example of how to use this is as follows:

var $$ = PluginDetect;
var DummyPDF = 'empty.pdf';
var detectNonAdobeIE = 1;

// We assume here that a <div id="pdfresult"></div> is in the <body> tag somewhere, so
// that we have somewhere to place the results from the PDF detection.

var output = 'pdfresult';

function displayPDFresults($$)
{
    var status = $$.isMinVersion('PDFReader', 0);
    var msg = 'PDF Reader plugin status: ';

    if (status >= 0) msg += 'installed & enabled'
    else if (status==-0.15) msg += 'installed but not enabled for object/embed tags'
    else if (status==-1) msg += 'not installed or not enabled'
    else if (status == -1.5) msg += 'unknown'
    else if (status==-3) msg+='error...bad input argument to PluginDetect method'
    else msg += 'unknown';

     var N = document.getElementById(output);
     if (N) N.innerHTML += msg;
};


// Display results when PDF detection is completed
$$.onDetectionDone('PDFReader', displayPDFresults, DummyPDF, detectNonAdobeIE);


A few things of interest to note for the above example.

1) The PDF detector at the very top of this page uses onDetectionDone( ). Feel free to use the script in your own web page if you wish.

2) DummyPDF only needs to be specified for the very first PluginDetect method that is executed by the browser. In this example, that would be the onDetectionDone( ) method. We did not need to specify DummyPDF for the isMinVersion( ) method inside event handler displayPDFresults, because isMinVersion( ) is executed after onDetectionDone( ). [Of course, you are free to use DummyPDF in both isMinVersion( ) and onDetectionDone( ) if you wish].
   As a general rule, I would recommend you only use DummyPDF with the onDetectionDone( ) method. The reason is that DummyPDF is usually used during NOTF detection, and NOTF is best handled using the onDetectionDone( ) method.

3) detectNonAdobeIE only needs to be specified for the very first PluginDetect method that is executed by the browser. In this example, that would be the onDetectionDone( ) method. If you do not specify a value at all, then a default value of false is assumed.

4) Sometimes, the isMinVersion('PDFReader') method will return -1.5. This means that PluginDetect is unable to determine whether a PDF reader is installed or not. The -1.5 result occurs only for Internet Explorer.
   There are 3 potential reasons why a -1.5 result can occur: a) ActiveX is disabled in the browser. This prevents any PDF Reader from being detected in the browser. b) ActiveX filtering is enabled (for IE 9+). This also prevents any PDF Reader from being detected. c) detectNonAdobeIE is false and Adobe Reader is not installed. This means we are not trying to detect non-Adobe Readers in Internet Explorer, so we have no way to know whether one of these PDF Readers is installed or not.



How to verify DummyPDF path & filename

Sometimes it's nice to verify that the path and filename of DummyPDF were correctly specified. The way to verify this is to select the "Verify DummyPDF [path/]name" option when downloading the PluginDetect script.

When the PluginDetect script is downloaded with this option, and you then use this script in your own plugin detection web page, a box will appear at the very top of your web page. This box will display the contents of the DummyPDF file, assuming that you specified the DummyPDF path and filename correctly. If not, then the DummyPDF input argument may have a problem.
  
When you are done verifying the DummyPDF path and filename, you should download another PluginDetect script without the "Verify DummyPDF [path/]name" option, and use that script in your own plugin detection web page.


Notes: The "Verify DummyPDF [path/]name" option ...

1) is only for testing, debugging, & verification purposes. It is not to be used when doing normal PDF detection.
2) will only be of use to you if your browser is able to display PDFs (either via a plugin or a built-in PDF viewer).
3) may not work with every browser, but you only need it to work on ONE browser in order to verify the DummyPDF path and filename.
4) when used with Internet Explorer, it might require the DummyPDF file to be on a web server in order for verification to work properly.
   For non-Internet Explorer browsers, it appears to make no difference whether the DummyPDF file is on your local hard drive or on a web server. The DummyPDF verification will work either way.
   Perhaps this behavior for Internet Explorer is just a small bug. But the user should be aware of this issue nonetheless.




Top of Page