// https://gist.github.com/harrison @ https://gist.github.com/gocardless
// ---------------------------------------------------------
// Heavily inspired by https://github.com/twilson63/ngUpload

// AngularJS file upload directive
//
// Creates a new inherited child scope and adds a $isUploading property
// Use this property to show loading messages and to disable the submit button
//
// The attribute directive takes an options hash:
// options = { onUploadEnd: function onUploadEnd(content) {}  }
// Use ng-submit if you want to know when the upload starts
//
// <div ng-app="app">
//   <div ng-controller="ctrl">
//    <form action="/uploads" gc-upload="{
//        onUploadEnd: onUploadEnd
//      }">
//      <input type="file" name="file" ng-required="true">
//      <input type="submit" value="Upload" ng-disabled="$isUploading">
//    </form>
//  </div>
// </div>
//
//  angular.module('app', ['gcUpload'])
//    .controller('ctrl', function($scope) {
//      $scope.onUploadEnd = function onUploadEnd(content) {
//        console.log(content);
//      }
//  });

'use strict';

angular.module('gcUpload', [])
  .directive('gcUpload', [
    '$log',
    function gcUploadDirective($log) {
      return {
        scope: true,
        require: 'form',
        link: function gcUploadLink(scope, element, attrs, ctrl) {
          // Give each directive instance a new id
          var iframeID = _.uniqueId();

          var options = scope.$eval(attrs.gcUpload) || {};

          function getActionAttrValue() {
            var action = element.attr('action');
            var separator = action.indexOf('?') === -1 ? '?' : '&';
            var tStamp = +(new Date());

            // Append a timestamp field to the url
            // to prevent browser caching results
            return action + separator + '_t=' + tStamp;
          }

          function setLoadingState(state) {
            scope.$isUploading = state;
          }

          element.attr({
            'target': 'upload-iframe-' + iframeID,
            'method': 'post',
            'action': getActionAttrValue(),
            'enctype': 'multipart/form-data',
            'encoding': 'multipart/form-data'
          });

          var iframe = angular.element(
            '<iframe name="upload-iframe-' + iframeID + '" ' +
            'border="0" width="0" height="0" ' +
            'style="width:0px;height:0px;border:none;display:none">'
          );

          element.after(iframe);

          setLoadingState(false);

          // Start upload
          element.bind('submit', function uploadStart() {
            scope.$apply(function() {
              setLoadingState(true);
            });

            // Finish upload
            iframe.bind('load', function uploadEnd() {
              iframe.unbind('load');
              // Reset form
              element[0].reset();
              ctrl.$setPristine();

              scope.$apply(function() {
                setLoadingState(false);
              });

              // Get iframe body contents
              var bodyContent = (iframe[0].contentDocument ||
                iframe[0].contentWindow.document).body;
              var content;
              try {
                content = angular.fromJson(bodyContent.innerText);
              } catch (e) {
                // Fall back to html if json parse failed
                content = bodyContent.innerHTML;
                $log.warn('Response is not valid JSON');
              }

              if (angular.isFunction(options.onUploadEnd)) {
                scope.$apply(function() {
                  options.onUploadEnd(content);
                });
              }
            });
          });
        }
      };
    }
  ]);

@@ -1196,291 +1196,9 @@
 ) %7B%0A
-      return %7B%0A        scope: true,%0A        require: 'form',%0A        link: function gcUploadLink(scope, element, attrs, ctrl) %7B%0A          // Give each directive instance a new id%0A          var iframeID = _.uniqueId();%0A%0A          var options = scope.$eval(attrs.gcUpload) %7C%7C %7B%7D;%0A%0A    
+%0A
     
@@ -1227,24 +1227,27 @@
 trValue(
+element
 ) %7B%0A
-    
         
@@ -1287,28 +1287,24 @@
 ');%0A        
- 
-   
 var separato
@@ -1351,28 +1351,24 @@
 &';%0A        
-    
 var tStamp =
@@ -1392,20 +1392,16 @@
         
-   
- 
 // Appen
@@ -1439,20 +1439,16 @@
         
-    
 // to pr
@@ -1477,20 +1477,16 @@
 results%0A
-    
         
@@ -1527,37 +1527,312 @@
 + tStamp;%0A      
-    %7D
+%7D%0A%0A      return %7B%0A        scope: true,%0A        require: 'form',%0A        link: function gcUploadLink(scope, element, attrs, ctrl) %7B%0A          // Give each directive instance a new id%0A          var iframeID = _.uniqueId();%0A%0A          var options = scope.$eval(attrs.gcUpload) %7C%7C %7B%7D;
 %0A%0A          func
@@ -2061,16 +2061,23 @@
 trValue(
+element
 ),%0A     
@@ -3040,20 +3040,20 @@
 var body
-Cont
+Elem
 ent = (i
@@ -3161,16 +3161,54 @@
  content
+ = angular.element(bodyElement).text()
 ;%0A      
@@ -3268,28 +3268,14 @@
 son(
-bodyContent.innerTex
+conten
 t);%0A
@@ -3306,115 +3306,8 @@
 ) %7B%0A
-                // Fall back to html if json parse failed%0A                content = bodyContent.innerHTML;%0A
     

Fix FF issue - use angular.element.text