Как стать автором
Обновить

Комментарии 26

Что это делает в хабе «JavaScript»?
Наверно coffee-филы негодуют, но я с вами согласен, в хабе JavaScript, я ожидаю увидеть именно его, а не ломать глаза об это.
Scss в хабе хабе CSS нормально смотрится. Хотя пометку про наличие coffee стоило написать.
В дополнение к крутым плагинам стоит упомянуть FileAPI хабраюзера RubaXa. Там и кроссбраузерность, и Drag'n'Drop, и много чего другого с возможностью настраивать это как хочешь.
И нет зависимости от jquery
и plupload, который поддерживает кучу транспортов, загрузку частями, Drag'n'Drop, сжатия изображений на клиенте, и еще кучу всего, и не требует jquery
И просит денег… а так, да, хорошая штука, если вам нужно коробочное решение (плагин).
Ок, спасибо, добавлю вариант как накоплю на UP
Что за синтаксис, что за каша?
Я понимаю язык даёт возможность так писать и т.д.?
Но зачем, особенно если это «идёт в люди»?
:(

З.Ы. И отчего используется 2 языка для комментариев кода?
Посмотрел на хаб, посмотрел на код -> получил разрыв шаблона не углядев js… Предупреждать надо, что код на coffeescript
Извините, habracut съел текст. Подправил
Так унесите его в тематический хаб.
CoffeScript не люблю. Понимаю, но не люблю. А кофе люблю.
Ребят, на сайте кофе есть прям «менюха» для таких как мы. Try CoffeScript.

Результат трансформации.
var Readers, Senders;

Senders = {
  _makeForm: function(options) {
    return $('<form>', {
      method: options.method,
      enctype: 'multipart/form-data'
    }).append(options.input.clone());
  },
  _sendData: function(options, data, file) {
    var dfd, xhr;
    xhr = new XMLHttpRequest();
    dfd = $.Deferred();
    xhr.onload = xhr.onerror = function() {
      return dfd[this.status === 200 && 'resolve' || 'reject'](this.response, file);
    };
    if (xhr.upload) {
      xhr.upload.onprogress = function(e) {
        return dfd.notify(e, file);
      };
    } else {
      options.no_progress = true;
    }
    xhr.open(options.method, options.url + '?name=' + (options.file_name || file.name), true);
    xhr.responseType = 'text';
    xhr.send(data);
    return dfd.promise();
  },
  iframe: function(options) {
    var $form, dfd, id;
    if (!(options.input && options.input.value)) {
      return false;
    }
    options.no_progress = true;
    id = 'frame' + Math.random();
    $form = Senders._makeForm(options).attr({
      target: id,
      action: options.url
    });
    $('<iframe>', {
      name: id
    }).appendTo($form).on('load', function() {
      var e, response;
      try {
        response = this.contents();
        if (!(response.length && response[0].firstChild)) {
          throw new Error;
        }
        return dfd.resolve(response, {
          name: options.input.value
        });
      } catch (_error) {
        e = _error;
        return dfd.reject(response, {
          name: options.input.value
        });
      }
    });
    $form.submit();
    return (dfd = $.Deferred()).promise();
  },
  formDataForm: function(options) {
    var form;
    if (!(options.input && options.input.value && window.FormData)) {
      return false;
    }
    form = options.input.form || Senders._makeForm(options).get(0);
    return Senders._sendData(options, new FormData(form), {
      name: options.input.value
    });
  },
  formDataFile: function(options) {
    if (!(options.files && options.files.length && window.FormData)) {
      return false;
    }
    return options.files.map(function(f) {
      var formData;
      formData = new FormData();
      formData.append(options.name, f);
      return Senders._sendData($.extend(options, {
        file_name: f.name
      }), formData, f);
    });
  },
  xhrFile: function(options) {
    if (!(options.files && options.files.length && window.ProgressEvent && window.FileReader)) {
      return false;
    }
    return $.map(options.files, function(file) {
      return Senders._sendData(options, file, file);
    });
  }
};

Readers = {
  input: function(options) {
    if (!options.input.value) {
      return false;
    }
    return $.Deferred().resolve([]).promise();
  },
  file: function(options) {
    var files;
    files = $.makeArray($(options.input).prop('files'));
    if (!files.length) {
      return false;
    }
    if (files[0].name === void 0 && files[0].fileName) {
      $.each(files, function(index, file) {
        file.name = file.fileName;
        return file.size = file.fileSize;
      });
    }
    return $.Deferred().resolve(files).promise();
  },
  entry: function(options) {
    var readEntries, roots;
    roots = $(options.input).prop('webkitEntries') || $(options.input).prop('entries');
    if (!(roots && roots.length > 0)) {
      return false;
    }
    readEntries = function(entries, path) {
      if (path == null) {
        path = '';
      }
      return $.when.apply($, $.map(entries, function(entry) {
        var dfd, errorHandler, resolveHandler;
        dfd = $.Deferred();
        errorHandler = function(e) {
          if (e && !e.entry) {
            e.entry = entry;
          }
          return dfd.resolve([e]);
        };
        resolveHandler = function(file) {
          file.relativePath = path;
          return dfd.resolve(file);
        };
        if (entry.isFile) {
          entry._file && resolveHandler(entry._file) || entry.file(resolveHandler, errorHandler);
        } else if (entry.isDirectory) {
          entry.createReader().readEntries(function(entries) {
            return readEntries(entries, path + entry.name + '/').done(function(files) {
              return dfd.resolve(files);
            }).fail(errorHandler);
          }, errorHandler);
        } else {
          dfd.resolve([]);
        }
        return dfd.promise();
      })).pipe(function() {
        return Array.prototype.concat.apply([], arguments);
      });
    };
    return readEntries(roots).promise();
  }
};

({
  Uploader: {
    _responsibilityChain: function(options, chain, name) {
      var stream;
      if (name == null) {
        name = false;
      }
      stream = false;
      $.each(chain, (function(_this) {
        return function(i, func) {
          if (stream = func(options)) {
            if (name) {
              _this[name] = func;
            }
            return false;
          }
        };
      })(this));
      return stream;
    },
    readers: [entry, file, input],
    read: function(options) {
      return this._responsibilityChain(options, this.readers, 'read');
    },
    senders: [xhrFile, formDataFile, formDataForm, iframe],
    send: function(options) {
      return this._responsibilityChain(options, this.senders, 'send');
    },
    upload: function(options) {
      options = $.extend({
        method: 'POST',
        name: options.input && options.input.name
      }, options);
      return this.read(options).then((function(_this) {
        return function(files) {
          return $.when.apply($, _this.send($.extend(options, {
            files: files
          })));
        };
      })(this));
    }
  }
});




Одного не пойму, почему они назвали его Coffe Script. Неужели от любви к Кофе?
Да, mea culpa любителям, не Coffe, а Coffee. Pardon (фр.).
Автор, Вам спасибо за саму статью, конечно :)
Проблема в том, что Java отношения к JavaScript имеет такое же, какое и Swift от Apple имеет к одноименному скриптовому языку: кроме названия ничего общего.
Да я кагбэ в курсе :)
Просто игра слов, не более.
Но ведь Java это сорт кофе и разработчики просто построили ассоциативный ряд, точно также как и пакеты программ на Ruby назвали Gems, или пакеты egg для Python. Довольно популярная практика именования.
А я для статистики отпишусь, идите со своим кофе в свой хаб. Достали везде его пихать под видом JS!
Какая лицензия на код?
GNU GPL подойдет? Если нет — скажите какая подойдет. Правда код местами нерабочий))))
MIT
Забирайте по MIT.
Правда, напоминаю код нерабочий. Планируемая вторая часть статьи с более адекватным кодом пока в процессе с неопределенным сроком выхода.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории