0

I need to embed a Flash .swf on the page and am unable use the normal way of setting the src or data attribute to the swf url - don't ask :s. So, I'm doing an ajax request for the swf, converting to a blob and then generating a blob url which I set as the swf src. Then I realised that as I'm building with Grunt, there may be a way to just write the swf file into the code as a blob in a var, and avoid the ajax request completely. Here's the code with the ajax request:

function createFlashMovie(blobUrl){
     var obj = document.createElement("object");
     obj.setAttribute("width", "800");
     obj.setAttribute("height", "600");
     obj.setAttribute("type", "application/x-shockwave-flash");
     obj.setAttribute("data", blobUrl);
     document.body.appendChild(obj);
}

function onAjaxLoad(oResponse){
    blobUrl = window.URL.createObjectURL(oResponse);
    createFlashMovie(blobUrl);
};

//do the xhr request for a.swf
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        onAjaxLoad(this.response);
    }
}
xhr.open('GET', '//theserver.com/a.swf');
xhr.responseType = 'blob';
xhr.send(); 

...but I'm sure it must be possible to have something like this which is replaced by grunt to have the blob already available when it runs, and go straight to creating the blob url without the xhr request:

var theBlob = new Blob(["GRUNT_WRITES_THIS_IN_FROM_FILE"], {type: "application/x-shockwave-flash"});
tripRev
  • 830
  • 3
  • 12
  • 27

2 Answers2

0

Well, grunt is at its core just a Node program, so you can use any node command in your Gruntfile or tasks definitions. And it seems that Node's http.request would be perfect for your needs.

So:

  1. add a custom task in your Gruntfile (http://gruntjs.com/creating-tasks#custom-tasks)
  2. that uses http.request to download your swf (https://docs.nodejitsu.com/articles/HTTP/clients/how-to-create-a-HTTP-request)
  3. update your code to use the local swf
Xavier Priour
  • 2,121
  • 1
  • 12
  • 16
  • Thanks but I'm not completely sure I explained the problem properly. I'm hoping the encoded data of the swf file will actually be written into the JS file so it's available in memory when it runs - and no requests will be needed. Anyway I found a solution which I'm posting shortly. – tripRev Sep 24 '15 at 22:55
0

I found a solution. Convert your swf file to be a base64-encoded string. At the moment I'm doing this separately and then pasting it into the source JS, but it can be automated at build time with grunt. Then in the page script create a var to store it as a dataURI:

var swfAsDataUri = "data:application/x-shockwave-flash;base64,BIG_LONG_CHUNK_OF_DATA_THAT_IS_YOUR_ENCODED_SWF_FILE__GRUNT_CAN_WRITE_THIS_IN_AT_BUILD_TIME";

Create a blob from the data url, and then create an object url from the blob:

//function taken from http://stackoverflow.com/questions/27159179/how-to-convert-blob-to-file-in-javascript
dataURLToBlob = function(dataURL) {
    var BASE64_MARKER = ';base64,';
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
};

var blobUrl = window.URL.createObjectURL( dataURLToBlob(swfAsDataUri) );

You can then use the object url as the src data for the flash movie's object tag when it's embedded:

function createFlashMovie(blobUrl){
    var obj = document.createElement("object");
    obj.setAttribute("width", "800");
    obj.setAttribute("height", "600");
    obj.setAttribute("type", "application/x-shockwave-flash");
    obj.setAttribute("data", blobUrl); //use the object url here
    document.body.appendChild(obj);
}

...and there you have it, no additional http request for the swf file.

tripRev
  • 830
  • 3
  • 12
  • 27