This commit is contained in:
Oleg Mokhov
2015-06-20 12:26:08 +03:00
committed by mokhov
parent a716969f4e
commit f3546ef3a5
85 changed files with 16682 additions and 1 deletions

View File

@@ -0,0 +1,206 @@
/* global escape */
modules.define(
'chitalka-fb2-parser',
[
'chitalka',
'jquery',
'inherit',
'y-extend',
'unzip'
],
function (
provide,
Chitalka,
$,
inherit,
extend,
zip
) {
var TIMEOUT = 2 * 1000;
/**
* Функция выполняет трансформацию строки в XMLDocument
* @param {String} text
*
* @returns {Document} XMLDocument
*/
var _parseXml = (function () {
var parseXml;
if (window.DOMParser) {
parseXml = function (xmlStr) {
return (new window.DOMParser()).parseFromString(xmlStr, 'text/xml');
};
} else if (typeof window.ActiveXObject !== 'undefined' && new window.ActiveXObject('Microsoft.XMLDOM')) {
parseXml = function (xmlStr) {
var xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
xmlDoc.async = 'false';
xmlDoc.loadXML(xmlStr);
return xmlDoc;
};
} else {
parseXml = function () {
return null;
};
}
return parseXml;
})();
/**
* По расщирению файла проверяет,
* запакованный файл или нет
* @param {string} url
* @returns {boolean}
* @private
*/
var _isZipArchive = function (url) {
return /(\.zip)$/i.test(url);
};
var parserFb2 = {
unzip: function (url, encoding) {
var d = $.Deferred();
var isBase64 = /^data:/.test(url);
// наша ручка /data/ проксируется на http://partnersdnld.litres.ru/static/trials
//url = url.replace('http://partnersdnld.litres.ru/static/trials', '/data');
zip.workerScriptsPath = window.document.location.pathname + 'lib/';
zip.createReader((isBase64 ? new zip.Data64URIReader(url) : new zip.HttpReader(url)), function (reader) {
// get all entries from the zip
reader.getEntries(function (entries) {
if (!entries.length) {
return;
}
// get first entry content as text
entries[0].getData(new zip.TextWriter(encoding), function (str) {
// close the zip reader
reader.close(function () {
// onclose callback
d.resolve(str);
});
}, function (/*current, total*/) {
// onprogress callback
});
});
}, function (error) {
// onerror callback
d.reject(error);
});
return d.promise();
},
getXml: function (xmlStr) {
var d = $.Deferred();
var xml = _parseXml(xmlStr);
d.resolve(xml);
return d.promise();
},
/**
* Читает файл по урлу или DataURI,
* если файл в архиве - распаковывает.
* @param {string} obj
* @returns {Promise}
*/
readFile: function (obj) {
var url = obj.file ? obj.result : obj;
if (/^data:/.test(url)) {
return this._readAsDataUri(obj);
}
if (_isZipArchive(url)) {
return this.unzip(url);
}
return $.ajax({
url: url,
dataType: 'text',
contentType: 'text/plain',
timeout: TIMEOUT
});
},
/**
* Читает файл по DataURI
* @param {Object} obj
* @param {String} obj.url данные из файла
* @param {Blob} obj.file файл для чтения
*
* @returns {Promise}
*/
_readAsDataUri: function (obj) {
var file = obj.file;
var url = file ? obj.result : obj;
var mediaInfo = url.split(',')[0];
var data = url.substring(url.indexOf(',') + 1);
var encodingRegExp = /encoding=\"UTF\-8\"/;
// zip-архив
if (mediaInfo.indexOf('zip') > 0) {
// Сразу возвращаем промис unzip, но затем перепроверяем результат относительно кодировки
return this.unzip(url).then(function (res) {
// Если кодировка не UTF-8, то нужно перезиповать с учётом прочитанной кодировки
if (!encodingRegExp.test(res)) {
var encoding = /encoding="([^"]+)"/.exec(res)[1];
return this.unzip(url, encoding);
} else {
// Иначе результат
var d = $.Deferred();
d.resolve(res);
return d.promise();
}
}.bind(this));
// Иначе получили просто текст
} else {
var d = $.Deferred();
// Магия чтения DataURI
// INFO: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/atob
data = window.atob(data);
// Опять же если кодировка не соответствует, то нужно перечитать файл
if (!encodingRegExp.test(data)) {
var encoding = /encoding="([^"]+)"/.exec(data);
if (!encoding || !Array.isArray(encoding) || encoding.length > 1) {
d.reject('файл повреждён или книга неподдерживаемого формата');
} else {
encoding = encoding[1];
var reader = new FileReader();
reader.readAsText(file, encoding);
reader.onloadend = function () {
d.resolve(reader.result);
};
}
} else {
try {
var result = decodeURIComponent(escape(data));
d.resolve(result);
} catch (e) {
d.reject(e);
}
}
return d.promise();
}
}
};
provide(parserFb2);
});