13693261870
2022-09-16 354b3dbfbffb3df45212a2a44dbbf48b4acc2594
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='Ext-data-flash-BinaryXhr'>/**
</span> *
 * Simulates an XMLHttpRequest object's methods and properties as returned
 * form the flash polyfill plugin. Used in submitting binary data in browsers that do 
 * not support doing so from JavaScript.
 * NOTE: By default this will look for the flash object in the ext directory. When packaging and deploying the app, copy the &lt;tt&gt;ext/plugins&lt;/tt&gt; directory and its contents to your root directory. For custom deployments where just the &lt;tt&gt;FlashPlugin.swf&lt;/tt&gt; file gets copied (e.g. to &lt;tt&gt;/resources/FlashPlugin.swf&lt;/tt&gt;), make sure to notify the framework of the location of the plugin before making the first attempt to post binary data, e.g. in the &lt;tt&gt;launch&lt;/tt&gt; method of your app do:
 * &lt;pre&gt;&lt;code&gt;
Ext.flashPluginPath=&quot;/resources/FlashPlugin.swf&quot;;
 &lt;/code&gt;&lt;/pre&gt;
 *
 * @private
 */
Ext.define('Ext.data.flash.BinaryXhr', {
    
    statics: {
<span id='Ext-data-flash-BinaryXhr-method-flashPluginActivated'>        /**
</span>         * Called by the flash plugin once it's installed and open for business.
         * @private
         */
        flashPluginActivated: function() {
            Ext.data.flash.BinaryXhr.flashPluginActive = true;
            Ext.data.flash.BinaryXhr.flashPlugin = document.getElementById(&quot;ext-flash-polyfill&quot;);
            Ext.globalEvents.fireEvent(&quot;flashready&quot;); // let all pending connections know
        },
        
<span id='Ext-data-flash-BinaryXhr-property-flashPluginActive'>        /**
</span>         * Set to &lt;tt&gt;trut&lt;/tt&gt; once the plugin registers and is active.
         * @private
         */
        flashPluginActive: false,
        
<span id='Ext-data-flash-BinaryXhr-property-flashPluginInjected'>        /**
</span>         * Flag to avoid installing the plugin twice.
         * @private
         */
        flashPluginInjected: false,
        
<span id='Ext-data-flash-BinaryXhr-property-connectionIndex'>        /**
</span>         * Counts IDs for new connections.
         * @private
         */
        
        connectionIndex: 1,
        
<span id='Ext-data-flash-BinaryXhr-property-liveConnections'>        /**
</span>         * Plcaeholder for active connections.
         * @private
         */
        liveConnections: {},
        
<span id='Ext-data-flash-BinaryXhr-property-flashPlugin'>        /**
</span>         * Reference to the actual plugin, once activated.
         * @private
         */
        flashPlugin: null,
        
<span id='Ext-data-flash-BinaryXhr-method-onFlashStateChange'>        /**
</span>         * Called by the flash plugin once the state of one of the active connections changes.
         * @param {Number/number} javascriptId the ID of the connection.
         * @param {number} state the state of the connection. Equivalent to readyState numbers in XHR.
         * @param {Object} data optional object containing the returned data, error and status codes.
         * @private
         */
        onFlashStateChange: function(javascriptId, state, data) {
            var connection;
            // Identify the request this is for
            connection = this.liveConnections[Number(javascriptId)]; // Make sure its a native number
            if (connection) {
                connection.onFlashStateChange(state, data);
            } 
            //&lt;debug&gt;
            else {
                Ext.warn.log(&quot;onFlashStateChange for unknown connection ID: &quot; + javascriptId);
            }
            //&lt;/debug&gt;
        },
        
<span id='Ext-data-flash-BinaryXhr-method-registerConnection'>        /**
</span>         * Adds the BinaryXhr object to the tracked connection list and assigns it an ID
         * @param {Ext.data.flash.BinaryXhr} conn the connection to register
         * @return {Number} id
         * @private
         */
        registerConnection: function(conn) {
            var i = this.connectionIndex;
            this.conectionIndex = this.connectionIndex + 1;
            this.liveConnections[i] = conn;
            return i;
        },
        
<span id='Ext-data-flash-BinaryXhr-method-injectFlashPlugin'>        /**
</span>         * Injects the flash polyfill plugin to allow posting binary data.
         * This is done in two steps: First we load the javascript loader for flash objects, then we call it to inject the flash object.
         * @private
         */
        injectFlashPlugin: function() {
            var divTag, pTag, aTag, iTag,
                me=this,
                flashLoaderPath, flashObjectPath;
                // Generate the following HTML set of tags:
               // + '&lt;div id=&quot;ext-flash-polyfill&quot;&gt;'
               // + '&lt;p&gt;To view this page ensure that Adobe Flash Player version 11.1.0 or greater is installed, and that the FlashPlugin.swf file was correctly placed in the /resources directory.&lt;/p&gt;'
                //+ '&lt;a href=&quot;http://www.adobe.com/go/getflashplayer&quot;&gt;&lt;img src=&quot;' + window.location.protocol + '//www.adobe.com/images/shared/download_buttons/get_flash_player.gif&quot; alt=&quot;Get Adobe Flash player&quot; /&gt;&lt;/a&gt;'
                //+ '&lt;/div&gt;'
            
            iTag=document.createElement(&quot;img&quot;);
            iTag.setAttribute(&quot;src&quot;,  window.location.protocol + '//www.adobe.com/images/shared/download_buttons/get_flash_player.gif');
            iTag.setAttribute(&quot;alt&quot;, &quot;Get Adobe Flash player&quot;);
            
            aTag=document.createElement(&quot;a&quot;);
            aTag.setAttribute(&quot;href&quot;, &quot;http://www.adobe.com/go/getflashplayer&quot;);
            aTag.appendChild(iTag);
            
            pTag=document.createElement(&quot;p&quot;);
            pTag.innerHTML=&quot;To view this page ensure that Adobe Flash Player version 11.1.0 or greater is installed.&quot;;
            
            divTag=document.createElement(&quot;div&quot;);
            divTag.setAttribute(&quot;id&quot;, &quot;ext-flash-polyfill&quot;);
            divTag.appendChild(pTag);
            divTag.appendChild(iTag);
            
            Ext.getBody().dom.appendChild(divTag);
            
            
            
            // Now load the flash-loading script
            
            flashLoaderPath = [Ext.Loader.getPath('Ext.data.Connection'), '../../../plugins/flash/swfobject.js'].join('/');
            flashObjectPath = &quot;/plugins/flash/FlashPlugin.swf&quot;;
            //&lt;debug&gt;
            flashObjectPath = [Ext.Loader.getPath('Ext.data.Connection'), '../../plugins/flash/FlashPlugin.swf'].join('/');
            //&lt;/debug&gt;
            if (Ext.flashPluginPath) {
                flashObjectPath = Ext.flashPluginPath;
            }
            //console.log('LOADING Flash plugin from: ' + flashObjectPath);
            Ext.Loader.loadScript({
                url:flashLoaderPath,
                onLoad: function() {
                    // For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. 
                    var swfVersionStr = &quot;11.4.0&quot;;
                    // To use express install, set to playerProductInstall.swf, otherwise the empty string. 
                    var xiSwfUrlStr = &quot;playerProductInstall.swf&quot;;
                    var flashvars = {};
                    var params = {};
                    params.quality = &quot;high&quot;;
                    params.bgcolor = &quot;#ffffff&quot;;
                    params.allowscriptaccess = &quot;sameDomain&quot;;
                    params.allowfullscreen = &quot;true&quot;;
                    var attributes = {};
                    attributes.id = &quot;ext-flash-polyfill&quot;;
                    attributes.name = &quot;polyfill&quot;;
                    attributes.align = &quot;middle&quot;;
                    swfobject.embedSWF(
                        flashObjectPath, &quot;ext-flash-polyfill&quot;, 
                        &quot;0&quot;, &quot;0&quot;, // no size so it's not visible. 
                        swfVersionStr, xiSwfUrlStr, 
                        flashvars, params, attributes);
                },
                onError: function() {
                    //&lt;debug&gt;
                    Ext.Error.raise(&quot;Could not load flash-loader file swfobject.js from &quot; + flashLoader);
                    //&lt;/debug&gt;
                },
                scope: me
            });
            Ext.globalEvents.addEvents(&quot;flashready&quot;); // we'll fire this one once flash is loaded
            Ext.data.flash.BinaryXhr.flashPluginInjected = true;
        }
 
    
    },
    
<span id='Ext-data-flash-BinaryXhr-property-readyState'>    /**
</span>     * @property {number} readyState The connection's simulated readyState. Note that the only supported values are 0, 1 and 4. States 2 and 3 will never be reported.
     */
    readyState: 0,
    
<span id='Ext-data-flash-BinaryXhr-property-status'>    /**
</span>     * @property {number} status Connection status code returned by flash or the server.
     */
    status: 0,
    
    
<span id='Ext-data-flash-BinaryXhr-property-statusText'>    /**
</span>     * Status text (if any) returned by flash or the server.
     */
    statusText: &quot;&quot;,
    
<span id='Ext-data-flash-BinaryXhr-property-responseBytes'>    /**
</span>     * @property {Array} responseBytes The binary bytes returned.
     */
    responseBytes: null,
    
<span id='Ext-data-flash-BinaryXhr-property-javascriptId'>    /**
</span>     * An ID representing this connection with flash.
     * @private
     */
    javascriptId: null,
    
    
<span id='Ext-data-flash-BinaryXhr-method-constructor'>    /**
</span>     * Creates a new instance of BinaryXhr.
     */
    constructor: function (config) {
        // first, make sure flash is loading if needed
        if (!Ext.data.flash.BinaryXhr.flashPluginInjected) {
            Ext.data.flash.BinaryXhr.injectFlashPlugin();
        }
        var me = this;
 
        Ext.apply(me, config);
        me.requestHeaders = {};
    },
 
<span id='Ext-data-flash-BinaryXhr-method-abort'>    /**
</span>     * Abort this connection. Sets its readyState to 4.
     */
    abort: function () {
        var me = this;
        // if complete, nothing to abort 
        if (me.readyState == 4) {
            //&lt;debug&gt;
            Ext.warn.log(&quot;Aborting a connection that's completed its transfer: &quot; + this.url);
            //&lt;/debug&gt;
            return;
        }
        // Mark as aborted
        me.aborted = true;
        // Remove ourselves from the listeners if flash isn't active yet
        if (!Ext.data.flash.BinaryXhr.flashPluginActive) {
            Ext.globalEvents.removeListener(&quot;flashready&quot;, me.onFlashReady, me);
            return;
        }
        // Flash is already live, so we should have a javascriptID and should have called flash to get the request going. Cancel:
        Ext.data.flash.BinaryXhr.flashPlugin.abortRequest(me.javascriptId);
        // remove from list
        delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];
    },
 
<span id='Ext-data-flash-BinaryXhr-method-getAllResponseHeaders'>    /**
</span>     * As in XMLHttpRequest.
     */
    getAllResponseHeaders: function () {
        var headers = [];
        Ext.Object.each(this.responseHeaders, function (name, value) {
            headers.push(name + ': ' + value);
        });
        return headers.join('\x0d\x0a');
    },
 
<span id='Ext-data-flash-BinaryXhr-method-getResponseHeader'>    /**
</span>     * As in XMLHttpRequest.
     */
    getResponseHeader: function (header) {
        var headers = this.responseHeaders;
        return (headers &amp;&amp; headers[header]) || null;
    },
 
<span id='Ext-data-flash-BinaryXhr-method-open'>    /**
</span>     * As in XMLHttpRequest.
     */
    open: function (method, url, async, user, password) {
        var me = this;
        me.method = method;
        me.url = url;
        me.async = async !== false;
        me.user = user;
        me.password = password;
        
        //&lt;debug&gt;
        if (!me.async) {
            Ext.Error.raise(&quot;Binary posts are only supported in async mode: &quot; + url);
        }
        if (me.method != &quot;POST&quot;) {
            Ext.log.warn(&quot;Binary data can only be sent as a POST request: &quot; + url);
        }
        //&lt;/debug&gt;
    },
 
<span id='Ext-data-flash-BinaryXhr-method-overrideMimeType'>    /**
</span>     * As in XMLHttpRequest.
     */
    overrideMimeType: function (mimeType) {
        this.mimeType = mimeType;
    },
 
<span id='Ext-data-flash-BinaryXhr-method-send'>    /**
</span>     * Initiate the request.
     * @param {Array} body an array of byte values to send.
     */
    send: function (body) {
        var me = this;
        me.body = body;
        if (!Ext.data.flash.BinaryXhr.flashPluginActive) {
            Ext.globalEvents.addListener(&quot;flashready&quot;, me.onFlashReady, me);
        } else {
            this.onFlashReady();
        }
    },
    
<span id='Ext-data-flash-BinaryXhr-method-onFlashReady'>    /**
</span>     * Called by send, or once flash is loaded, to actually send the bytes.
     * @private
     */
    onFlashReady: function() {
        var me = this, req, status;
        me.javascriptId = Ext.data.flash.BinaryXhr.registerConnection(me);
        
        // Create the request object we're sending to flash
        req = {
            method: me.method, // ignored since we always POST binary data
            url: me.url,
            user: me.user,
            password: me.password,
            mimeType: me.mimeType,
            requestHeaders: me.requestHeaders,
            body: me.body,
            javascriptId: me.javascriptId
        };
        status = Ext.data.flash.BinaryXhr.flashPlugin.postBinary(req);
    },
 
<span id='Ext-data-flash-BinaryXhr-method-setReadyState'>    /**
</span>     * Updates readyState and notifies listeners.
     * @private
     */
    setReadyState: function (state) {
        var me = this;
        if (me.readyState != state) {
            me.readyState = state;
            me.onreadystatechange();
        }
    },
 
<span id='Ext-data-flash-BinaryXhr-method-setRequestHeader'>    /**
</span>     * As in XMLHttpRequest.
     */
    setRequestHeader: function (header, value) {
        this.requestHeaders[header] = value;
    },
 
<span id='Ext-data-flash-BinaryXhr-method-onreadystatechange'>    /**
</span>     * As in XMLHttpRequest.
     */
    onreadystatechange: Ext.emptyFn,
 
<span id='Ext-data-flash-BinaryXhr-method-parseData'>    /**
</span>     * Parses data returned from flash once a connection is done.
     * @param {Object} data the data object send from Flash.
     * @private
     */
    parseData: function (data) {
        var me = this;
        // parse data and set up variables so that listeners can use this XHR
        this.status = data.status || 0; 
        // we get back no response headers, so fake what we know:
        me.responseHeaders = {};
        if (me.mimeType) {
            me.responseHeaders[&quot;content-type&quot;] = me.mimeType;
        }
        if (data.reason == &quot;complete&quot;) {
            // Transfer complete and data received
            this.responseBytes = data.data;
            me.responseHeaders[&quot;content-length&quot;] = data.data.length;
        } else if (data.reason == &quot;error&quot; || data.reason == &quot;securityError&quot;) {
            this.statusText = data.text;
            me.responseHeaders[&quot;content-length&quot;] = 0; // we don't get the error response data
        }
        //&lt;debug&gt;
        else {
            Ext.Error.raise(&quot;Unkown reason code in data: &quot; + data.reason);
        }
        //&lt;/debug&gt;
    },
 
<span id='Ext-data-flash-BinaryXhr-method-onFlashStateChange'>    /**
</span>     * Called once flash calls back with updates about the connection
     * @param {Number} state the readyState of the connection.
     * @param {Object} data optional data object.
     * @private
     */
    onFlashStateChange: function(state, data) {
        var me = this;
        if (state == 4) {
            // parse data and prepare for handing back to initiator
            me.parseData(data);
            // remove from list
            delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];
        }
        me.setReadyState(state); // notify all listeners
    }
    
});
</pre>
</body>
</html>