Release
This commit is contained in:
206
client/core/chitalka-fb2/chitalka-fb2-parser.js
Normal file
206
client/core/chitalka-fb2/chitalka-fb2-parser.js
Normal 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);
|
||||
});
|
||||
Reference in New Issue
Block a user