<!DOCTYPE html>
<html ng-app="app">
<head>
<link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script data-require="bootstrap@*" data-semver="3.3.2" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="uploadCtrl as vm">
<h1>{{vm.title}}</h1>
<button class="btn btn-default" ngf-select="" ngf-change="vm.upload($files)">Upload on file change</button>
<hr/>
<pre ng-show="vm.log">
{{vm.log}}
</pre>
<script src="https://code.angularjs.org/1.4.1/angular.js"></script>
<script src="xdomain.fixed.js" slave="http://echo.jpillora.com/proxy.html"></script>
<script src="ng-file-upload-all.js"></script>
<script src="script.js"></script>
</body>
</html>
// Code goes here
(function() {
'use strict';
angular.module('app',['ngFileUpload']).controller('uploadCtrl', UploadCtrl);
UploadCtrl.$inject = ['Upload'];
function UploadCtrl(Upload){
var vm = this;
vm.title="Upload test";
vm.upload = function(files){
if (files && files.length) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
Upload.upload({
url: 'https://angular-file-upload-cors-srv.appspot.com/upload',
fields: {
'username': 'username'
},
file: file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
vm.log = 'progress: ' + progressPercentage + '% ' +
evt.config.file.name + '\n' + $scope.log;
}).success(function (data, status, headers, config) {
vm.log = 'file ' + config.file.name + 'uploaded. Response: ' + JSON.stringify(data) + '\n' + vm.log;
});
}
}
};
};
})();
/* Styles go here */
// XDomain - v0.7.3 - https://github.com/jpillora/xdomain
// Jaime Pillora <dev@jpillora.com> - MIT Copyright 2015
(function (window, undefined) {
// XHook - v1.3.3 - https://github.com/jpillora/xhook
// Jaime Pillora <dev@jpillora.com> - MIT Copyright 2015
(function (window, undefined) {
var AFTER, BEFORE, COMMON_EVENTS, EventEmitter, FIRE, FormData, NativeFormData, NativeXMLHttp, OFF, ON, READY_STATE, UPLOAD_EVENTS, XHookFormData, XHookHttpRequest, XMLHTTP, convertHeaders, depricatedProp, document, fakeEvent, mergeObjects, msie, proxyEvents, slice, xhook, _base,
__indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
document = window.document;
BEFORE = 'before';
AFTER = 'after';
READY_STATE = 'readyState';
ON = 'addEventListener';
OFF = 'removeEventListener';
FIRE = 'dispatchEvent';
XMLHTTP = 'XMLHttpRequest';
FormData = 'FormData';
UPLOAD_EVENTS = ['load', 'loadend', 'loadstart'];
COMMON_EVENTS = ['progress', 'abort', 'error', 'timeout'];
msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
if (isNaN(msie)) {
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
}
(_base = Array.prototype).indexOf || (_base.indexOf = function (item) {
var i, x, _i, _len;
for (i = _i = 0, _len = this.length; _i < _len; i = ++_i) {
x = this[i];
if (x === item) {
return i;
}
}
return -1;
});
slice = function (o, n) {
return Array.prototype.slice.call(o, n);
};
depricatedProp = function (p) {
return p === "returnValue" || p === "totalSize" || p === "position";
};
mergeObjects = function (src, dst) {
var k, v;
for (k in src) {
v = src[k];
if (depricatedProp(k)) {
continue;
}
try {
dst[k] = src[k];
} catch (_error) { }
}
return dst;
};
proxyEvents = function (events, src, dst) {
var event, p, _i, _len;
p = function (event) {
return function (e) {
var clone, k, val;
clone = {};
for (k in e) {
if (depricatedProp(k)) {
continue;
}
val = e[k];
clone[k] = val === src ? dst : val;
}
return dst[FIRE](event, clone);
};
};
for (_i = 0, _len = events.length; _i < _len; _i++) {
event = events[_i];
if (dst._has(event)) {
src["on" + event] = p(event);
}
}
};
fakeEvent = function (type) {
var msieEventObject;
if (document.createEventObject != null) {
msieEventObject = document.createEventObject();
msieEventObject.type = type;
return msieEventObject;
} else {
try {
return new Event(type);
} catch (_error) {
return {
type: type
};
}
}
};
EventEmitter = function (nodeStyle) {
var emitter, events, listeners;
events = {};
listeners = function (event) {
return events[event] || [];
};
emitter = {};
emitter[ON] = function (event, callback, i) {
events[event] = listeners(event);
if (events[event].indexOf(callback) >= 0) {
return;
}
i = i === undefined ? events[event].length : i;
events[event].splice(i, 0, callback);
};
emitter[OFF] = function (event, callback) {
var i;
if (event === undefined) {
events = {};
return;
}
if (callback === undefined) {
events[event] = [];
}
i = listeners(event).indexOf(callback);
if (i === -1) {
return;
}
listeners(event).splice(i, 1);
};
emitter[FIRE] = function () {
var args, event, i, legacylistener, listener, _i, _len, _ref;
args = slice(arguments);
event = args.shift();
if (!nodeStyle) {
args[0] = mergeObjects(args[0], fakeEvent(event));
}
legacylistener = emitter["on" + event];
if (legacylistener) {
legacylistener.apply(undefined, args);
}
_ref = listeners(event).concat(listeners("*"));
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
listener = _ref[i];
listener.apply(undefined, args);
}
};
emitter._has = function (event) {
return !!(events[event] || emitter["on" + event]);
};
if (nodeStyle) {
emitter.listeners = function (event) {
return slice(listeners(event));
};
emitter.on = emitter[ON];
emitter.off = emitter[OFF];
emitter.fire = emitter[FIRE];
emitter.once = function (e, fn) {
var fire;
fire = function () {
emitter.off(e, fire);
return fn.apply(null, arguments);
};
return emitter.on(e, fire);
};
emitter.destroy = function () {
return events = {};
};
}
return emitter;
};
xhook = EventEmitter(true);
xhook.EventEmitter = EventEmitter;
xhook[BEFORE] = function (handler, i) {
if (handler.length < 1 || handler.length > 2) {
throw "invalid hook";
}
return xhook[ON](BEFORE, handler, i);
};
xhook[AFTER] = function (handler, i) {
if (handler.length < 2 || handler.length > 3) {
throw "invalid hook";
}
return xhook[ON](AFTER, handler, i);
};
xhook.enable = function () {
window[XMLHTTP] = XHookHttpRequest;
if (NativeFormData) {
window[FormData] = XHookFormData;
}
};
xhook.disable = function () {
window[XMLHTTP] = xhook[XMLHTTP];
window[FormData] = NativeFormData;
};
convertHeaders = xhook.headers = function (h, dest) {
var header, headers, k, name, v, value, _i, _len, _ref;
if (dest == null) {
dest = {};
}
switch (typeof h) {
case "object":
headers = [];
for (k in h) {
v = h[k];
name = k.toLowerCase();
headers.push("" + name + ":\t" + v);
}
return headers.join('\n');
case "string":
headers = h.split('\n');
for (_i = 0, _len = headers.length; _i < _len; _i++) {
header = headers[_i];
if (/([^:]+):\s*(.+)/.test(header)) {
name = (_ref = RegExp.$1) != null ? _ref.toLowerCase() : void 0;
value = RegExp.$2;
if (dest[name] == null) {
dest[name] = value;
}
}
}
return dest;
}
};
NativeFormData = window[FormData];
XHookFormData = function (form) {
var entries;
this.fd = form ? new NativeFormData(form) : new NativeFormData();
this.form = form;
entries = [];
Object.defineProperty(this, 'entries', {
get: function () {
var fentries;
fentries = !form ? [] : slice(form.querySelectorAll("input,select")).filter(function (e) {
var _ref;
return ((_ref = e.type) !== 'checkbox' && _ref !== 'radio') || e.checked;
}).map(function (e) {
return [e.name, e.type === "file" ? e.files : e.value];
});
return fentries.concat(entries);
}
});
this.append = (function (_this) {
return function () {
var args;
args = slice(arguments);
entries.push(args);
return _this.fd.append.apply(_this.fd, args);
};
})(this);
};
if (NativeFormData) {
xhook[FormData] = NativeFormData;
window[FormData] = XHookFormData;
}
NativeXMLHttp = window[XMLHTTP];
xhook[XMLHTTP] = NativeXMLHttp;
XHookHttpRequest = window[XMLHTTP] = function () {
var ABORTED, currentState, emitFinal, emitReadyState, facade, hasError, hasErrorHandler, readBody, readHead, request, response, setReadyState, status, transiting, writeBody, writeHead, xhr;
ABORTED = -1;
xhr = new xhook[XMLHTTP]();
request = {};
status = null;
hasError = void 0;
transiting = void 0;
response = void 0;
readHead = function () {
var key, name, val, _ref;
response.status = status || xhr.status;
if (!(status === ABORTED && msie < 10)) {
response.statusText = xhr.statusText;
}
if (status !== ABORTED) {
_ref = convertHeaders(xhr.getAllResponseHeaders());
for (key in _ref) {
val = _ref[key];
if (!response.headers[key]) {
name = key.toLowerCase();
response.headers[name] = val;
}
}
}
};
readBody = function () {
if (!xhr.responseType || xhr.responseType === "text") {
response.text = xhr.responseText;
response.data = xhr.responseText;
} else if (xhr.responseType === "document") {
response.xml = xhr.responseXML;
response.data = xhr.responseXML;
} else {
response.data = xhr.response;
}
if ("responseURL" in xhr) {
response.finalUrl = xhr.responseURL;
}
};
writeHead = function () {
facade.status = response.status;
facade.statusText = response.statusText;
};
writeBody = function () {
if ('text' in response) {
facade.responseText = response.text;
}
if ('xml' in response) {
facade.responseXML = response.xml;
}
if ('data' in response) {
facade.response = response.data;
}
if ('finalUrl' in response) {
facade.responseURL = response.finalUrl;
}
};
emitReadyState = function (n) {
while (n > currentState && currentState < 4) {
facade[READY_STATE] = ++currentState;
if (currentState === 1) {
facade[FIRE]("loadstart", {});
}
if (currentState === 2) {
writeHead();
}
if (currentState === 4) {
writeHead();
writeBody();
}
facade[FIRE]("readystatechange", {});
if (currentState === 4) {
setTimeout(emitFinal, 0);
}
}
};
emitFinal = function () {
if (!hasError) {
facade[FIRE]("load", {});
}
facade[FIRE]("loadend", {});
if (hasError) {
facade[READY_STATE] = 0;
}
};
currentState = 0;
setReadyState = function (n) {
var hooks, process;
if (n !== 4) {
emitReadyState(n);
return;
}
hooks = xhook.listeners(AFTER);
process = function () {
var hook;
if (!hooks.length) {
return emitReadyState(4);
}
hook = hooks.shift();
if (hook.length === 2) {
hook(request, response);
return process();
} else if (hook.length === 3 && request.async) {
return hook(request, response, process);
} else {
return process();
}
};
process();
};
facade = request.xhr = EventEmitter();
xhr.onreadystatechange = function (event) {
try {
if (xhr[READY_STATE] === 2) {
readHead();
}
} catch (_error) { }
if (xhr[READY_STATE] === 4) {
transiting = false;
readHead();
readBody();
}
setReadyState(xhr[READY_STATE]);
};
hasErrorHandler = function () {
hasError = true;
};
facade[ON]('error', hasErrorHandler);
facade[ON]('timeout', hasErrorHandler);
facade[ON]('abort', hasErrorHandler);
facade[ON]('progress', function () {
if (currentState < 3) {
setReadyState(3);
} else {
facade[FIRE]("readystatechange", {});
}
});
if ('withCredentials' in xhr || xhook.addWithCredentials) {
facade.withCredentials = false;
}
facade.status = 0;
facade.open = function (method, url, async, user, pass) {
currentState = 0;
hasError = false;
transiting = false;
request.headers = {};
request.headerNames = {};
request.status = 0;
response = {};
response.headers = {};
request.method = method;
request.url = url;
request.async = async !== false;
request.user = user;
request.pass = pass;
setReadyState(1);
};
facade.send = function (body) {
var hooks, k, modk, process, send, _i, _len, _ref;
_ref = ['type', 'timeout', 'withCredentials'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
k = _ref[_i];
modk = k === "type" ? "responseType" : k;
if (modk in facade) {
request[k] = facade[modk];
}
}
request.body = body;
send = function () {
var header, value, _j, _len1, _ref1, _ref2;
proxyEvents(COMMON_EVENTS, xhr, facade);
if (facade.upload) {
proxyEvents(COMMON_EVENTS.concat(UPLOAD_EVENTS), xhr.upload, facade.upload);
}
transiting = true;
xhr.open(request.method, request.url, request.async, request.user, request.pass);
_ref1 = ['type', 'timeout', 'withCredentials'];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
k = _ref1[_j];
modk = k === "type" ? "responseType" : k;
if (k in request) {
xhr[modk] = request[k];
}
}
_ref2 = request.headers;
for (header in _ref2) {
value = _ref2[header];
if (typeof value !== 'function') {
xhr.setRequestHeader(header, value);
}
}
if (request.body instanceof XHookFormData) {
request.body = request.body.fd;
}
xhr.send(request.body);
};
hooks = xhook.listeners(BEFORE);
process = function () {
var done, hook;
if (!hooks.length) {
return send();
}
done = function (userResponse) {
if (typeof userResponse === 'object' && (typeof userResponse.status === 'number' || typeof response.status === 'number')) {
mergeObjects(userResponse, response);
if (__indexOf.call(userResponse, 'data') < 0) {
userResponse.data = userResponse.response || userResponse.text;
}
setReadyState(4);
return;
}
process();
};
done.head = function (userResponse) {
mergeObjects(userResponse, response);
return setReadyState(2);
};
done.progress = function (userResponse) {
mergeObjects(userResponse, response);
return setReadyState(3);
};
hook = hooks.shift();
if (hook.length === 1) {
return done(hook(request));
} else if (hook.length === 2 && request.async) {
return hook(request, done);
} else {
return done();
}
};
process();
};
facade.abort = function () {
status = ABORTED;
if (transiting) {
xhr.abort();
} else {
facade[FIRE]('abort', {});
}
};
facade.setRequestHeader = function (header, value) {
var lName, name;
lName = header != null ? header.toLowerCase() : void 0;
name = request.headerNames[lName] = request.headerNames[lName] || header;
if (request.headers[name]) {
value = request.headers[name] + ', ' + value;
}
request.headers[name] = value;
};
facade.getResponseHeader = function (header) {
var name;
name = header != null ? header.toLowerCase() : void 0;
return response.headers[name];
};
facade.getAllResponseHeaders = function () {
return convertHeaders(response.headers);
};
if (xhr.overrideMimeType) {
facade.overrideMimeType = function () {
return xhr.overrideMimeType.apply(xhr, arguments);
};
}
if (xhr.upload) {
facade.upload = request.upload = EventEmitter();
}
return facade;
};
if (typeof this.define === "function" && this.define.amd) {
define("xhook", [], function () {
return xhook;
});
} else {
(this.exports || this).xhook = xhook;
}
}.call(this, window));
var CHECK_INTERVAL, COMPAT_VERSION, XD_CHECK, console, cookies, createSocket, currentOrigin, document, emitter, feature, frames, getFrame, guid, handleSocket, initMaster, initSlave, initdMaster, initdSlave, instOf, jsonEncode, location, log, logger, masters, onMessage, parseUrl, setupEmitter, slaves, slice, sockets, startPostMessage, strip, toRegExp, warn, xdomain, xhook, _i, _len, _ref;
initdMaster = false;
slaves = function (s) {
var origin, path;
if (!initdMaster) {
initMaster();
}
for (origin in s) {
path = s[origin];
log("adding slave: " + origin);
slaves[origin] = path;
}
};
frames = {};
getFrame = function (origin, proxyPath) {
var frame;
if (frames[origin]) {
return frames[origin];
}
frame = document.createElement("iframe");
frame.id = frame.name = guid();
log("creating iframe " + frame.id);
frame.src = "" + origin + proxyPath;
frame.setAttribute('style', 'display:none;');
document.body.appendChild(frame);
return frames[origin] = frame.contentWindow;
};
initMaster = function () {
var convertFormData, convertToArrayBuffer, handleRequest;
initdMaster = true;
convertToArrayBuffer = function (args, done) {
var isBlob, isFile, name, obj, reader;
name = args[0], obj = args[1];
isBlob = instOf(obj, 'Blob');
isFile = instOf(obj, 'File');
if (!(isBlob || isFile)) {
return 0;
}
reader = new FileReader();
reader.onload = function () {
args[1] = null;
if (isFile) {
args[2] = obj.name;
}
return done(['XD_BLOB', args, this.result, obj.type]);
};
reader.readAsArrayBuffer(obj);
return 1;
};
convertFormData = function (entries, send) {
var c;
entries.forEach(function (args, i) {
var file, name, value, _i, _len;
name = args[0], value = args[1];
if (instOf(value, 'FileList')) {
entries.splice(i, 1);
for (_i = 0, _len = value.length; _i < _len; _i++) {
file = value[_i];
entries.splice(i, 0, [name, file]);
}
}
});
c = 0;
entries.forEach(function (args, i) {
c += convertToArrayBuffer(args, function (newargs) {
entries[i] = newargs;
if (--c === 0) {
send();
}
});
});
if (c === 0) {
send();
}
};
handleRequest = function (request, socket) {
var entries, obj, send;
socket.on("xhr-event", function () {
return request.xhr.dispatchEvent.apply(null, arguments);
});
socket.on("xhr-upload-event", function () {
return request.xhr.upload.dispatchEvent.apply(null, arguments);
});
obj = strip(request);
obj.headers = request.headers;
if (request.withCredentials) {
if (cookies.master) {
obj.headers[cookies.master] = document.cookie;
}
obj.slaveCookie = cookies.slave;
}
send = function () {
return socket.emit("request", obj);
};
if (request.body) {
obj.body = request.body;
if (instOf(obj.body, 'FormData')) {
entries = obj.body.entries;
obj.body = ["XD_FD", entries];
convertFormData(entries, send);
return;
}
}
send();
};
if (!('addWithCredentials' in xhook)) {
xhook.addWithCredentials = true;
}
return xhook.before(function (request, callback) {
var frame, p, socket;
p = parseUrl(request.url);
if (!p || p.origin === currentOrigin) {
return callback();
}
if (!slaves[p.origin]) {
if (p) {
log("no slave matching: '" + p.origin + "'");
}
return callback();
}
log("proxying request to slave: '" + p.origin + "'");
if (request.async === false) {
warn("sync not supported");
return callback();
}
frame = getFrame(p.origin, slaves[p.origin]);
socket = createSocket(guid(), frame);
socket.on("response", function (resp) {
callback(resp);
return socket.close();
});
request.xhr.addEventListener('abort', function () {
return socket.emit("abort");
});
if (socket.ready) {
handleRequest(request, socket);
} else {
socket.once('ready', function () {
return handleRequest(request, socket);
});
}
});
};
initdSlave = false;
masters = function (m) {
var origin, path;
if (!initdSlave) {
initSlave();
}
for (origin in m) {
path = m[origin];
log("adding master: " + origin);
masters[origin] = path;
}
};
handleSocket = null;
initSlave = function () {
initdSlave = true;
log("handling incoming sockets...");
handleSocket = function (origin, socket) {
var master, masterRegex, pathRegex, regex;
if (origin === "null") {
origin = "*";
}
pathRegex = null;
for (master in masters) {
regex = masters[master];
try {
masterRegex = toRegExp(master);
if (masterRegex.test(origin)) {
pathRegex = toRegExp(regex);
break;
}
} catch (_error) { }
}
if (!pathRegex) {
warn("blocked request from: '" + origin + "'");
return;
}
socket.once("request", function (req) {
var args, blob, entries, fd, k, p, v, xhr, _i, _len, _ref;
log("request: " + req.method + " " + req.url);
p = parseUrl(req.url);
if (!(p && pathRegex.test(p.path))) {
warn("blocked request to path: '" + p.path + "' by regex: " + pathRegex);
socket.close();
return;
}
xhr = new XMLHttpRequest();
xhr.open(req.method, req.url);
xhr.addEventListener("*", function (e) {
return socket.emit('xhr-event', e.type, strip(e));
});
if (xhr.upload) {
xhr.upload.addEventListener("*", function (e) {
return socket.emit('xhr-upload-event', e.type, strip(e));
});
}
socket.once("abort", function () {
return xhr.abort();
});
xhr.onreadystatechange = function () {
var resp;
if (xhr.readyState !== 4) {
return;
}
resp = {
status: xhr.status,
statusText: xhr.statusText,
data: xhr.response,
headers: xhook.headers(xhr.getAllResponseHeaders())
};
try {
resp.text = xhr.responseText;
} catch (_error) { }
return socket.emit('response', resp);
};
if (req.withCredentials) {
xhr.withCredentials = true;
if (req.slaveCookie) {
req.headers[req.slaveCookie] = document.cookie;
}
}
if (req.timeout) {
xhr.timeout = req.timeout;
}
if (req.type) {
xhr.responseType = req.type;
}
_ref = req.headers;
for (k in _ref) {
v = _ref[k];
xhr.setRequestHeader(k, v);
}
if (req.body instanceof Array && req.body[0] === "XD_FD") {
fd = new xhook.FormData();
entries = req.body[1];
for (_i = 0, _len = entries.length; _i < _len; _i++) {
args = entries[_i];
if (args[0] === "XD_BLOB" && args.length === 4) {
blob = new Blob([args[2]], {
type: args[3]
});
args = args[1];
args[1] = blob;
}
fd.append.apply(fd, args);
}
req.body = fd;
}
xhr.send(req.body || null);
});
log("slave listening for requests on socket: " + socket.id);
};
if (window === window.parent) {
return warn("slaves must be in an iframe");
} else {
return window.parent.postMessage("XDPING_" + COMPAT_VERSION, '*');
}
};
XD_CHECK = "XD_CHECK";
sockets = {};
jsonEncode = true;
createSocket = function (id, frame) {
var check, checks, emit, pendingEmits, ready, sock;
ready = false;
sock = sockets[id] = xhook.EventEmitter(true);
sock.id = id;
sock.once('close', function () {
sock.destroy();
return sock.close();
});
pendingEmits = [];
sock.emit = function () {
var args, extra;
args = slice(arguments);
extra = typeof args[1] === "string" ? " -> " + args[1] : "";
log("send socket: " + id + ": " + args[0] + extra);
args.unshift(id);
if (ready) {
emit(args);
} else {
pendingEmits.push(args);
}
};
emit = function (args) {
if (jsonEncode) {
args = JSON.stringify(args);
}
frame.postMessage(args, "*");
};
sock.close = function () {
sock.emit('close');
log("close socket: " + id);
sockets[id] = null;
};
sock.once(XD_CHECK, function (obj) {
jsonEncode = typeof obj === "string";
ready = sock.ready = true;
sock.emit('ready');
log("ready socket: " + id + " (emit #" + pendingEmits.length + " pending)");
while (pendingEmits.length) {
emit(pendingEmits.shift());
}
});
checks = 0;
check = (function (_this) {
return function () {
frame.postMessage([id, XD_CHECK, {}], "*");
if (ready) {
return;
}
if (checks++ >= xdomain.timeout / CHECK_INTERVAL) {
warn("Timeout waiting on iframe socket");
emitter.fire("timeout");
sock.fire("abort");
} else {
setTimeout(check, CHECK_INTERVAL);
}
};
})(this);
setTimeout(check);
log("new socket: " + id);
return sock;
};
onMessage = function (fn) {
if (document.addEventListener) {
return window.addEventListener("message", fn);
} else {
return window.attachEvent("onmessage", fn);
}
};
startPostMessage = function () {
return onMessage(function (e) {
var d, extra, id, sock;
d = e.data;
if (typeof d === "string") {
if (/^XDPING(_(V\d+))?$/.test(d) && RegExp.$2 !== COMPAT_VERSION) {
return warn("your master is not compatible with your slave, check your xdomain.js version");
} else if (/^xdomain-/.test(d)) {
d = d.split(",");
} else if (jsonEncode) {
try {
d = JSON.parse(d);
} catch (_error) {
return;
}
}
}
if (!(d instanceof Array)) {
return;
}
id = d.shift();
if (!/^xdomain-/.test(id)) {
return;
}
sock = sockets[id];
if (sock === null) {
return;
}
if (sock === undefined) {
if (!handleSocket) {
return;
}
sock = createSocket(id, e.source);
handleSocket(e.origin, sock);
}
extra = typeof d[1] === "string" ? " -> " + d[1] : "";
log("receive socket: " + id + ": " + d[0] + extra);
sock.fire.apply(sock, d);
});
};
'use strict';
xhook = (this.exports || this).xhook;
xdomain = function (o) {
if (!o) {
return;
}
if (o.masters) {
masters(o.masters);
}
if (o.slaves) {
slaves(o.slaves);
}
};
xdomain.masters = masters;
xdomain.slaves = slaves;
xdomain.debug = false;
xdomain.timeout = 15e3;
CHECK_INTERVAL = 100;
cookies = xdomain.cookies = {
master: "Master-Cookie",
slave: "Slave-Cookie"
};
document = window.document;
location = window.location;
currentOrigin = xdomain.origin = location.protocol + '//' + location.host;
guid = function () {
return 'xdomain-' + Math.round(Math.random() * Math.pow(2, 32)).toString(16);
};
slice = function (o, n) {
return Array.prototype.slice.call(o, n);
};
console = window.console || {};
emitter = null;
setupEmitter = function () {
emitter = xhook.EventEmitter(true);
xdomain.on = emitter.on;
xdomain.off = emitter.off;
};
if (xhook) {
setupEmitter();
}
logger = function (type) {
return function (str) {
str = "xdomain (" + currentOrigin + "): " + str;
emitter.fire(type, str);
if (type === 'log' && !xdomain.debug) {
return;
}
if (type in xdomain) {
xdomain[type](str);
} else if (type in console) {
console[type](str);
} else if (type === 'warn') {
alert(str);
}
};
};
log = logger('log');
warn = logger('warn');
_ref = ['postMessage', 'JSON'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
feature = _ref[_i];
if (!window[feature]) {
warn("requires '" + feature + "' and this browser does not support it");
return;
}
}
instOf = function (obj, global) {
if (!(global in window)) {
return false;
}
return obj instanceof window[global];
};
COMPAT_VERSION = "V1";
parseUrl = xdomain.parseUrl = function (url) {
if (/^((https?:)?\/\/[^\/\?]+)(\/.*)?/.test(url)) {
return {
origin: (RegExp.$2 ? '' : location.protocol) + RegExp.$1,
path: RegExp.$3
};
} else {
log("failed to parse absolute url: " + url);
return null;
}
};
toRegExp = function (obj) {
var str;
if (obj instanceof RegExp) {
return obj;
}
str = obj.toString().replace(/\W/g, function (str) {
return "\\" + str;
}).replace(/\\\*/g, ".*");
return new RegExp("^" + str + "$");
};
strip = function (src) {
var dst, k, v, _ref1;
dst = {};
for (k in src) {
if (k === "returnValue") {
continue;
}
v = src[k];
if ((_ref1 = typeof v) !== "function" && _ref1 !== "object") {
dst[k] = v;
}
}
return dst;
};
(function () {
var attrs, fn, k, prefix, script, _j, _k, _len1, _len2, _ref1, _ref2;
attrs = {
debug: function (value) {
if (typeof value !== "string") {
return;
}
return xdomain.debug = value !== "false";
},
slave: function (value) {
var p, s;
if (!value) {
return;
}
p = parseUrl(value);
if (!p) {
return;
}
s = {};
s[p.origin] = p.path;
return slaves(s);
},
master: function (value) {
var m, p;
if (!value) {
return;
}
if (value === "*") {
p = {
origin: "*",
path: "*"
};
} else {
p = parseUrl(value);
}
if (!p) {
return;
}
m = {};
m[p.origin] = p.path.replace(/^\//, "") ? p.path : "*";
return masters(m);
}
};
_ref1 = document.getElementsByTagName("script");
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
script = _ref1[_j];
if (/xdomain/.test(script.src)) {
_ref2 = ['', 'data-'];
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
prefix = _ref2[_k];
for (k in attrs) {
fn = attrs[k];
fn(script.getAttribute(prefix + k));
}
}
}
}
})();
startPostMessage();
if (typeof this.define === "function" && this.define.amd) {
define("xdomain", ["xhook"], function (xh) {
xhook = xh;
setupEmitter();
return xdomain;
});
} else {
(this.exports || this).xdomain = xdomain;
}
}.call(this, window));
/**!
* AngularJS file upload/drop directive and service with progress and abort
* @author Danial <danial.farid@gmail.com>
* @version 5.0.8
*/
var ngFileUpload = angular.module('ngFileUpload', []);
ngFileUpload.version = '5.0.8';
ngFileUpload.service('Upload', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
function patchXHR(fnName, newFn) {
window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
}
if (window.XMLHttpRequest && !window.XMLHttpRequest.__isFileAPIShim) {
patchXHR('setRequestHeader', function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
orig.apply(this, arguments);
}
};
});
}
function sendHttp(config) {
config.method = config.method || 'POST';
config.headers = config.headers || {};
var deferred = $q.defer();
var promise = deferred.promise;
config.headers.__setXHR_ = function () {
return function (xhr) {
if (!xhr) return;
config.__XHR = xhr;
if (config.xhrFn) config.xhrFn(xhr);
xhr.upload.addEventListener('progress', function (e) {
e.config = config;
if (deferred.notify) {
deferred.notify(e);
} else if (promise.progressFunc) {
$timeout(function () {
promise.progressFunc(e);
});
}
}, false);
//fix for firefox not firing upload progress end, also IE8-9
xhr.upload.addEventListener('load', function (e) {
if (e.lengthComputable) {
e.config = config;
if (deferred.notify) {
deferred.notify(e);
} else if (promise.progressFunc) {
$timeout(function () {
promise.progressFunc(e);
});
}
}
}, false);
};
};
$http(config).then(function (r) {
deferred.resolve(r);
}, function (e) {
deferred.reject(e);
}, function (n) {
deferred.notify(n);
});
promise.success = function (fn) {
promise.then(function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.error = function (fn) {
promise.then(null, function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.progress = function (fn) {
promise.progressFunc = fn;
promise.then(null, null, function (update) {
fn(update);
});
return promise;
};
promise.abort = function () {
if (config.__XHR) {
$timeout(function () {
config.__XHR.abort();
});
}
return promise;
};
promise.xhr = function (fn) {
config.xhrFn = (function (origXhrFn) {
return function () {
if (origXhrFn) origXhrFn.apply(promise, arguments);
fn.apply(promise, arguments);
};
})(config.xhrFn);
return promise;
};
return promise;
}
this.upload = function (config) {
function addFieldToFormData(formData, val, key) {
if (val !== undefined) {
if (angular.isDate(val)) {
val = val.toISOString();
}
if (angular.isString(val)) {
formData.append(key, val);
} else if (config.sendFieldsAs === 'form') {
if (angular.isObject(val)) {
for (var k in val) {
if (val.hasOwnProperty(k)) {
addFieldToFormData(formData, val[k], key + '[' + k + ']');
}
}
} else {
formData.append(key, val);
}
} else {
val = angular.isString(val) ? val : JSON.stringify(val);
if (config.sendFieldsAs === 'json-blob') {
formData.append(key, new Blob([val], {type: 'application/json'}));
} else {
formData.append(key, val);
}
}
}
}
config.headers = config.headers || {};
config.headers['Content-Type'] = undefined;
config.transformRequest = config.transformRequest ?
(angular.isArray(config.transformRequest) ?
config.transformRequest : [config.transformRequest]) : [];
config.transformRequest.push(function (data) {
var formData = new FormData();
var allFields = {};
var key;
for (key in config.fields) {
if (config.fields.hasOwnProperty(key)) {
allFields[key] = config.fields[key];
}
}
if (data) allFields.data = data;
for (key in allFields) {
if (allFields.hasOwnProperty(key)) {
var val = allFields[key];
if (config.formDataAppender) {
config.formDataAppender(formData, key, val);
} else {
addFieldToFormData(formData, val, key);
}
}
}
if (config.file != null) {
var fileFormName = config.fileFormDataName || 'file';
if (angular.isArray(config.file)) {
var isFileFormNameString = angular.isString(fileFormName);
for (var i = 0; i < config.file.length; i++) {
formData.append(isFileFormNameString ? fileFormName : fileFormName[i], config.file[i],
(config.fileName && config.fileName[i]) || config.file[i].name);
}
} else {
formData.append(fileFormName, config.file, config.fileName || config.file.name);
}
}
return formData;
});
return sendHttp(config);
};
this.http = function (config) {
config.transformRequest = config.transformRequest || function (data) {
if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof Blob) {
return data;
}
return $http.defaults.transformRequest[0](arguments);
};
return sendHttp(config);
};
}
]);
(function () {
ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile',
function ($parse, $timeout, $compile) {
return {
restrict: 'AEC',
require: '?ngModel',
link: function (scope, elem, attr, ngModel) {
linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile);
}
};
}]);
function linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile) {
/** @namespace attr.ngfSelect */
/** @namespace attr.ngfChange */
/** @namespace attr.ngModel */
/** @namespace attr.ngModelRejected */
/** @namespace attr.ngfMultiple */
/** @namespace attr.ngfCapture */
/** @namespace attr.ngfAccept */
/** @namespace attr.ngfMaxSize */
/** @namespace attr.ngfMinSize */
/** @namespace attr.ngfResetOnClick */
/** @namespace attr.ngfResetModelOnClick */
/** @namespace attr.ngfKeep */
/** @namespace attr.ngfKeepDistinct */
if (elem.attr('__ngf_gen__')) {
return;
}
scope.$on('$destroy', function () {
if (elem.$$ngfRefElem) elem.$$ngfRefElem.remove();
});
var disabled = false;
if (attr.ngfSelect.search(/\W+$files\W+/) === -1) {
scope.$watch(attr.ngfSelect, function (val) {
disabled = val === false;
});
}
function isInputTypeFile() {
return elem[0].tagName.toLowerCase() === 'input' && attr.type && attr.type.toLowerCase() === 'file';
}
var isUpdating = false;
function changeFn(evt) {
if (!isUpdating) {
isUpdating = true;
try {
var fileList = evt.__files_ || (evt.target && evt.target.files);
var files = [], rejFiles = [];
for (var i = 0; i < fileList.length; i++) {
var file = fileList.item(i);
if (validate(scope, $parse, attr, file, evt)) {
files.push(file);
} else {
rejFiles.push(file);
}
}
updateModel($parse, $timeout, scope, ngModel, attr, attr.ngfChange || attr.ngfSelect, files, rejFiles, evt);
if (files.length === 0) evt.target.value = files;
// if (evt.target && evt.target.getAttribute('__ngf_gen__')) {
// angular.element(evt.target).remove();
// }
} finally {
isUpdating = false;
}
}
}
function bindAttrToFileInput(fileElem) {
if (attr.ngfMultiple) fileElem.attr('multiple', $parse(attr.ngfMultiple)(scope));
if (attr.ngfCapture) fileElem.attr('capture', $parse(attr.ngfCapture)(scope));
if (attr.accept) fileElem.attr('accept', attr.accept);
for (var i = 0; i < elem[0].attributes.length; i++) {
var attribute = elem[0].attributes[i];
if ((isInputTypeFile() && attribute.name !== 'type') ||
(attribute.name !== 'type' && attribute.name !== 'class' &&
attribute.name !== 'id' && attribute.name !== 'style')) {
fileElem.attr(attribute.name, attribute.value);
}
}
}
function createFileInput(evt, resetOnClick) {
if (!resetOnClick && (evt || isInputTypeFile())) return elem.$$ngfRefElem || elem;
var fileElem = angular.element('<input type="file">');
bindAttrToFileInput(fileElem);
if (isInputTypeFile()) {
elem.replaceWith(fileElem);
elem = fileElem;
fileElem.attr('__ngf_gen__', true);
$compile(elem)(scope);
} else {
fileElem.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')
.css('width', '0px').css('height', '0px').css('z-index', '-100000').css('border', 'none')
.css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');
if (elem.$$ngfRefElem) {
elem.$$ngfRefElem.remove();
}
elem.$$ngfRefElem = fileElem;
document.body.appendChild(fileElem[0]);
}
return fileElem;
}
function resetModel(evt) {
updateModel($parse, $timeout, scope, ngModel, attr, attr.ngfChange || attr.ngfSelect, [], [], evt, true);
}
function clickHandler(evt) {
if (elem.attr('disabled') || disabled) return false;
if (evt != null) {
evt.preventDefault();
evt.stopPropagation();
}
var resetOnClick = $parse(attr.ngfResetOnClick)(scope) !== false;
var fileElem = createFileInput(evt, resetOnClick);
function clickAndAssign(evt) {
if (evt) {
fileElem[0].click();
}
if (isInputTypeFile() || !evt) {
elem.bind('click touchend', clickHandler);
}
}
if (fileElem) {
if (!evt || resetOnClick) fileElem.bind('change', changeFn);
if (evt && resetOnClick && $parse(attr.ngfResetModelOnClick)(scope) !== false) resetModel(evt);
// fix for android native browser < 4.4
if (shouldClickLater(navigator.userAgent)) {
setTimeout(function () {
clickAndAssign(evt);
}, 0);
} else {
clickAndAssign(evt);
}
}
return false;
}
if (window.FileAPI && window.FileAPI.ngfFixIE) {
window.FileAPI.ngfFixIE(elem, createFileInput, bindAttrToFileInput, changeFn);
} else {
clickHandler();
//if (!isInputTypeFile()) {
// elem.bind('click touchend', clickHandler);
//}
}
}
function shouldClickLater(ua) {
// android below 4.4
var m = ua.match(/Android[^\d]*(\d+)\.(\d+)/);
if (m && m.length > 2) {
return parseInt(m[1]) < 4 || (parseInt(m[1]) === 4 && parseInt(m[2]) < 4);
}
// safari on windows
return /.*Windows.*Safari.*/.test(ua);
}
ngFileUpload.validate = function (scope, $parse, attr, file, evt) {
function globStringToRegex(str) {
if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
return str.substring(1, str.length - 1);
}
var split = str.split(','), result = '';
if (split.length > 1) {
for (var i = 0; i < split.length; i++) {
result += '(' + globStringToRegex(split[i]) + ')';
if (i < split.length - 1) {
result += '|';
}
}
} else {
if (str.indexOf('.') === 0) {
str = '*' + str;
}
result = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + '-]', 'g'), '\\$&') + '$';
result = result.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
}
return result;
}
var accept = $parse(attr.ngfAccept)(scope, {$file: file, $event: evt});
var fileSizeMax = $parse(attr.ngfMaxSize)(scope, {$file: file, $event: evt}) || 9007199254740991;
var fileSizeMin = $parse(attr.ngfMinSize)(scope, {$file: file, $event: evt}) || -1;
if (accept != null && angular.isString(accept)) {
var regexp = new RegExp(globStringToRegex(accept), 'gi');
accept = (file.type != null && regexp.test(file.type.toLowerCase())) ||
(file.name != null && regexp.test(file.name.toLowerCase()));
}
return (accept == null || accept) && (file.size == null || (file.size < fileSizeMax && file.size > fileSizeMin));
};
ngFileUpload.updateModel = function ($parse, $timeout, scope, ngModel, attr, fileChange,
files, rejFiles, evt, noDelay) {
function update() {
if ($parse(attr.ngfKeep)(scope) === true) {
var prevFiles = (ngModel.$modelValue || []).slice(0);
if (!files || !files.length) {
files = prevFiles;
} else if ($parse(attr.ngfKeepDistinct)(scope) === true) {
var len = prevFiles.length;
for (var i = 0; i < files.length; i++) {
for (var j = 0; j < len; j++) {
if (files[i].name === prevFiles[j].name) break;
}
if (j === len) {
prevFiles.push(files[i]);
}
}
files = prevFiles;
} else {
files = prevFiles.concat(files);
}
}
if (ngModel) {
$parse(attr.ngModel).assign(scope, files);
$timeout(function () {
if (ngModel) {
ngModel.$setViewValue(files != null && files.length === 0 ? null : files);
}
});
}
if (attr.ngModelRejected) {
$parse(attr.ngModelRejected).assign(scope, rejFiles);
}
if (fileChange) {
$parse(fileChange)(scope, {
$files: files,
$rejectedFiles: rejFiles,
$event: evt
});
}
}
if (noDelay) {
update();
} else {
$timeout(function () {
update();
});
}
};
var validate = ngFileUpload.validate;
var updateModel = ngFileUpload.updateModel;
})();
(function () {
var validate = ngFileUpload.validate;
var updateModel = ngFileUpload.updateModel;
ngFileUpload.directive('ngfDrop', ['$parse', '$timeout', '$location', function ($parse, $timeout, $location) {
return {
restrict: 'AEC',
require: '?ngModel',
link: function (scope, elem, attr, ngModel) {
linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location);
}
};
}]);
ngFileUpload.directive('ngfNoFileDrop', function () {
return function (scope, elem) {
if (dropAvailable()) elem.css('display', 'none');
};
});
ngFileUpload.directive('ngfDropAvailable', ['$parse', '$timeout', function ($parse, $timeout) {
return function (scope, elem, attr) {
if (dropAvailable()) {
var fn = $parse(attr.ngfDropAvailable);
$timeout(function () {
fn(scope);
if (fn.assign) {
fn.assign(scope, true);
}
});
}
};
}]);
function linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location) {
var available = dropAvailable();
if (attr.dropAvailable) {
$timeout(function () {
if (scope[attr.dropAvailable]) {
scope[attr.dropAvailable].value = available;
} else {
scope[attr.dropAvailable] = available;
}
});
}
if (!available) {
if ($parse(attr.ngfHideOnDropNotAvailable)(scope) === true) {
elem.css('display', 'none');
}
return;
}
var disabled = false;
if (attr.ngfDrop.search(/\W+$files\W+/) === -1) {
scope.$watch(attr.ngfDrop, function(val) {
disabled = val === false;
});
}
var leaveTimeout = null;
var stopPropagation = $parse(attr.ngfStopPropagation);
var dragOverDelay = 1;
var actualDragOverClass;
elem[0].addEventListener('dragover', function (evt) {
if (elem.attr('disabled') || disabled) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
// handling dragover events from the Chrome download bar
if (navigator.userAgent.indexOf('Chrome') > -1) {
var b = evt.dataTransfer.effectAllowed;
evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';
}
$timeout.cancel(leaveTimeout);
if (!scope.actualDragOverClass) {
actualDragOverClass = calculateDragOverClass(scope, attr, evt);
}
elem.addClass(actualDragOverClass);
}, false);
elem[0].addEventListener('dragenter', function (evt) {
if (elem.attr('disabled') || disabled) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
}, false);
elem[0].addEventListener('dragleave', function () {
if (elem.attr('disabled') || disabled) return;
leaveTimeout = $timeout(function () {
elem.removeClass(actualDragOverClass);
actualDragOverClass = null;
}, dragOverDelay || 1);
}, false);
elem[0].addEventListener('drop', function (evt) {
if (elem.attr('disabled') || disabled) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
elem.removeClass(actualDragOverClass);
actualDragOverClass = null;
extractFiles(evt, function (files, rejFiles) {
updateModel($parse, $timeout, scope, ngModel, attr,
attr.ngfChange || attr.ngfDrop, files, rejFiles, evt);
}, $parse(attr.ngfAllowDir)(scope) !== false, attr.multiple || $parse(attr.ngfMultiple)(scope));
}, false);
function calculateDragOverClass(scope, attr, evt) {
var accepted = true;
var items = evt.dataTransfer.items;
if (items != null) {
for (var i = 0; i < items.length && accepted; i++) {
accepted = accepted &&
(items[i].kind === 'file' || items[i].kind === '') &&
validate(scope, $parse, attr, items[i], evt);
}
}
var clazz = $parse(attr.ngfDragOverClass)(scope, {$event: evt});
if (clazz) {
if (clazz.delay) dragOverDelay = clazz.delay;
if (clazz.accept) clazz = accepted ? clazz.accept : clazz.reject;
}
return clazz || attr.ngfDragOverClass || 'dragover';
}
function extractFiles(evt, callback, allowDir, multiple) {
var files = [], rejFiles = [], items = evt.dataTransfer.items, processing = 0;
function addFile(file) {
if (validate(scope, $parse, attr, file, evt)) {
files.push(file);
} else {
rejFiles.push(file);
}
}
function traverseFileTree(files, entry, path) {
if (entry != null) {
if (entry.isDirectory) {
var filePath = (path || '') + entry.name;
addFile({name: entry.name, type: 'directory', path: filePath});
var dirReader = entry.createReader();
var entries = [];
processing++;
var readEntries = function () {
dirReader.readEntries(function (results) {
try {
if (!results.length) {
for (var i = 0; i < entries.length; i++) {
traverseFileTree(files, entries[i], (path ? path : '') + entry.name + '/');
}
processing--;
} else {
entries = entries.concat(Array.prototype.slice.call(results || [], 0));
readEntries();
}
} catch (e) {
processing--;
console.error(e);
}
}, function () {
processing--;
});
};
readEntries();
} else {
processing++;
entry.file(function (file) {
try {
processing--;
file.path = (path ? path : '') + file.name;
addFile(file);
} catch (e) {
processing--;
console.error(e);
}
}, function () {
processing--;
});
}
}
}
if (items && items.length > 0 && $location.protocol() !== 'file') {
for (var i = 0; i < items.length; i++) {
if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {
var entry = items[i].webkitGetAsEntry();
if (entry.isDirectory && !allowDir) {
continue;
}
if (entry != null) {
traverseFileTree(files, entry);
}
} else {
var f = items[i].getAsFile();
if (f != null) addFile(f);
}
if (!multiple && files.length > 0) break;
}
} else {
var fileList = evt.dataTransfer.files;
if (fileList != null) {
for (var j = 0; j < fileList.length; j++) {
addFile(fileList.item(j));
if (!multiple && files.length > 0) {
break;
}
}
}
}
var delays = 0;
(function waitForProcess(delay) {
$timeout(function () {
if (!processing) {
if (!multiple && files.length > 1) {
i = 0;
while (files[i].type === 'directory') i++;
files = [files[i]];
}
callback(files, rejFiles);
} else {
if (delays++ * 10 < 20 * 1000) {
waitForProcess(10);
}
}
}, delay || 0);
})();
}
}
ngFileUpload.directive('ngfSrc', ['$parse', '$timeout', function ($parse, $timeout) {
return {
restrict: 'AE',
link: function (scope, elem, attr) {
if (window.FileReader) {
scope.$watch(attr.ngfSrc, function (file) {
if (file &&
validate(scope, $parse, attr, file, null) &&
(!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) &&
(!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) {
$timeout(function () {
//prefer URL.createObjectURL for handling refrences to files of all sizes
//since it doesn´t build a large string in memory
var URL = window.URL || window.webkitURL;
if (URL && URL.createObjectURL) {
elem.attr('src', URL.createObjectURL(file));
} else {
var fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function (e) {
$timeout(function () {
elem.attr('src', e.target.result);
});
};
}
});
} else {
elem.attr('src', attr.ngfDefaultSrc || '');
}
});
}
}
};
}]);
function dropAvailable() {
var div = document.createElement('div');
return ('draggable' in div) && ('ondrop' in div);
}
})();
/**!
* AngularJS file upload/drop directive and service with progress and abort
* FileAPI Flash shim for old browsers not supporting FormData
* @author Danial <danial.farid@gmail.com>
* @version 5.0.8
*/
(function () {
/** @namespace FileAPI.noContentTimeout */
function patchXHR(fnName, newFn) {
window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
}
function redefineProp(xhr, prop, fn) {
try {
Object.defineProperty(xhr, prop, {get: fn});
} catch (e) {/*ignore*/
}
}
if (!window.FileAPI) {
window.FileAPI = {};
}
FileAPI.shouldLoad = (window.XMLHttpRequest && !window.FormData) || FileAPI.forceLoad;
if (FileAPI.shouldLoad) {
var initializeUploadListener = function (xhr) {
if (!xhr.__listeners) {
if (!xhr.upload) xhr.upload = {};
xhr.__listeners = [];
var origAddEventListener = xhr.upload.addEventListener;
xhr.upload.addEventListener = function (t, fn) {
xhr.__listeners[t] = fn;
if (origAddEventListener) origAddEventListener.apply(this, arguments);
};
}
};
patchXHR('open', function (orig) {
return function (m, url, b) {
initializeUploadListener(this);
this.__url = url;
try {
orig.apply(this, [m, url, b]);
} catch (e) {
if (e.message.indexOf('Access is denied') > -1) {
this.__origError = e;
orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);
}
}
};
});
patchXHR('getResponseHeader', function (orig) {
return function (h) {
return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));
};
});
patchXHR('getAllResponseHeaders', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('abort', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('setRequestHeader', function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
initializeUploadListener(this);
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
this.__requestHeaders = this.__requestHeaders || {};
this.__requestHeaders[header] = value;
orig.apply(this, arguments);
}
};
});
patchXHR('send', function (orig) {
return function () {
var xhr = this;
if (arguments[0] && arguments[0].__isFileAPIShim) {
var formData = arguments[0];
var config = {
url: xhr.__url,
jsonp: false, //removes the callback form param
cache: true, //removes the ?fileapiXXX in the url
complete: function (err, fileApiXHR) {
xhr.__completed = true;
if (!err && xhr.__listeners.load)
xhr.__listeners.load({
type: 'load',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (!err && xhr.__listeners.loadend)
xhr.__listeners.loadend({
type: 'loadend',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (err === 'abort' && xhr.__listeners.abort)
xhr.__listeners.abort({
type: 'abort',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function () {
return (fileApiXHR.status === 0 && err && err !== 'abort') ? 500 : fileApiXHR.status;
});
if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function () {
return fileApiXHR.statusText;
});
redefineProp(xhr, 'readyState', function () {
return 4;
});
if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function () {
return fileApiXHR.response;
});
var resp = fileApiXHR.responseText || (err && fileApiXHR.status === 0 && err !== 'abort' ? err : undefined);
redefineProp(xhr, 'responseText', function () {
return resp;
});
redefineProp(xhr, 'response', function () {
return resp;
});
if (err) redefineProp(xhr, 'err', function () {
return err;
});
xhr.__fileApiXHR = fileApiXHR;
if (xhr.onreadystatechange) xhr.onreadystatechange();
if (xhr.onload) xhr.onload();
},
progress: function (e) {
e.target = xhr;
if (xhr.__listeners.progress) xhr.__listeners.progress(e);
xhr.__total = e.total;
xhr.__loaded = e.loaded;
if (e.total === e.loaded) {
// fix flash issue that doesn't call complete if there is no response text from the server
var _this = this;
setTimeout(function () {
if (!xhr.__completed) {
xhr.getAllResponseHeaders = function () {
};
_this.complete(null, {status: 204, statusText: 'No Content'});
}
}, FileAPI.noContentTimeout || 10000);
}
},
headers: xhr.__requestHeaders
};
config.data = {};
config.files = {};
for (var i = 0; i < formData.data.length; i++) {
var item = formData.data[i];
if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {
config.files[item.key] = item.val;
} else {
config.data[item.key] = item.val;
}
}
setTimeout(function () {
if (!FileAPI.hasFlash) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
xhr.__fileApiXHR = FileAPI.upload(config);
}, 1);
} else {
if (this.__origError) {
throw this.__origError;
}
orig.apply(xhr, arguments);
}
};
});
window.XMLHttpRequest.__isFileAPIShim = true;
window.FormData = FormData = function () {
return {
append: function (key, val, name) {
if (val.__isFileAPIBlobShim) {
val = val.data[0];
}
this.data.push({
key: key,
val: val,
name: name
});
},
data: [],
__isFileAPIShim: true
};
};
window.Blob = Blob = function (b) {
return {
data: b,
__isFileAPIBlobShim: true
};
};
}
})();
(function () {
/** @namespace FileAPI.forceLoad */
/** @namespace window.FileAPI.jsUrl */
/** @namespace window.FileAPI.jsPath */
function isInputTypeFile(elem) {
return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';
}
function hasFlash() {
try {
var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if (fo) return true;
} catch (e) {
if (navigator.mimeTypes['application/x-shockwave-flash'] !== undefined) return true;
}
return false;
}
function getOffset(obj) {
var left = 0, top = 0;
if (window.jQuery) {
return jQuery(obj).offset();
}
if (obj.offsetParent) {
do {
left += (obj.offsetLeft - obj.scrollLeft);
top += (obj.offsetTop - obj.scrollTop);
obj = obj.offsetParent;
} while (obj);
}
return {
left: left,
top: top
};
}
if (FileAPI.shouldLoad) {
//load FileAPI
if (FileAPI.forceLoad) {
FileAPI.html5 = false;
}
if (!FileAPI.upload) {
var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;
if (window.FileAPI.jsUrl) {
jsUrl = window.FileAPI.jsUrl;
} else if (window.FileAPI.jsPath) {
basePath = window.FileAPI.jsPath;
} else {
for (i = 0; i < allScripts.length; i++) {
src = allScripts[i].src;
index = src.search(/\/ng\-file\-upload[\-a-zA-z0-9\.]*\.js/);
if (index > -1) {
basePath = src.substring(0, index + 1);
break;
}
}
}
if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;
script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');
document.getElementsByTagName('head')[0].appendChild(script);
FileAPI.hasFlash = hasFlash();
}
FileAPI.ngfFixIE = function (elem, createFileElemFn, bindAttr, changeFn) {
if (!hasFlash()) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
var makeFlashInput = function () {
if (elem.attr('disabled')) {
elem.$$ngfRefElem.removeClass('js-fileapi-wrapper');
} else {
var fileElem = elem.$$ngfRefElem;
if (!fileElem) {
fileElem = elem.$$ngfRefElem = createFileElemFn();
fileElem.addClass('js-fileapi-wrapper');
if (!isInputTypeFile(elem)) {
// if (fileElem.parent().css('position') === '' || fileElem.parent().css('position') === 'static') {
// fileElem.parent().css('position', 'relative');
// }
// elem.parent()[0].insertBefore(fileElem[0], elem[0]);
// elem.css('overflow', 'hidden');
}
setTimeout(function () {
fileElem.bind('mouseenter', makeFlashInput);
}, 10);
fileElem.bind('change', function (evt) {
fileApiChangeFn.apply(this, [evt]);
changeFn.apply(this, [evt]);
// alert('change' + evt);
});
} else {
bindAttr(elem.$$ngfRefElem);
}
if (!isInputTypeFile(elem)) {
fileElem.css('position', 'absolute')
.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')
.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))
.css('overflow', 'hidden').css('z-index', '900000')
.css('visibility', 'visible');
}
}
};
elem.bind('mouseenter', makeFlashInput);
var fileApiChangeFn = function (evt) {
var files = FileAPI.getFiles(evt);
//just a double check for #233
for (var i = 0; i < files.length; i++) {
if (files[i].size === undefined) files[i].size = 0;
if (files[i].name === undefined) files[i].name = 'file';
if (files[i].type === undefined) files[i].type = 'undefined';
}
if (!evt.target) {
evt.target = {};
}
evt.target.files = files;
// if evt.target.files is not writable use helper field
if (evt.target.files !== files) {
evt.__files_ = files;
}
(evt.__files_ || evt.target.files).item = function (i) {
return (evt.__files_ || evt.target.files)[i] || null;
};
};
};
FileAPI.disableFileInput = function (elem, disable) {
if (disable) {
elem.removeClass('js-fileapi-wrapper');
} else {
elem.addClass('js-fileapi-wrapper');
}
};
}
})();
if (!window.FileReader) {
window.FileReader = function () {
var _this = this, loadStarted = false;
this.listeners = {};
this.addEventListener = function (type, fn) {
_this.listeners[type] = _this.listeners[type] || [];
_this.listeners[type].push(fn);
};
this.removeEventListener = function (type, fn) {
if (_this.listeners[type]) _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);
};
this.dispatchEvent = function (evt) {
var list = _this.listeners[evt.type];
if (list) {
for (var i = 0; i < list.length; i++) {
list[i].call(_this, evt);
}
}
};
this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;
var constructEvent = function (type, evt) {
var e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error};
if (evt.result != null) e.target.result = evt.result;
return e;
};
var listener = function (evt) {
if (!loadStarted) {
loadStarted = true;
if (_this.onloadstart) _this.onloadstart(constructEvent('loadstart', evt));
}
var e;
if (evt.type === 'load') {
if (_this.onloadend) _this.onloadend(constructEvent('loadend', evt));
e = constructEvent('load', evt);
if (_this.onload) _this.onload(e);
_this.dispatchEvent(e);
} else if (evt.type === 'progress') {
e = constructEvent('progress', evt);
if (_this.onprogress) _this.onprogress(e);
_this.dispatchEvent(e);
} else {
e = constructEvent('error', evt);
if (_this.onerror) _this.onerror(e);
_this.dispatchEvent(e);
}
};
this.readAsArrayBuffer = function (file) {
FileAPI.readAsBinaryString(file, listener);
};
this.readAsBinaryString = function (file) {
FileAPI.readAsBinaryString(file, listener);
};
this.readAsDataURL = function (file) {
FileAPI.readAsDataURL(file, listener);
};
this.readAsText = function (file) {
FileAPI.readAsText(file, listener);
};
};
}