├── LICENSE ├── README.md ├── bower.json ├── npm-react-swf ├── README.md ├── compat.js ├── package.json └── react-swf.js ├── package.json ├── react-swf-compat.js ├── react-swf-compat.min.js ├── react-swf.js └── react-swf.min.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Andreas Svensson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ReactSWF ![](https://img.shields.io/github/release/syranide/react-swf.svg) ![](https://img.shields.io/badge/npm-react--swf-blue.svg) ![](https://img.shields.io/badge/bower-react--swf-blue.svg) 2 | 3 | Shockwave Flash Player component for React. GCC `ADVANCED` optimizations compatible. 4 | 5 | Supports all browsers supported by React. ReactSWFCompat is required to support IE8-9. 6 | 7 | Depends on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill_for_non-ES6_browsers) and [`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill) 8 | 9 | Use [SWFPlayerVersion](https://github.com/syranide/swf-player-version) to determine SWF Player support. 10 | 11 | ```jsx 12 | 20 | ``` 21 | ```jsx 22 | const SWF_ID_PREFIX = '__MyExternalInterfaceExample_SWFID_'; 23 | const SWF_CALL_NAME_PREFIX = '__MyExternalInterfaceExample_SWFCall_'; 24 | 25 | let nextUID = 0; 26 | 27 | class MyExternalInterfaceExample extends React.Component { 28 | constructor(props) { 29 | super(props); 30 | 31 | // For most purposes nextUID is sufficient. However, if you rely on 32 | // non-trivial server rendering you must generate deterministic UIDs per 33 | // React root to avoid markup mismatch. 34 | this._uid = nextUID++; 35 | 36 | window[SWF_CALL_NAME_PREFIX + this._uid] = this.handleSWFCall.bind(this); 37 | } 38 | 39 | componentWillUnmount() { 40 | delete window[SWF_CALL_NAME_PREFIX + this._uid]; 41 | } 42 | 43 | handleSWFCall() { 44 | // Beware; SWF calls are executed in the context of SWF Player. 45 | console.log('SWFCall', arguments); 46 | return 'foobar'; 47 | } 48 | 49 | invokeSWFMyCallback(arg) { 50 | // Beware; SWF Player does not sufficiently escape serialized arguments. 51 | return this._swfPlayerNode.myCallback(arg); 52 | } 53 | 54 | render() { 55 | // Globally unique ID is required for ExternalInterface callbacks in IE<11. 56 | return ( 57 | this._swfPlayerNode = c} 60 | id={SWF_ID_PREFIX + this._uid} 61 | flashVars={{myCallbackName: SWF_CALL_NAME_PREFIX + this._uid}} 62 | /> 63 | ); 64 | } 65 | } 66 | ``` 67 | 68 | ## ReactSWFCompat 69 | 70 | ReactSWFCompat (`require('react-swf/compat')`) also supports IE8-9, but should only be used if you must support these browsers. Internally it uses `ReactDOMServer.renderToString` to render to markup and then immediately `ReactDOM.render` on-top of that. There may be some behavioral differences in edge-cases but overall it should behave just the same. Due to the design of React you are required to provide a container element, the SWF-markup will be rendered inside. 71 | 72 | ```jsx 73 | } 75 | src="example.swf" 76 | id="guid_001" 77 | width="300" 78 | height="200" 79 | wmode="transparent" 80 | flashVars={{foo: 'A', bar: 1}} 81 | /> 82 | ``` 83 | 84 | ## Breaking changes 85 | 86 | #### 1.0.0 87 | 88 | * IE8-9 is no longer supported due to issues with the new DOM renderer in React 15. `ReactSWFCompat` has been introduced as a workaround to this. 89 | 90 | #### 0.13.0 91 | 92 | * `getFPVersion` and `isFPVersionSupported` forked to [SWFPlayerVersion](https://github.com/syranide/swf-player-version) and dropped from ReactSWF. Replace `ReactSWF.getFPVersion => SWFPlayerVersion.get` and `ReactSWF.isFPVersionSupported => SWFPlayerVersion.isSupported`. 93 | 94 | #### 0.12.3 95 | 96 | * Depends on `Object.assign()`, [polyfills are available](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill). 97 | 98 | #### 0.11.0 99 | 100 | * React 0.13 components no longer support `ref.getDOMNode()`, use `ref.getFPDOMNode()` instead. 101 | * Depends on `Object.is()`, [polyfills are available](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill_for_non-ES6_browsers). 102 | 103 | ## Properties 104 | 105 | Standard DOM properties are forwarded to the underlying ``. 106 | 107 | Changes to props cannot be and are not reflected by an already mounted SWF (except for `width` and `height`). You must manually provide a computed `key` to ensure the component is reset when appropriate. Beware, this also applies to `src`. 108 | 109 | ``` 110 | src {string} [required] 111 | width {number} 112 | height {number} 113 | ``` 114 | ``` 115 | flashVars {object|string} - {key: {string}}, "key=value&..." 116 | ``` 117 | ``` 118 | allowFullScreen {boolean} - true, false* 119 | allowFullScreenInteractive {boolean} - true, false* 120 | allowNetworking {enum} - all*, internal, none 121 | allowScriptAccess {enum} - always, sameDomain*, never 122 | ``` 123 | ``` 124 | align {enum} - l, t, r 125 | base {string} 126 | bgcolor {string} - #RRGGBB 127 | browserZoom {enum} - scale*, noscale 128 | fullScreenAspectRatio {enum} - portrait, landscape 129 | loop {boolean} - true*, false 130 | menu {boolean} - true*, false 131 | play {boolean} - true*, false 132 | quality {enum} - low, autolow, autohigh, medium, high, best 133 | salign {enum} - l, t, r, tl, tr 134 | scale {enum} - default*, noborder, exactfit, noscale 135 | seamlessTabbing {boolean} - true*, false 136 | wmode {enum} - window*, direct, opaque, transparent, gpu 137 | ``` 138 | 139 | Detailed explanation of most properties found at [[Flash OBJECT and EMBED tag attributes]](http://helpx.adobe.com/flash/kb/flash-object-embed-tag-attributes.html). 140 | 141 | ## API 142 | 143 | #### Instance methods 144 | 145 | ``` 146 | getFPDOMNode() 147 | returns {?DOMNode} Flash Player object DOM node. 148 | 149 | Returns the Flash Player object DOM node. 150 | Should be prefered over `React.findDOMNode`. 151 | ``` 152 | 153 | ## AS3 ExternalInterface 154 | 155 | #### Security flaws 156 | ``` 157 | Escape object key characters for FP: 158 | "&" => "&" 159 | "<" => "<" 160 | "\"" => """ 161 | 162 | Escape object key characters for JS: 163 | "\r" => "\\r" 164 | "\"" => "\\\"" 165 | + wrap key string with "\"" 166 | identifiers with keyword names must also be quoted for JS 167 | 168 | Escape string characters for JS: 169 | 0x005C => "\\\\" (Backslash) 170 | 0x2028 => "\\u2028" (Line separator) 171 | 0x2029 => "\\u2029" (Paragraph separator) 172 | 173 | Invalid UTF8 characters for FP and JS: 174 | 0x0000 (NULL character) 175 | 0xD800-0xDFFF (Non private use surrogates) 176 | 0xFDD0-0xFDEF (Non-characters) 177 | 0xFFFE-0xFFFF (Non-characters) 178 | remove or replace with "\uFFFD" (replacement character) 179 | can only be produced by String.fromCharCode(c) in FP, not "\uXXXX" (exception: 0x0000) 180 | ``` 181 | 182 | This list *may* be incomplete. 183 | 184 | #### ExternalInterface.addCallback 185 | 186 | Returned strings should be encoded using `StringForJS.encode`. 187 | 188 | You must provide a unique DOM `id` to `ReactSWF` for IE8-10. 189 | 190 | ``` 191 | 192 | ``` 193 | 194 | #### ExternalInterface.call 195 | 196 | String arguments should be encoded using `StringForJS.encode`. 197 | 198 | #### StringForJS.encode 199 | 200 | The Flash run-time does not sufficiently encode strings passed to JavaScript. This can cause run-time errors, string corruption or character substitution to occur. Encoded strings are transparently decoded by the JavaScript run-time. 201 | 202 | ```as3 203 | public class StringForJS { 204 | private static var UNSAFE_CHARS_REGEX:RegExp = new RegExp( 205 | // NULL-char (0x00) and backslash (0x5C) 206 | "[\\x00\\\\" + 207 | // Line separator (0x2028), paragraph separator (0x2029) 208 | "\u2028-\u2029" + 209 | // Non private use surrogates (0xD800 - 0xDFFF) 210 | String.fromCharCode(0xD800) + "-" + String.fromCharCode(0xDFFF) + 211 | // Non-characters (0xFDD0 - 0xFDEF) 212 | String.fromCharCode(0xFDD0) + "-" + String.fromCharCode(0xFDEF) + 213 | // Non-characters (0xFFFE + 0xFFFF) 214 | String.fromCharCode(0xFFFE) + String.fromCharCode(0xFFFF) + "]", 215 | "g" 216 | ); 217 | 218 | private static function unsafeCharEscaper():String { 219 | switch (arguments[0]) { 220 | case "\u0000": return "\\0"; 221 | case "\u005C": return "\\\\"; 222 | case "\u2028": return "\\u2028"; 223 | case "\u2029": return "\\u2029"; 224 | default: return "\uFFFD"; 225 | }; 226 | } 227 | 228 | // Encode unsafe strings for use with ExternalInterface. Invalid characters 229 | // are substituted by the Unicode replacement character. 230 | public static function encode(value:String):String { 231 | return value.replace(UNSAFE_CHARS_REGEX, unsafeCharEscaper); 232 | } 233 | } 234 | ``` 235 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-swf", 3 | "version": "1.0.7", 4 | "license": "MIT", 5 | "description": "Shockwave Flash Player component for React", 6 | "authors": ["Andreas Svensson "], 7 | "homepage": "https://github.com/syranide/react-swf", 8 | "bugs": "https://github.com/syranide/react-swf/issues", 9 | "main": "react-swf.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/syranide/react-swf" 13 | }, 14 | "dependencies": { 15 | "react": "^15.0.0-0 || ^16.0.0-0", 16 | "prop-types": "^15.0.0-0" 17 | }, 18 | "keywords": [ 19 | "react", 20 | "react-component", 21 | "component", 22 | "swf", 23 | "shockwave", 24 | "flash", 25 | "player", 26 | "object", 27 | "embed" 28 | ], 29 | "ignore": [ 30 | "npm-react-swf/" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /npm-react-swf/README.md: -------------------------------------------------------------------------------- 1 | ## ReactSWF ![](https://img.shields.io/npm/v/react-swf.svg) 2 | 3 | Shockwave Flash Player component for React. GCC `ADVANCED` optimizations compatible. 4 | 5 | Supports all browsers supported by React. ReactSWFCompat is required to support IE8-9. 6 | 7 | Depends on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill_for_non-ES6_browsers) and [`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill) 8 | 9 | Use [SWFPlayerVersion](https://github.com/syranide/swf-player-version) to determine SWF Player support. 10 | 11 | ```jsx 12 | 20 | ``` 21 | ```jsx 22 | const SWF_ID_PREFIX = '__MyExternalInterfaceExample_SWFID_'; 23 | const SWF_CALL_NAME_PREFIX = '__MyExternalInterfaceExample_SWFCall_'; 24 | 25 | let nextUID = 0; 26 | 27 | class MyExternalInterfaceExample extends React.Component { 28 | constructor(props) { 29 | super(props); 30 | 31 | // For most purposes nextUID is sufficient. However, if you rely on 32 | // non-trivial server rendering you must generate deterministic UIDs per 33 | // React root to avoid markup mismatch. 34 | this._uid = nextUID++; 35 | 36 | window[SWF_CALL_NAME_PREFIX + this._uid] = this.handleSWFCall.bind(this); 37 | } 38 | 39 | componentWillUnmount() { 40 | delete window[SWF_CALL_NAME_PREFIX + this._uid]; 41 | } 42 | 43 | handleSWFCall() { 44 | // Beware; SWF calls are executed in the context of SWF Player. 45 | console.log('SWFCall', arguments); 46 | return 'foobar'; 47 | } 48 | 49 | invokeSWFMyCallback(arg) { 50 | // Beware; SWF Player does not sufficiently escape serialized arguments. 51 | return this._swfPlayerNode.myCallback(arg); 52 | } 53 | 54 | render() { 55 | // Globally unique ID is required for ExternalInterface callbacks in IE<11. 56 | return ( 57 | this._swfPlayerNode = c} 60 | id={SWF_ID_PREFIX + this._uid} 61 | flashVars={{myCallbackName: SWF_CALL_NAME_PREFIX + this._uid}} 62 | /> 63 | ); 64 | } 65 | } 66 | ``` 67 | 68 | ## ReactSWFCompat 69 | 70 | ReactSWFCompat (`require('react-swf/compat')`) also supports IE8-9, but should only be used if you must support these browsers. Internally it uses `ReactDOMServer.renderToString` to render to markup and then immediately `ReactDOM.render` on-top of that. There may be some behavioral differences in edge-cases but overall it should behave just the same. Due to the design of React you are required to provide a container element, the SWF-markup will be rendered inside. 71 | 72 | ```jsx 73 | } 75 | src="example.swf" 76 | id="guid_001" 77 | width="300" 78 | height="200" 79 | wmode="transparent" 80 | flashVars={{foo: 'A', bar: 1}} 81 | /> 82 | ``` 83 | 84 | ## Breaking changes 85 | 86 | #### 1.0.0 87 | 88 | * IE8-9 is no longer supported due to issues with the new DOM renderer in React 15. `ReactSWFCompat` has been introduced as a workaround to this. 89 | 90 | #### 0.13.0 91 | 92 | * `getFPVersion` and `isFPVersionSupported` forked to [SWFPlayerVersion](https://github.com/syranide/swf-player-version) and dropped from ReactSWF. Replace `ReactSWF.getFPVersion => SWFPlayerVersion.get` and `ReactSWF.isFPVersionSupported => SWFPlayerVersion.isSupported`. 93 | 94 | #### 0.12.3 95 | 96 | * Depends on `Object.assign()`, [polyfills are available](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill). 97 | 98 | #### 0.11.0 99 | 100 | * React 0.13 components no longer support `ref.getDOMNode()`, use `ref.getFPDOMNode()` instead. 101 | * Depends on `Object.is()`, [polyfills are available](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill_for_non-ES6_browsers). 102 | 103 | ## Properties 104 | 105 | Standard DOM properties are forwarded to the underlying ``. 106 | 107 | Changes to props cannot be and are not reflected by an already mounted SWF (except for `width` and `height`). You must manually provide a computed `key` to ensure the component is reset when appropriate. Beware, this also applies to `src`. 108 | 109 | ``` 110 | src {string} [required] 111 | width {number} 112 | height {number} 113 | ``` 114 | ``` 115 | flashVars {object|string} - {key: {string}}, "key=value&..." 116 | ``` 117 | ``` 118 | allowFullScreen {boolean} - true, false* 119 | allowFullScreenInteractive {boolean} - true, false* 120 | allowNetworking {enum} - all*, internal, none 121 | allowScriptAccess {enum} - always, sameDomain*, never 122 | ``` 123 | ``` 124 | align {enum} - l, t, r 125 | base {string} 126 | bgcolor {string} - #RRGGBB 127 | browserZoom {enum} - scale*, noscale 128 | fullScreenAspectRatio {enum} - portrait, landscape 129 | loop {boolean} - true*, false 130 | menu {boolean} - true*, false 131 | play {boolean} - true*, false 132 | quality {enum} - low, autolow, autohigh, medium, high, best 133 | salign {enum} - l, t, r, tl, tr 134 | scale {enum} - default*, noborder, exactfit, noscale 135 | seamlessTabbing {boolean} - true*, false 136 | wmode {enum} - window*, direct, opaque, transparent, gpu 137 | ``` 138 | 139 | Detailed explanation of most properties found at [[Flash OBJECT and EMBED tag attributes]](http://helpx.adobe.com/flash/kb/flash-object-embed-tag-attributes.html). 140 | 141 | ## API 142 | 143 | #### Instance methods 144 | 145 | ``` 146 | getFPDOMNode() 147 | returns {?DOMNode} Flash Player object DOM node. 148 | 149 | Returns the Flash Player object DOM node. 150 | Should be prefered over `React.findDOMNode`. 151 | ``` 152 | 153 | ## AS3 ExternalInterface 154 | 155 | #### Security flaws 156 | ``` 157 | Escape object key characters for FP: 158 | "&" => "&" 159 | "<" => "<" 160 | "\"" => """ 161 | 162 | Escape object key characters for JS: 163 | "\r" => "\\r" 164 | "\"" => "\\\"" 165 | + wrap key string with "\"" 166 | identifiers with keyword names must also be quoted for JS 167 | 168 | Escape string characters for JS: 169 | 0x005C => "\\\\" (Backslash) 170 | 0x2028 => "\\u2028" (Line separator) 171 | 0x2029 => "\\u2029" (Paragraph separator) 172 | 173 | Invalid UTF8 characters for FP and JS: 174 | 0x0000 (NULL character) 175 | 0xD800-0xDFFF (Non private use surrogates) 176 | 0xFDD0-0xFDEF (Non-characters) 177 | 0xFFFE-0xFFFF (Non-characters) 178 | remove or replace with "\uFFFD" (replacement character) 179 | can only be produced by String.fromCharCode(c) in FP, not "\uXXXX" (exception: 0x0000) 180 | ``` 181 | 182 | This list *may* be incomplete. 183 | 184 | #### ExternalInterface.addCallback 185 | 186 | Returned strings should be encoded using `StringForJS.encode`. 187 | 188 | You must provide a unique DOM `id` to `ReactSWF` for IE8-10. 189 | 190 | ``` 191 | 192 | ``` 193 | 194 | #### ExternalInterface.call 195 | 196 | String arguments should be encoded using `StringForJS.encode`. 197 | 198 | #### StringForJS.encode 199 | 200 | The Flash run-time does not sufficiently encode strings passed to JavaScript. This can cause run-time errors, string corruption or character substitution to occur. Encoded strings are transparently decoded by the JavaScript run-time. 201 | 202 | ```as3 203 | public class StringForJS { 204 | private static var UNSAFE_CHARS_REGEX:RegExp = new RegExp( 205 | // NULL-char (0x00) and backslash (0x5C) 206 | "[\\x00\\\\" + 207 | // Line separator (0x2028), paragraph separator (0x2029) 208 | "\u2028-\u2029" + 209 | // Non private use surrogates (0xD800 - 0xDFFF) 210 | String.fromCharCode(0xD800) + "-" + String.fromCharCode(0xDFFF) + 211 | // Non-characters (0xFDD0 - 0xFDEF) 212 | String.fromCharCode(0xFDD0) + "-" + String.fromCharCode(0xFDEF) + 213 | // Non-characters (0xFFFE + 0xFFFF) 214 | String.fromCharCode(0xFFFE) + String.fromCharCode(0xFFFF) + "]", 215 | "g" 216 | ); 217 | 218 | private static function unsafeCharEscaper():String { 219 | switch (arguments[0]) { 220 | case "\u0000": return "\\0"; 221 | case "\u005C": return "\\\\"; 222 | case "\u2028": return "\\u2028"; 223 | case "\u2029": return "\\u2029"; 224 | default: return "\uFFFD"; 225 | }; 226 | } 227 | 228 | // Encode unsafe strings for use with ExternalInterface. Invalid characters 229 | // are substituted by the Unicode replacement character. 230 | public static function encode(value:String):String { 231 | return value.replace(UNSAFE_CHARS_REGEX, unsafeCharEscaper); 232 | } 233 | } 234 | ``` 235 | -------------------------------------------------------------------------------- /npm-react-swf/compat.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | 3 | 'use strict'; 4 | 5 | var PropTypes = require('prop-types'); 6 | var React = require('react'); 7 | var ReactDOM = require('react-dom'); 8 | var ReactDOMServer = require('react-dom/server'); 9 | var ReactSWF = require('react-swf'); 10 | 11 | function ReactSWFCompat(props) { 12 | React.Component.call(this, props); 13 | 14 | var that = this; 15 | this._containerRefCallback = function(c) { 16 | that._container = c; 17 | }; 18 | this._swfRefCallback = function(c) { 19 | that._swf = c; 20 | }; 21 | } 22 | 23 | ReactSWFCompat.prototype = Object.create(React.Component.prototype); 24 | ReactSWFCompat.prototype.constructor = ReactSWFCompat; 25 | Object.assign(ReactSWFCompat, React.Component); 26 | 27 | ReactSWFCompat.propTypes = { 28 | container: PropTypes.element.isRequired 29 | }; 30 | 31 | ReactSWFCompat.prototype._createSWFElement = function() { 32 | var props = Object.assign({}, this.props); 33 | delete props.container; 34 | props.movie = props.src; 35 | props.ref = this._swfRefCallback; 36 | 37 | return React.createElement(ReactSWF, props); 38 | }; 39 | 40 | ReactSWFCompat.prototype.getFPDOMNode = function() { 41 | return this._swf.getFPDOMNode(); 42 | }; 43 | 44 | ReactSWFCompat.prototype.componentDidMount = function() { 45 | var swfElement = this._createSWFElement(); 46 | this._container.innerHTML = ReactDOMServer.renderToString(swfElement); 47 | ReactDOM.render(swfElement, this._container); 48 | }; 49 | 50 | ReactSWFCompat.prototype.componentDidUpdate = function() { 51 | var swfElement = this._createSWFElement(); 52 | ReactDOM.render(swfElement, this._container); 53 | }; 54 | 55 | ReactSWFCompat.prototype.componentWillUnmount = function() { 56 | // IE8 leaks nodes if AS3 `ExternalInterface.addCallback`-functions remain. 57 | if (document.documentMode < 9) { 58 | var node = this.getFPDOMNode(); 59 | 60 | // Node-methods are not enumerable in IE8, but properties are. 61 | for (var key in node) { 62 | if (typeof node[key] === 'function') { 63 | node[key] = null; 64 | } 65 | } 66 | } 67 | }; 68 | 69 | ReactSWFCompat.prototype.render = function() { 70 | var containerProps = { 71 | ref: this._containerRefCallback 72 | }; 73 | 74 | return React.cloneElement(this.props.container, containerProps, null); 75 | }; 76 | 77 | module.exports = ReactSWFCompat; 78 | -------------------------------------------------------------------------------- /npm-react-swf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-swf", 3 | "version": "1.0.7", 4 | "license": "MIT", 5 | "description": "Shockwave Flash Player component for React", 6 | "author": "Andreas Svensson ", 7 | "homepage": "https://github.com/syranide/react-swf", 8 | "bugs": "https://github.com/syranide/react-swf/issues", 9 | "main": "react-swf.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/syranide/react-swf" 13 | }, 14 | "peerDependencies": { 15 | "react": "^15.0.0-0 || ^16.0.0-0", 16 | "prop-types": "^15.0.0-0" 17 | }, 18 | "keywords": [ 19 | "react", 20 | "react-component", 21 | "component", 22 | "swf", 23 | "shockwave", 24 | "flash", 25 | "player", 26 | "object", 27 | "embed" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /npm-react-swf/react-swf.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | 3 | 'use strict'; 4 | 5 | var PropTypes = require('prop-types'); 6 | var React = require('react'); 7 | 8 | /* 9 | flashVars = {key: string} or "key=value&..." 10 | 11 | allowFullScreen = true, false* 12 | allowFullScreenInteractive = true, false* 13 | allowNetworking = all*, internal, none 14 | allowScriptAccess = always, sameDomain, never 15 | 16 | align = l, t, r 17 | base = url 18 | bgcolor = #RRGGBB 19 | browserZoom = scale*, noscale 20 | fullScreenAspectRatio = portrait, landscape 21 | loop = true*, false 22 | menu = true*, false 23 | play = true*, false 24 | quality = low, autolow, autohigh, medium, high, best 25 | salign = l, t, r, tl, tr 26 | scale = default*, noborder, exactfit, noscale 27 | seamlessTabbing = true*, false 28 | wmode = window*, direct, opaque, transparent, gpu 29 | */ 30 | 31 | var supportedFPParamNames = { 32 | movie: 'movie', // react-swf/compat for IE8 33 | 34 | flashVars: 'flashvars', 35 | 36 | allowFullScreen: 'allowfullscreen', 37 | allowFullScreenInteractive: 'allowfullscreeninteractive', 38 | allowNetworking: 'allownetworking', 39 | allowScriptAccess: 'allowscriptaccess', 40 | 41 | align: 'align', 42 | base: 'base', 43 | bgcolor: 'bgcolor', 44 | browserZoom: 'browserzoom', 45 | fullScreenAspectRatio: 'fullscreenaspectratio', 46 | loop: 'loop', 47 | menu: 'menu', 48 | play: 'play', 49 | quality: 'quality', 50 | salign: 'salign', 51 | scale: 'scale', 52 | seamlessTabbing: 'seamlesstabbing', 53 | wmode: 'wmode' 54 | }; 55 | 56 | var booleanFPParams = { 57 | allowFullScreen: true, 58 | allowFullScreenInteractive: true, 59 | loop: true, 60 | menu: true, 61 | play: true, 62 | seamlessTabbing: true 63 | }; 64 | 65 | 66 | var ENCODE_FLASH_VARS_REGEX = /[\r%&+=]/g; 67 | var ENCODE_FLASH_VARS_LOOKUP = { 68 | '\r': '%0D', 69 | '%': '%25', 70 | '&': '%26', 71 | '+': '%2B', 72 | '=': '%3D' 73 | }; 74 | 75 | function encodeFlashVarsStringReplacer(match) { 76 | return ENCODE_FLASH_VARS_LOOKUP[match]; 77 | } 78 | 79 | function encodeFlashVarsString(string) { 80 | return ('' + string).replace( 81 | ENCODE_FLASH_VARS_REGEX, 82 | encodeFlashVarsStringReplacer 83 | ); 84 | } 85 | 86 | function encodeFlashVarsObject(object) { 87 | // Push to array; faster and scales better than string concat. 88 | var output = []; 89 | 90 | for (var key in object) { 91 | if (object.hasOwnProperty(key)) { 92 | var value = object[key]; 93 | 94 | if (value != null) { 95 | output.push( 96 | encodeFlashVarsString(key) + '=' + encodeFlashVarsString(value) 97 | ); 98 | } 99 | } 100 | } 101 | 102 | return output.join('&'); 103 | } 104 | 105 | 106 | /** @constructor */ 107 | function ReactSWF(props) { 108 | React.Component.call(this, props); 109 | 110 | var that = this; 111 | this._refCallback = function(c) { 112 | that._node = c; 113 | }; 114 | 115 | // The only way to change Flash parameters or reload the movie is to update 116 | // the key of the ReactSWF element. This unmounts the previous instance and 117 | // reloads the movie. Store initial values to keep the DOM consistent. 118 | 119 | var params = {}; 120 | 121 | for (var key in supportedFPParamNames) { 122 | if (supportedFPParamNames.hasOwnProperty(key) && 123 | props.hasOwnProperty(key)) { 124 | var value = props[key]; 125 | 126 | if (value != null) { 127 | var name = supportedFPParamNames[key]; 128 | 129 | if (name === 'flashvars' && typeof value === 'object') { 130 | value = encodeFlashVarsObject(value); 131 | } else if (booleanFPParams.hasOwnProperty(key)) { 132 | // Force boolean parameter arguments to be boolean. 133 | value = !!value; 134 | } 135 | 136 | params[name] = '' + value; 137 | } 138 | } 139 | } 140 | 141 | this._node = null; 142 | this.state = { 143 | src: props.src, 144 | params: params 145 | }; 146 | } 147 | 148 | ReactSWF.prototype = Object.create(React.Component.prototype); 149 | ReactSWF.prototype.constructor = ReactSWF; 150 | Object.assign(ReactSWF, React.Component); 151 | 152 | ReactSWF.propTypes = { 153 | src: PropTypes.string.isRequired, 154 | movie: PropTypes.string, // react-swf/compat for IE8 155 | 156 | flashVars: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), 157 | 158 | allowFullScreen: PropTypes.bool, 159 | allowFullScreenInteractive: PropTypes.bool, 160 | allowNetworking: PropTypes.oneOf(['all', 'internal', 'none']), 161 | allowScriptAccess: PropTypes.oneOf(['always', 'sameDomain', 'never']), 162 | 163 | align: PropTypes.oneOf(['l', 't', 'r']), 164 | base: PropTypes.string, 165 | bgcolor: PropTypes.string, 166 | browserZoom: PropTypes.oneOf(['scale', 'noscale']), 167 | fullScreenAspectRatio: PropTypes.oneOf(['portrait', 'landscape']), 168 | loop: PropTypes.bool, 169 | menu: PropTypes.bool, 170 | play: PropTypes.bool, 171 | quality: PropTypes.oneOf(['low', 'autolow', 'autohigh', 'medium', 'high', 'best']), 172 | salign: PropTypes.oneOf(['l', 't', 'r', 'tl', 'tr']), 173 | scale: PropTypes.oneOf(['default', 'noborder', 'exactfit', 'noscale']), 174 | seamlessTabbing: PropTypes.bool, 175 | wmode: PropTypes.oneOf(['window', 'direct', 'opaque', 'transparent', 'gpu']) 176 | }; 177 | 178 | ReactSWF.prototype.getFPDOMNode = function() { 179 | return this._node; 180 | }; 181 | 182 | ReactSWF.prototype.shouldComponentUpdate = function(nextProps) { 183 | var prevProps = this.props; 184 | 185 | for (var key in prevProps) { 186 | // Ignore all Flash parameter props 187 | if (prevProps.hasOwnProperty(key) && 188 | !supportedFPParamNames.hasOwnProperty(key) && 189 | (!nextProps.hasOwnProperty(key) || 190 | !Object.is(prevProps[key], nextProps[key]))) { 191 | return true; 192 | } 193 | } 194 | 195 | for (var key in nextProps) { 196 | if (nextProps.hasOwnProperty(key) && 197 | !supportedFPParamNames.hasOwnProperty(key) && 198 | !prevProps.hasOwnProperty(key)) { 199 | return true; 200 | } 201 | } 202 | 203 | return false; 204 | }; 205 | 206 | ReactSWF.prototype.render = function() { 207 | var props = this.props; 208 | var state = this.state; 209 | 210 | // AS3 `ExternalInterface.addCallback` requires a unique node ID in IE8-10. 211 | // There is however no isolated way to play nice with server-rendering, so 212 | // we must leave it up to the user. 213 | 214 | var objectProps = { 215 | ref: this._refCallback, 216 | children: [], 217 | type: 'application/x-shockwave-flash', 218 | data: state.src, 219 | // Discard `props.src` 220 | src: null 221 | }; 222 | 223 | for (var key in props) { 224 | // Ignore props that are Flash parameters or managed by this component. 225 | if (props.hasOwnProperty(key) && 226 | !supportedFPParamNames.hasOwnProperty(key) && 227 | !objectProps.hasOwnProperty(key)) { 228 | objectProps[key] = props[key]; 229 | } 230 | } 231 | 232 | var objectChildren = objectProps.children; 233 | 234 | for (var name in state.params) { 235 | objectChildren.push( 236 | React.createElement('param', { 237 | key: name, 238 | name: name, 239 | value: state.params[name] 240 | }) 241 | ); 242 | } 243 | 244 | // Push `props.children` to the end of the children, React will generate a 245 | // key warning if there are multiple children. This is preferable for now. 246 | if (props.children != null) { 247 | objectChildren.push(props.children); 248 | } 249 | 250 | return React.createElement('object', objectProps); 251 | }; 252 | 253 | module.exports = ReactSWF; 254 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-swf", 3 | "version": "1.0.7", 4 | "license": "MIT", 5 | "description": "Shockwave Flash Player component for React", 6 | "author": "Andreas Svensson ", 7 | "homepage": "https://github.com/syranide/react-swf", 8 | "bugs": "https://github.com/syranide/react-swf/issues", 9 | "main": "react-swf.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/syranide/react-swf" 13 | }, 14 | "peerDependencies": { 15 | "react": "^15.0.0-0 || ^16.0.0-0", 16 | "prop-types": "^15.0.0-0" 17 | }, 18 | "keywords": [ 19 | "react", 20 | "react-component", 21 | "component", 22 | "swf", 23 | "shockwave", 24 | "flash", 25 | "player", 26 | "object", 27 | "embed" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /react-swf-compat.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | 3 | (function(root, factory) { 4 | if (typeof define === 'function' && define.amd) { 5 | define(['prop-types', 'react', 'react-dom', 'react-dom/server', 'react-swf'], factory); 6 | } else if (typeof exports === 'object') { 7 | module.exports = factory(require('prop-types'), require('react'), require('react-dom'), require('react-dom/server'), require('react-swf')); 8 | } else { 9 | root.ReactSWFCompat = factory(root.PropTypes, root.React, root.ReactDOM, root.ReactDOMServer, root.ReactSWF); 10 | } 11 | }(this, function(PropTypes, React, ReactDOM, ReactDOMServer, ReactSWF) { 12 | 'use strict'; 13 | 14 | function ReactSWFCompat(props) { 15 | React.Component.call(this, props); 16 | 17 | var that = this; 18 | this._containerRefCallback = function(c) { 19 | that._container = c; 20 | }; 21 | this._swfRefCallback = function(c) { 22 | that._swf = c; 23 | }; 24 | } 25 | 26 | ReactSWFCompat.prototype = Object.create(React.Component.prototype); 27 | ReactSWFCompat.prototype.constructor = ReactSWFCompat; 28 | Object.assign(ReactSWFCompat, React.Component); 29 | 30 | ReactSWFCompat.propTypes = { 31 | container: PropTypes.element.isRequired 32 | }; 33 | 34 | ReactSWFCompat.prototype._createSWFElement = function() { 35 | var props = Object.assign({}, this.props); 36 | delete props.container; 37 | props.movie = props.src; 38 | props.ref = this._swfRefCallback; 39 | 40 | return React.createElement(ReactSWF, props); 41 | }; 42 | 43 | ReactSWFCompat.prototype.getFPDOMNode = function() { 44 | return this._swf.getFPDOMNode(); 45 | }; 46 | 47 | ReactSWFCompat.prototype.componentDidMount = function() { 48 | var swfElement = this._createSWFElement(); 49 | this._container.innerHTML = ReactDOMServer.renderToString(swfElement); 50 | ReactDOM.render(swfElement, this._container); 51 | }; 52 | 53 | ReactSWFCompat.prototype.componentDidUpdate = function() { 54 | var swfElement = this._createSWFElement(); 55 | ReactDOM.render(swfElement, this._container); 56 | }; 57 | 58 | ReactSWFCompat.prototype.componentWillUnmount = function() { 59 | // IE8 leaks nodes if AS3 `ExternalInterface.addCallback`-functions remain. 60 | if (document.documentMode < 9) { 61 | var node = this.getFPDOMNode(); 62 | 63 | // Node-methods are not enumerable in IE8, but properties are. 64 | for (var key in node) { 65 | if (typeof node[key] === 'function') { 66 | node[key] = null; 67 | } 68 | } 69 | } 70 | }; 71 | 72 | ReactSWFCompat.prototype.render = function() { 73 | var containerProps = { 74 | ref: this._containerRefCallback 75 | }; 76 | 77 | return React.cloneElement(this.props.container, containerProps, null); 78 | }; 79 | 80 | return ReactSWFCompat; 81 | })); 82 | -------------------------------------------------------------------------------- /react-swf-compat.min.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | !function(e,t){"function"==typeof define&&define.amd?define(["prop-types","react","react-dom","react-dom/server","react-swf"],t):"object"==typeof exports?module.exports=t(require("prop-types"),require("react"),require("react-dom"),require("react-dom/server"),require("react-swf")):e.ReactSWFCompat=t(e.PropTypes,e.React,e.ReactDOM,e.ReactDOMServer,e.ReactSWF)}(this,function(e,t,n,r,o){"use strict";function c(e){t.Component.call(this,e);var n=this;this._containerRefCallback=function(e){n._container=e},this._swfRefCallback=function(e){n._swf=e}}return c.prototype=Object.create(t.Component.prototype),c.prototype.constructor=c,Object.assign(c,t.Component),c.propTypes={container:e.element.isRequired},c.prototype._createSWFElement=function(){var e=Object.assign({},this.props);return delete e.container,e.movie=e.src,e.ref=this._swfRefCallback,t.createElement(o,e)},c.prototype.getFPDOMNode=function(){return this._swf.getFPDOMNode()},c.prototype.componentDidMount=function(){var e=this._createSWFElement();this._container.innerHTML=r.renderToString(e),n.render(e,this._container)},c.prototype.componentDidUpdate=function(){var e=this._createSWFElement();n.render(e,this._container)},c.prototype.componentWillUnmount=function(){if(document.documentMode<9){var e=this.getFPDOMNode();for(var t in e)"function"==typeof e[t]&&(e[t]=null)}},c.prototype.render=function(){var e={ref:this._containerRefCallback};return t.cloneElement(this.props.container,e,null)},c}); 3 | -------------------------------------------------------------------------------- /react-swf.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | 3 | (function(root, factory) { 4 | if (typeof define === 'function' && define.amd) { 5 | define(['prop-types', 'react'], factory); 6 | } else if (typeof exports === 'object') { 7 | module.exports = factory(require('prop-types'), require('react')); 8 | } else { 9 | root.ReactSWF = factory(root.PropTypes, root.React); 10 | } 11 | }(this, function(PropTypes, React) { 12 | 'use strict'; 13 | 14 | /* 15 | flashVars = {key: string} or "key=value&..." 16 | 17 | allowFullScreen = true, false* 18 | allowFullScreenInteractive = true, false* 19 | allowNetworking = all*, internal, none 20 | allowScriptAccess = always, sameDomain, never 21 | 22 | align = l, t, r 23 | base = url 24 | bgcolor = #RRGGBB 25 | browserZoom = scale*, noscale 26 | fullScreenAspectRatio = portrait, landscape 27 | loop = true*, false 28 | menu = true*, false 29 | play = true*, false 30 | quality = low, autolow, autohigh, medium, high, best 31 | salign = l, t, r, tl, tr 32 | scale = default*, noborder, exactfit, noscale 33 | seamlessTabbing = true*, false 34 | wmode = window*, direct, opaque, transparent, gpu 35 | */ 36 | 37 | var supportedFPParamNames = { 38 | flashVars: 'flashvars', 39 | 40 | allowFullScreen: 'allowfullscreen', 41 | allowFullScreenInteractive: 'allowfullscreeninteractive', 42 | allowNetworking: 'allownetworking', 43 | allowScriptAccess: 'allowscriptaccess', 44 | 45 | align: 'align', 46 | base: 'base', 47 | bgcolor: 'bgcolor', 48 | browserZoom: 'browserzoom', 49 | fullScreenAspectRatio: 'fullscreenaspectratio', 50 | loop: 'loop', 51 | menu: 'menu', 52 | play: 'play', 53 | quality: 'quality', 54 | salign: 'salign', 55 | scale: 'scale', 56 | seamlessTabbing: 'seamlesstabbing', 57 | wmode: 'wmode' 58 | }; 59 | 60 | var booleanFPParams = { 61 | allowFullScreen: true, 62 | allowFullScreenInteractive: true, 63 | loop: true, 64 | menu: true, 65 | play: true, 66 | seamlessTabbing: true 67 | }; 68 | 69 | 70 | var ENCODE_FLASH_VARS_REGEX = /[\r%&+=]/g; 71 | var ENCODE_FLASH_VARS_LOOKUP = { 72 | '\r': '%0D', 73 | '%': '%25', 74 | '&': '%26', 75 | '+': '%2B', 76 | '=': '%3D' 77 | }; 78 | 79 | function encodeFlashVarsStringReplacer(match) { 80 | return ENCODE_FLASH_VARS_LOOKUP[match]; 81 | } 82 | 83 | function encodeFlashVarsString(string) { 84 | return ('' + string).replace( 85 | ENCODE_FLASH_VARS_REGEX, 86 | encodeFlashVarsStringReplacer 87 | ); 88 | } 89 | 90 | function encodeFlashVarsObject(object) { 91 | // Push to array; faster and scales better than string concat. 92 | var output = []; 93 | 94 | for (var key in object) { 95 | if (object.hasOwnProperty(key)) { 96 | var value = object[key]; 97 | 98 | if (value != null) { 99 | output.push( 100 | encodeFlashVarsString(key) + '=' + encodeFlashVarsString(value) 101 | ); 102 | } 103 | } 104 | } 105 | 106 | return output.join('&'); 107 | } 108 | 109 | 110 | /** @constructor */ 111 | function ReactSWF(props) { 112 | React.Component.call(this, props); 113 | 114 | var that = this; 115 | this._refCallback = function(c) { 116 | that._node = c; 117 | }; 118 | 119 | // The only way to change Flash parameters or reload the movie is to update 120 | // the key of the ReactSWF element. This unmounts the previous instance and 121 | // reloads the movie. Store initial values to keep the DOM consistent. 122 | 123 | var params = {}; 124 | 125 | for (var key in supportedFPParamNames) { 126 | if (supportedFPParamNames.hasOwnProperty(key) && 127 | props.hasOwnProperty(key)) { 128 | var value = props[key]; 129 | 130 | if (value != null) { 131 | var name = supportedFPParamNames[key]; 132 | 133 | if (name === 'flashvars' && typeof value === 'object') { 134 | value = encodeFlashVarsObject(value); 135 | } else if (booleanFPParams.hasOwnProperty(key)) { 136 | // Force boolean parameter arguments to be boolean. 137 | value = !!value; 138 | } 139 | 140 | params[name] = '' + value; 141 | } 142 | } 143 | } 144 | 145 | this._node = null; 146 | this.state = { 147 | src: props.src, 148 | params: params 149 | }; 150 | } 151 | 152 | ReactSWF.prototype = Object.create(React.Component.prototype); 153 | ReactSWF.prototype.constructor = ReactSWF; 154 | Object.assign(ReactSWF, React.Component); 155 | 156 | ReactSWF.propTypes = { 157 | src: PropTypes.string.isRequired, 158 | 159 | flashVars: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), 160 | 161 | allowFullScreen: PropTypes.bool, 162 | allowFullScreenInteractive: PropTypes.bool, 163 | allowNetworking: PropTypes.oneOf(['all', 'internal', 'none']), 164 | allowScriptAccess: PropTypes.oneOf(['always', 'sameDomain', 'never']), 165 | 166 | align: PropTypes.oneOf(['l', 't', 'r']), 167 | base: PropTypes.string, 168 | bgcolor: PropTypes.string, 169 | browserZoom: PropTypes.oneOf(['scale', 'noscale']), 170 | fullScreenAspectRatio: PropTypes.oneOf(['portrait', 'landscape']), 171 | loop: PropTypes.bool, 172 | menu: PropTypes.bool, 173 | play: PropTypes.bool, 174 | quality: PropTypes.oneOf(['low', 'autolow', 'autohigh', 'medium', 'high', 'best']), 175 | salign: PropTypes.oneOf(['l', 't', 'r', 'tl', 'tr']), 176 | scale: PropTypes.oneOf(['default', 'noborder', 'exactfit', 'noscale']), 177 | seamlessTabbing: PropTypes.bool, 178 | wmode: PropTypes.oneOf(['window', 'direct', 'opaque', 'transparent', 'gpu']) 179 | }; 180 | 181 | ReactSWF.prototype.getFPDOMNode = function() { 182 | return this._node; 183 | }; 184 | 185 | ReactSWF.prototype.shouldComponentUpdate = function(nextProps) { 186 | var prevProps = this.props; 187 | 188 | for (var key in prevProps) { 189 | // Ignore all Flash parameter props 190 | if (prevProps.hasOwnProperty(key) && 191 | !supportedFPParamNames.hasOwnProperty(key) && 192 | (!nextProps.hasOwnProperty(key) || 193 | !Object.is(prevProps[key], nextProps[key]))) { 194 | return true; 195 | } 196 | } 197 | 198 | for (var key in nextProps) { 199 | if (nextProps.hasOwnProperty(key) && 200 | !supportedFPParamNames.hasOwnProperty(key) && 201 | !prevProps.hasOwnProperty(key)) { 202 | return true; 203 | } 204 | } 205 | 206 | return false; 207 | }; 208 | 209 | ReactSWF.prototype.render = function() { 210 | var props = this.props; 211 | var state = this.state; 212 | 213 | // AS3 `ExternalInterface.addCallback` requires a unique node ID in IE8-10. 214 | // There is however no isolated way to play nice with server-rendering, so 215 | // we must leave it up to the user. 216 | 217 | var objectProps = { 218 | ref: this._refCallback, 219 | children: [], 220 | type: 'application/x-shockwave-flash', 221 | data: state.src, 222 | // Discard `props.src` 223 | src: null 224 | }; 225 | 226 | for (var key in props) { 227 | // Ignore props that are Flash parameters or managed by this component. 228 | if (props.hasOwnProperty(key) && 229 | !supportedFPParamNames.hasOwnProperty(key) && 230 | !objectProps.hasOwnProperty(key)) { 231 | objectProps[key] = props[key]; 232 | } 233 | } 234 | 235 | var objectChildren = objectProps.children; 236 | 237 | for (var name in state.params) { 238 | objectChildren.push( 239 | React.createElement('param', { 240 | key: name, 241 | name: name, 242 | value: state.params[name] 243 | }) 244 | ); 245 | } 246 | 247 | // Push `props.children` to the end of the children, React will generate a 248 | // key warning if there are multiple children. This is preferable for now. 249 | if (props.children != null) { 250 | objectChildren.push(props.children); 251 | } 252 | 253 | return React.createElement('object', objectProps); 254 | }; 255 | 256 | return ReactSWF; 257 | })); 258 | -------------------------------------------------------------------------------- /react-swf.min.js: -------------------------------------------------------------------------------- 1 | /*! react-swf v1.0.7 | @syranide | MIT license */ 2 | !function(e,r){"function"==typeof define&&define.amd?define(["prop-types","react"],r):"object"==typeof exports?module.exports=r(require("prop-types"),require("react")):e.ReactSWF=r(e.PropTypes,e.React)}(this,function(e,r){"use strict";function o(e){return c[e]}function n(e){return(""+e).replace(i,o)}function a(e){var r=[];for(var o in e)if(e.hasOwnProperty(o)){var a=e[o];null!=a&&r.push(n(o)+"="+n(a))}return r.join("&")}function t(e){r.Component.call(this,e);var o=this;this._refCallback=function(e){o._node=e};var n={};for(var t in l)if(l.hasOwnProperty(t)&&e.hasOwnProperty(t)){var i=e[t];if(null!=i){var c=l[t];"flashvars"===c&&"object"==typeof i?i=a(i):s.hasOwnProperty(t)&&(i=!!i),n[c]=""+i}}this._node=null,this.state={src:e.src,params:n}}var l={flashVars:"flashvars",allowFullScreen:"allowfullscreen",allowFullScreenInteractive:"allowfullscreeninteractive",allowNetworking:"allownetworking",allowScriptAccess:"allowscriptaccess",align:"align",base:"base",bgcolor:"bgcolor",browserZoom:"browserzoom",fullScreenAspectRatio:"fullscreenaspectratio",loop:"loop",menu:"menu",play:"play",quality:"quality",salign:"salign",scale:"scale",seamlessTabbing:"seamlesstabbing",wmode:"wmode"},s={allowFullScreen:!0,allowFullScreenInteractive:!0,loop:!0,menu:!0,play:!0,seamlessTabbing:!0},i=/[\r%&+=]/g,c={"\r":"%0D","%":"%25","&":"%26","+":"%2B","=":"%3D"};return t.prototype=Object.create(r.Component.prototype),t.prototype.constructor=t,Object.assign(t,r.Component),t.propTypes={src:e.string.isRequired,flashVars:e.oneOfType([e.object,e.string]),allowFullScreen:e.bool,allowFullScreenInteractive:e.bool,allowNetworking:e.oneOf(["all","internal","none"]),allowScriptAccess:e.oneOf(["always","sameDomain","never"]),align:e.oneOf(["l","t","r"]),base:e.string,bgcolor:e.string,browserZoom:e.oneOf(["scale","noscale"]),fullScreenAspectRatio:e.oneOf(["portrait","landscape"]),loop:e.bool,menu:e.bool,play:e.bool,quality:e.oneOf(["low","autolow","autohigh","medium","high","best"]),salign:e.oneOf(["l","t","r","tl","tr"]),scale:e.oneOf(["default","noborder","exactfit","noscale"]),seamlessTabbing:e.bool,wmode:e.oneOf(["window","direct","opaque","transparent","gpu"])},t.prototype.getFPDOMNode=function(){return this._node},t.prototype.shouldComponentUpdate=function(e){var r=this.props;for(var o in r)if(r.hasOwnProperty(o)&&!l.hasOwnProperty(o)&&(!e.hasOwnProperty(o)||!Object.is(r[o],e[o])))return!0;for(var o in e)if(e.hasOwnProperty(o)&&!l.hasOwnProperty(o)&&!r.hasOwnProperty(o))return!0;return!1},t.prototype.render=function(){var e=this.props,o=this.state,n={ref:this._refCallback,children:[],type:"application/x-shockwave-flash",data:o.src,src:null};for(var a in e)!e.hasOwnProperty(a)||l.hasOwnProperty(a)||n.hasOwnProperty(a)||(n[a]=e[a]);var t=n.children;for(var s in o.params)t.push(r.createElement("param",{key:s,name:s,value:o.params[s]}));return null!=e.children&&t.push(e.children),r.createElement("object",n)},t}); 3 | --------------------------------------------------------------------------------