|
24 | 24 |
|
25 | 25 | 'use strict';
|
26 | 26 |
|
| 27 | + |
27 | 28 | (function (root, factory) {
|
28 | 29 | if (typeof define === 'function' && define.amd) {
|
29 | 30 | // AMD. Register as an anonymous module.
|
30 |
| - define(['exports', 'react'], factory); |
| 31 | + define(['react'], factory); |
31 | 32 | } else if (typeof exports === 'object') {
|
32 |
| - // CommonJS |
33 |
| - factory(exports, require('react')); |
| 33 | + // Node. Does not work with strict CommonJS, but |
| 34 | + // only CommonJS-like enviroments that support module.exports, |
| 35 | + // like Node. |
| 36 | + module.exports = factory(require('react')); |
34 | 37 | } else {
|
35 |
| - // Browser globals |
36 |
| - factory((root.ReactSWF = {}), root.React); |
| 38 | + // Browser globals (root is window) |
| 39 | + root.ReactSWF = factory(root.React); |
37 | 40 | }
|
38 |
| -}(this, function (exports, React) { |
39 |
| - |
| 41 | +}(this, function (React) { |
| 42 | + |
| 43 | + var encodeFlashKeyValueRegex = /[\r%&+]/g; |
40 | 44 | var encodeFlashKeyValueLookup = {
|
41 | 45 | '\r': '%0D', '%': '%25', '&': '%26', '+': '%2B', '=': '%3D'
|
42 | 46 | };
|
43 | 47 |
|
44 | 48 | var objectParamNames = {
|
45 |
| - play: true, loop: true, menu: true, quality: true, scale: true, |
46 |
| - bgColor: true, wmode: true, base: true, allowScriptAccess: true, |
| 49 | + play: true, loop: true, menu: true, quality: true, scale: true, align: true, |
| 50 | + salign: true, bgColor: true, wmode: true, base: true, allowScriptAccess: true, |
47 | 51 | allowFullScreen: true, fullScreenAspectRatio: true
|
48 | 52 | };
|
49 | 53 |
|
50 |
| - var flashPlayerVersion; |
51 |
| - |
52 | 54 | var nextUniqueObjectSwfId = 0;
|
53 | 55 |
|
54 |
| - var memoryLeakWorkaround; |
55 |
| - |
56 |
| - |
57 |
| - /** |
58 |
| - * Get the installed Flash Player version. |
59 |
| - * |
60 |
| - * @return {?string} Version as X.Y.Z, null if not installed/enabled. |
61 |
| - */ |
62 |
| - function getFPVersion() { |
63 |
| - if (flashPlayerVersion === undefined) { |
64 |
| - flashPlayerVersion = null; |
65 |
| - |
66 |
| - if ('plugins' in navigator) { |
67 |
| - var plugin = navigator.plugins['Shockwave Flash']; |
68 |
| - if (plugin) { |
69 |
| - var mimeType = navigator.mimeTypes['application/x-shockwave-flash']; |
70 |
| - if (mimeType && mimeType.enabledPlugin) { |
71 |
| - flashPlayerVersion = plugin.description |
72 |
| - .match(/(\d+)\.(\d+) r(\d+)/).slice(1).join('.'); |
73 |
| - } |
74 |
| - } |
75 |
| - } else if ('ActiveXObject' in window) { |
76 |
| - try { |
77 |
| - var axObject = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); |
78 |
| - if (axObject) { |
79 |
| - flashPlayerVersion = axObject.GetVariable('$version') |
80 |
| - .match(/(\d+),(\d+),(\d+)/).slice(1).join('.'); |
81 |
| - } |
82 |
| - } |
83 |
| - catch (e) {} |
84 |
| - } |
85 |
| - } |
86 |
| - |
87 |
| - return flashPlayerVersion; |
88 |
| - } |
89 | 56 |
|
90 |
| - /** |
91 |
| - * Checks if the required Flash Player version is supported by the client. |
92 |
| - * |
93 |
| - * @param {string} version Required version. |
94 |
| - * @return {boolean} True if the version is supported. |
95 |
| - */ |
96 |
| - function isFPVersionSupported(version) { |
97 |
| - var supportedVersion = getFPVersion(); |
98 |
| - |
99 |
| - if (supportedVersion === null) { |
100 |
| - return false; |
101 |
| - } |
102 |
| - |
103 |
| - var supportedVersionArray = supportedVersion.split('.'); |
104 |
| - var requiredVersionArray = version.split('.'); |
105 |
| - |
106 |
| - for (var i = 0; i < requiredVersionArray.length; i++) { |
107 |
| - if (+supportedVersionArray[i] > +requiredVersionArray[i]) { |
108 |
| - return true; |
109 |
| - } |
110 |
| - if (+supportedVersionArray[i] < +requiredVersionArray[i]) { |
111 |
| - return false; |
112 |
| - } |
113 |
| - } |
114 |
| - |
115 |
| - return true; |
| 57 | + function encodeFlashKeyValueEncoder(match) { |
| 58 | + return encodeFlashKeyValueLookup[match]; |
116 | 59 | }
|
117 | 60 |
|
118 |
| - /** |
119 |
| - * Encodes text for safe transport through flashVars. |
120 |
| - * |
121 |
| - * @param {*} text Text value to encode. |
122 |
| - * @return {string} An encoded string. |
123 |
| - */ |
124 | 61 | function encodeFlashKeyValue(string) {
|
125 | 62 | // Encode \r or it may be normalized into \n
|
126 |
| - return ('' + string).replace(/[\r%&+]/g, function(match) { |
127 |
| - return encodeFlashKeyValueLookup[match]; |
128 |
| - }); |
| 63 | + return ('' + string).replace( |
| 64 | + encodeFlashKeyValueRegex, |
| 65 | + encodeFlashKeyValueEncoder |
| 66 | + ); |
129 | 67 | }
|
130 | 68 |
|
131 |
| - |
132 | 69 | function encodeFlashVarsObject(obj) {
|
133 | 70 | // Pushing encoded key-values to an array instead of immediately
|
134 | 71 | // concatenating is faster and scales better with large values.
|
135 | 72 | var list = [];
|
136 | 73 |
|
137 | 74 | for (var key in obj) {
|
138 |
| - list.push( |
139 |
| - encodeFlashKeyValue(key) + '=' + |
140 |
| - encodeFlashKeyValue(obj[key]) |
141 |
| - ); |
| 75 | + if (obj[key] !== null) { |
| 76 | + list.push( |
| 77 | + encodeFlashKeyValue(key) + '=' + |
| 78 | + encodeFlashKeyValue(obj[key]) |
| 79 | + ); |
| 80 | + } |
142 | 81 | }
|
143 | 82 |
|
144 | 83 | return list.join('&');
|
145 | 84 | }
|
146 | 85 |
|
147 |
| - var swf = React.createClass({ |
| 86 | + |
| 87 | + var ReactSWF = React.createClass({ |
148 | 88 | getInitialState: function() {
|
149 | 89 | return {
|
150 | 90 | // flash.external.ExternalInterface.addCallback requires a unique id
|
|
154 | 94 | componentWillUnmount: function() {
|
155 | 95 | // IE8: leaks memory if all ExternalInterface-callbacks have not been
|
156 | 96 | // removed. Only IE implements readyState, hasOwnProperty does not exist
|
157 |
| - // for DOM nodes in IE8. |
| 97 | + // for DOM nodes in IE8, but does in IE9+. |
158 | 98 |
|
159 |
| - if (memoryLeakWorkaround === undefined) { |
160 |
| - memoryLeakWorkaround = |
161 |
| - 'readyState' in document && !('hasOwnProperty' in document); |
162 |
| - } |
163 |
| - if (memoryLeakWorkaround) { |
| 99 | + if ('readyState' in document && !('hasOwnProperty' in document)) { |
164 | 100 | this._cleanup();
|
165 | 101 | }
|
166 | 102 | },
|
|
176 | 112 | render: function() {
|
177 | 113 | var params = [];
|
178 | 114 |
|
179 |
| - // IE8: requires the use of the movie param instead of src |
| 115 | + // IE8: requires the use of the movie param to function |
180 | 116 | params.push(
|
181 | 117 | React.DOM.param({
|
182 | 118 | key: 'movie',
|
|
209 | 145 |
|
210 | 146 | params.push(
|
211 | 147 | React.DOM.param({
|
212 |
| - key: 'flashVars', |
213 |
| - name: 'flashVars', |
| 148 | + key: 'flashvars', |
| 149 | + name: 'flashvars', |
214 | 150 | value: encodedFlashVars
|
215 | 151 | })
|
216 | 152 | );
|
|
228 | 164 | });
|
229 | 165 |
|
230 | 166 |
|
231 |
| - module.exports.getFPVersion = getFPVersion; |
232 |
| - module.exports.isFPVersionSupported = isFPVersionSupported; |
| 167 | + var cachedFPVersion; |
| 168 | + |
| 169 | + /** |
| 170 | + * Detect installed Flash Player version. Result is cached. |
| 171 | + * |
| 172 | + * @return {?string} 'X.Y.Z'-version, or null. |
| 173 | + */ |
| 174 | + function getFPVersion() { |
| 175 | + if (cachedFPVersion === undefined) { |
| 176 | + cachedFPVersion = null; |
| 177 | + |
| 178 | + if (navigator.plugins) { |
| 179 | + var plugin = navigator.plugins['Shockwave Flash']; |
| 180 | + if (plugin) { |
| 181 | + var mimeType = navigator.mimeTypes['application/x-shockwave-flash']; |
| 182 | + if (mimeType && mimeType.enabledPlugin) { |
| 183 | + var matches = plugin.description |
| 184 | + .match(/^Shockwave Flash (\d+)(?:\.(\d+))?(?: r(\d+))?/); |
| 185 | + |
| 186 | + cachedFPVersion = |
| 187 | + matches[1] + '.' + (matches[2] || 0) + '.' + (matches[3] || 0); |
| 188 | + } |
| 189 | + } |
| 190 | + } |
| 191 | + if (window.ActiveXObject) { |
| 192 | + try { |
| 193 | + var axObject = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); |
| 194 | + if (axObject) { |
| 195 | + cachedFPVersion = axObject.GetVariable('$version') |
| 196 | + .match(/^WIN (\d+),(\d+),(\d+)/).slice(1).join('.'); |
| 197 | + } |
| 198 | + } |
| 199 | + catch (e) {} |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + return cachedFPVersion; |
| 204 | + } |
233 | 205 |
|
234 |
| - module.exports.DOM = {}; |
235 |
| - module.exports.DOM.swf = swf; |
| 206 | + /** |
| 207 | + * Detect if installed Flash Player version meets requirements. |
| 208 | + * |
| 209 | + * @param {string} version 'X.Y.Z' or 'X.Y' or 'X'-version. |
| 210 | + * @return {boolean} True if version is supported. |
| 211 | + */ |
| 212 | + function isFPVersionSupported(version) { |
| 213 | + var supportedVersion = getFPVersion(); |
| 214 | + |
| 215 | + if (supportedVersion === null) { |
| 216 | + return false; |
| 217 | + } |
| 218 | + |
| 219 | + var supportedVersionArray = supportedVersion.split('.'); |
| 220 | + var requiredVersionArray = version.split('.'); |
| 221 | + |
| 222 | + for (var i = 0; i < requiredVersionArray.length; i++) { |
| 223 | + if (+supportedVersionArray[i] > +requiredVersionArray[i]) { |
| 224 | + return true; |
| 225 | + } |
| 226 | + if (+supportedVersionArray[i] < +requiredVersionArray[i]) { |
| 227 | + return false; |
| 228 | + } |
| 229 | + } |
| 230 | + |
| 231 | + return true; |
| 232 | + } |
| 233 | + |
| 234 | + |
| 235 | + ReactSWF.utils = { |
| 236 | + getFPVersion: getFPVersion, |
| 237 | + isFPVersionSupported: isFPVersionSupported |
| 238 | + }; |
| 239 | + |
| 240 | + |
| 241 | + return ReactSWF; |
236 | 242 |
|
237 | 243 | }));
|
0 commit comments