mirror of
https://github.com/alexadam/save-as-ebook.git
synced 2025-09-10 17:34:47 +00:00
chrome & ff
This commit is contained in:
parent
2c4e0d023d
commit
a391509e5d
16 changed files with 404 additions and 8781 deletions
139
background.js
139
background.js
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
Called when the item has been created, or when creation failed due to an error.
|
||||
We'll just log success/failure here.
|
||||
*/
|
||||
function onCreated(n) {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.log("error creating item:" + chrome.runtime.lastError);
|
||||
} else {
|
||||
console.log("item created successfully");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the item has been removed, or when there was an error.
|
||||
We'll just log success or failure here.
|
||||
*/
|
||||
function onRemoved() {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.log("error removing item:" + chrome.runtime.lastError);
|
||||
} else {
|
||||
console.log("item removed successfully");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create all the context menu items.
|
||||
*/
|
||||
chrome.contextMenus.create({
|
||||
id: "whole-page",
|
||||
title: 'Whole Page',
|
||||
contexts: ["all"]
|
||||
}, onCreated);
|
||||
|
||||
chrome.contextMenus.create({
|
||||
id: "selection",
|
||||
title: "Selection",
|
||||
contexts: ["all"]
|
||||
}, onCreated);
|
||||
|
||||
chrome.contextMenus.create({
|
||||
id: "separator-1",
|
||||
type: "separator",
|
||||
contexts: ["all"]
|
||||
}, onCreated);
|
||||
|
||||
chrome.contextMenus.create({
|
||||
id: "edit-buffer",
|
||||
title: "edit Buffer",
|
||||
contexts: ["all"]
|
||||
}, onCreated);
|
||||
//
|
||||
// chrome.contextMenus.create({
|
||||
// id: "selection-to-buffer",
|
||||
// title: "Selection > Buffer",
|
||||
// contexts: ["all"]
|
||||
// }, onCreated);
|
||||
//
|
||||
// chrome.contextMenus.create({
|
||||
// id: "separator-2",
|
||||
// type: "separator",
|
||||
// contexts: ["all"]
|
||||
// }, onCreated);
|
||||
//
|
||||
// chrome.contextMenus.create({
|
||||
// id: "save-buffer",
|
||||
// title: "save Buffer",
|
||||
// contexts: ["all"]
|
||||
// }, onCreated);
|
||||
|
||||
|
||||
/*
|
||||
Set a colored border on the document in the given tab.
|
||||
|
||||
Note that this only work on normal web pages, not special pages
|
||||
like about:debugging.
|
||||
*/
|
||||
// var blue = 'document.body.style.border = "5px solid blue"';
|
||||
// var green = 'document.body.style.border = "5px solid green"';
|
||||
//
|
||||
// function borderify(tabId, color) {
|
||||
// chrome.tabs.executeScript(tabId, {
|
||||
// file: 'test.js'
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// Toggle checkedState, and update the menu item's title
|
||||
// appropriately.
|
||||
//
|
||||
// Note that we should not have to maintain checkedState independently like
|
||||
// this, but have to because Firefox does not currently pass the "checked"
|
||||
// property into the event listener.
|
||||
// */
|
||||
// function updateCheckUncheck() {
|
||||
// checkedState = !checkedState;
|
||||
// if (checkedState) {
|
||||
// chrome.contextMenus.update("check-uncheck", {
|
||||
// title: chrome.i18n.getMessage("contextMenuItemUncheckMe"),
|
||||
// });
|
||||
// } else {
|
||||
// chrome.contextMenus.update("check-uncheck", {
|
||||
// title: chrome.i18n.getMessage("contextMenuItemCheckMe"),
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
The click event listener, where we perform the appropriate action given the
|
||||
ID of the menu item that was clicked.
|
||||
*/
|
||||
chrome.contextMenus.onClicked.addListener(function(info, tab) {
|
||||
switch (info.menuItemId) {
|
||||
case "whole-page":
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {type: "whole-page"});
|
||||
});
|
||||
break;
|
||||
case "selection":
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {type: "selection"});
|
||||
});
|
||||
break;
|
||||
case "selection-to-buffer":
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {type: "selection-to-buffer"});
|
||||
});
|
||||
break;
|
||||
case "save-buffer":
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {type: "save-buffer"});
|
||||
});
|
||||
break;
|
||||
case "edit-buffer":
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {type: "show-buffer"});
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
|
@ -8,13 +8,18 @@
|
|||
<h1>Chapter Editor</h1>
|
||||
<div>
|
||||
<ol id="chapters">
|
||||
|
||||
</ol>
|
||||
</div>
|
||||
<div class="">
|
||||
<button id="closeButton" type="button" name="button">Cancel</button>
|
||||
<button id="saveButton" type="button" name="button">Save</button>
|
||||
</div>
|
||||
<script src="jquery.js" charset="utf-8"></script>
|
||||
<script src="filesaver.js" charset="utf-8"></script>
|
||||
<script src="jszip.js" charset="utf-8"></script>
|
||||
<script src="jszip-utils.js" charset="utf-8"></script>
|
||||
<script src="utils.js" charset="utf-8"></script>
|
||||
<script src="saveEbook.js" charset="utf-8"></script>
|
||||
<script src="editor.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,40 +1,30 @@
|
|||
// var chapterHolder = document.getElementById('chapters');
|
||||
var list = document.getElementById('chapters');
|
||||
var title = localStorage.getItem('title');
|
||||
if (title === null) {
|
||||
title = [];
|
||||
} else {
|
||||
title = JSON.parse(title);
|
||||
}
|
||||
var allPages = getEbookPages();
|
||||
|
||||
for (var i = 0; i < title.length; i++) {
|
||||
console.log(allPages.length);
|
||||
|
||||
for (var i = 0; i < allPages.length; i++) {
|
||||
if (!allPages[i]) {
|
||||
continue;
|
||||
}
|
||||
var listItem = document.createElement('li');
|
||||
var label = document.createElement('span');
|
||||
label.innerHTML = title[i].title;
|
||||
label.innerHTML = allPages[i].title;
|
||||
listItem.appendChild(label);
|
||||
list.appendChild(listItem);
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('closeButton').onclick = function () {
|
||||
chrome.tabs.query({
|
||||
currentWindow: true,
|
||||
active: true
|
||||
// Select active tab of the current window
|
||||
}, function(tab) {
|
||||
chrome.tabs.sendMessage(
|
||||
// Send a message to the content script
|
||||
tab[0].id, { line: 'countparas' }
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
browser.runtime.onMessage.addListener(function(request) {
|
||||
console.log('cccccc', request);
|
||||
|
||||
|
||||
});
|
||||
|
||||
document.getElementById('saveButton').onclick = function () {
|
||||
window.open(window.location, '_self').close();
|
||||
};
|
||||
|
||||
document.getElementById('saveButton').onclick = function () {
|
||||
try {
|
||||
buildEbook();
|
||||
// window.open(window.location, '_self').close();
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
};
|
||||
|
|
257
chapter-editor/getInnerHtml.js
Normal file
257
chapter-editor/getInnerHtml.js
Normal file
|
@ -0,0 +1,257 @@
|
|||
var allImgSrc = {};
|
||||
//////
|
||||
|
||||
function getCurrentUrl() {
|
||||
var url = window.location.href;
|
||||
if (url.indexOf('?') > 0) {
|
||||
url = window.location.href.split('?')[0];
|
||||
}
|
||||
url = url.substring(0, url.lastIndexOf('/')+1);
|
||||
return url;
|
||||
}
|
||||
|
||||
function getFileExtension(fileName) {
|
||||
var tmpFileName = fileName.split('.').pop();
|
||||
if (tmpFileName.indexOf('?') > 0) {
|
||||
tmpFileName = tmpFileName.split('?')[0];
|
||||
}
|
||||
if (tmpFileName.trim() === '') {
|
||||
return 'jpg'; //TODO
|
||||
}
|
||||
return tmpFileName;
|
||||
}
|
||||
|
||||
function getImageSrc(srcTxt) {
|
||||
if (!srcTxt) {
|
||||
return '';
|
||||
}
|
||||
allImgSrc[srcTxt] = 'img-' + (Math.floor(Math.random()*1000000)) + '.' + getFileExtension(srcTxt);
|
||||
return '../images/' + allImgSrc[srcTxt];
|
||||
}
|
||||
|
||||
function getHref(hrefTxt) {
|
||||
if (!hrefTxt) {
|
||||
return '';
|
||||
}
|
||||
if (hrefTxt.indexOf('#') === 0) {
|
||||
hrefTxt = window.location.href + hrefTxt;
|
||||
}
|
||||
if (hrefTxt.indexOf('/') === 0) {
|
||||
hrefTxt = window.location.protocol + '//' + window.location.hostname + hrefTxt;
|
||||
}
|
||||
// hrefTxt = escape(hrefTxt); // TODO
|
||||
return hrefTxt;
|
||||
}
|
||||
|
||||
function force(contentString) {
|
||||
try {
|
||||
var tagOpen = '@@@';
|
||||
var tagClose = '###';
|
||||
var inlineElements = ['h1', 'h2', 'h3', 'sup', 'b', 'i', 'em', 'code', 'pre', 'p'];
|
||||
|
||||
var $content = $(contentString);
|
||||
|
||||
$content.find('img').each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + 'img src="' + getImageSrc($(elem).attr('src')) + '"' + tagClose + tagOpen + '/img' + tagClose + '</span>');
|
||||
});
|
||||
|
||||
$content.find('a').each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + 'a href="' + getHref($(elem).attr('href')) + '"' + tagClose + $(elem).html() + tagOpen + '/a' + tagClose + '</span>');
|
||||
});
|
||||
|
||||
if ($('*').length < 3000) { // TODO
|
||||
inlineElements.forEach(function (tagName) {
|
||||
$content.find(tagName).each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + tagName + tagClose + $(elem).html() + tagOpen + '/' + tagName + tagClose + '</span>');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
contentString = $content.text();
|
||||
|
||||
var tagOpenRegex = new RegExp(tagOpen, 'gi');
|
||||
var tagCloseRegex = new RegExp(tagClose, 'gi');
|
||||
contentString = contentString.replace(tagOpenRegex, '<');
|
||||
contentString = contentString.replace(tagCloseRegex, '>');
|
||||
contentString = contentString.replace(/&/gi, '&'); // TODO ??
|
||||
contentString = contentString.replace(/&/gi, '&');
|
||||
|
||||
return contentString;
|
||||
} catch(e) {
|
||||
console.log('ERROR');
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
|
||||
function sanitize(rawContentString) {
|
||||
allImgSrc = {};
|
||||
var srcTxt = '';
|
||||
var dirty = null;
|
||||
try {
|
||||
// dirty = getHtmlAsString(rawContent);
|
||||
wdirty = $.parseHTML(rawContentString);
|
||||
$wdirty = $(wdirty);
|
||||
$wdirty.find('script, style, svg, canvas, noscript').remove();
|
||||
$wdirty.find('*:empty').not('img').remove();
|
||||
|
||||
dirty = '<div>' + $wdirty.html() + '</div>';
|
||||
|
||||
////////////////
|
||||
|
||||
|
||||
return force(dirty); // TODO
|
||||
|
||||
|
||||
// var dirty = '<div>' + document.getElementsByTagName('body')[0].innerHTML + '</div>';
|
||||
|
||||
var results = '';
|
||||
var lastFragment = '';
|
||||
var lastTag = '';
|
||||
var inList = false;
|
||||
var allowedTags = ['div', 'p', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'blockquote',
|
||||
'img', 'a', 'ol', 'ul', 'li', 'b', 'i', 'sup', 'strong', 'strike',
|
||||
'table', 'tr', 'td', 'th', 'thead', 'tbody', 'pre', 'em'
|
||||
];
|
||||
var allowedTextTags = ['h4', 'h5', 'h6', 'span'];
|
||||
|
||||
HTMLParser(dirty, {
|
||||
start: function(tag, attrs, unary) {
|
||||
lastTag = tag;
|
||||
if (allowedTags.indexOf(tag) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag === 'ol' || tag === 'ul') {
|
||||
inList = true;
|
||||
}
|
||||
if (tag === 'li' && !inList) {
|
||||
tag = 'p';
|
||||
}
|
||||
|
||||
var tattrs = null;
|
||||
if (tag === 'img') {
|
||||
tattrs = attrs.filter(function(attr) {
|
||||
return attr.name === 'src';
|
||||
}).map(function(attr) {
|
||||
return getImageSrc(attr.escaped);
|
||||
});
|
||||
lastFragment = tattrs.length === 0 ? '<img></img>' : '<img src="' + tattrs[0] + '" alt=""></img>';
|
||||
} else if (tag === 'a') {
|
||||
tattrs = attrs.filter(function(attr) {
|
||||
return attr.name === 'href';
|
||||
}).map(function(attr) {
|
||||
return getHref(attr.escaped);
|
||||
});
|
||||
lastFragment = tattrs.length === 0 ? '<a>' : '<a href="' + tattrs[0] + '">';
|
||||
} else {
|
||||
lastFragment = '<' + tag + '>';
|
||||
}
|
||||
|
||||
results += lastFragment;
|
||||
lastFragment = '';
|
||||
},
|
||||
end: function(tag) {
|
||||
if (allowedTags.indexOf(tag) < 0 || tag === 'img') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag === 'ol' || tag === 'ul') {
|
||||
inList = false;
|
||||
}
|
||||
if (tag === 'li' && !inList) {
|
||||
tag = 'p';
|
||||
}
|
||||
|
||||
results += "</" + tag + ">\n";
|
||||
},
|
||||
chars: function(text) {
|
||||
if (lastTag !== '' && allowedTags.indexOf(lastTag) < 0) {
|
||||
return;
|
||||
}
|
||||
results += text;
|
||||
},
|
||||
comment: function(text) {
|
||||
// results += "<!--" + text + "-->";
|
||||
}
|
||||
});
|
||||
|
||||
// results = results.replace(/<([^>]+?)>\s*<\/\1>/gim, '');
|
||||
results = results.replace(/&[a-z]+;/gim, '');
|
||||
|
||||
return results;
|
||||
|
||||
} catch (e) {
|
||||
console.trace();
|
||||
console.log(e);
|
||||
|
||||
return force(dirty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getContent(htmlContent) {
|
||||
try {
|
||||
var tmp = document.createElement('div');
|
||||
tmp.appendChild(htmlContent.cloneNode(true));
|
||||
var dirty = '<div>' + tmp.innerHTML + '</div>';
|
||||
return sanitize(dirty);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
function getPageUrl(url) {
|
||||
return url.toLowerCase().replace(/\s+/g,'_').replace(/[^a-z0-9_]/g,'') + Math.floor(Math.random() * 10000) + '.xhtml';
|
||||
}
|
||||
|
||||
function getPageTitle(inp) { //TODO
|
||||
return inp;
|
||||
}
|
||||
|
||||
function getSelectedNodes() {
|
||||
if (document.selection) {
|
||||
// return document.selection.createRange().parentElement();
|
||||
return document.selection.createRange();
|
||||
}
|
||||
var selection = window.getSelection();
|
||||
if (selection.rangeCount > 0) {
|
||||
var range = selection.getRangeAt(0);
|
||||
var selectionContents = range.cloneContents();
|
||||
return selectionContents;
|
||||
}
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
console.log('Extract Html...');
|
||||
allImgSrc = {};
|
||||
var result = {};
|
||||
var pageSrc = '';
|
||||
var tmpContent = '';
|
||||
|
||||
if (request.type === 'extract-page') {
|
||||
pageSrc = document.getElementsByTagName('body')[0];
|
||||
tmpContent = getContent(pageSrc);
|
||||
} else if (request.type === 'extract-selection') {
|
||||
pageSrc = getSelectedNodes();
|
||||
tmpContent = getContent(pageSrc);
|
||||
}
|
||||
|
||||
if (tmpContent.trim() === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
result = {
|
||||
url: getPageUrl(document.title),
|
||||
title: getPageTitle(document.title), //gatPageTitle(document.title),
|
||||
baseUrl: getCurrentUrl(),
|
||||
imgs: allImgSrc,
|
||||
content: tmpContent
|
||||
};
|
||||
|
||||
console.log('Html Extracted');
|
||||
sendResponse(result);
|
||||
});
|
|
@ -3,29 +3,63 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
.row {
|
||||
width: 320px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.menu-holder {
|
||||
padding: 5px;
|
||||
padding-right: 10px;
|
||||
margin: 0;
|
||||
width: 320px;
|
||||
/*height: 500px;*/
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: block;
|
||||
display: inline-block;
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.menu-item-full {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
ul, li {
|
||||
display: block;
|
||||
width: 300px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
border-bottom: solid 1px #ccc;
|
||||
padding: 5px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="menu-holder">
|
||||
<h3>Save as Ebook:</h3>
|
||||
<button id="savePage" type="button" name="button" class="menu-item">Save Page</button>
|
||||
<button id="saveSelection" type="button" name="button" class="menu-item">Save Selection</button>
|
||||
<div class="row">
|
||||
<b>Save as Ebook:</b>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button id="savePage" type="button" name="button" class="menu-item">Save Page</button>
|
||||
<button id="saveSelection" type="button" name="button" class="menu-item">Save Selection</button>
|
||||
</div>
|
||||
<hr/>
|
||||
<button id="pageChapter" type="button" name="button" class="menu-item">Add Page as Chapter</button>
|
||||
<button id="selectionChapter" type="button" name="button" class="menu-item">Add Selection as Chapter</button>
|
||||
<div class="row">
|
||||
<button id="pageChapter" type="button" name="button" class="menu-item">Add Page as Chapter</button>
|
||||
<button id="selectionChapter" type="button" name="button" class="menu-item">Add Selection as Chapter</button>
|
||||
</div>
|
||||
<hr/>
|
||||
<button id="editChapters" type="button" name="button" class="menu-item">Edit Chapters...</button>
|
||||
<div class="row">
|
||||
<button id="editChapters" type="button" name="button" class="menu-item-full">Edit Chapters...</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<ul id="chapters" class="menu-item-full"></ul>
|
||||
<button id="saveChapters" type="button" name="button" class="menu-item-full">Save Chapters</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -1,71 +1,95 @@
|
|||
var win = null;
|
||||
|
||||
document.getElementById("editChapters").onclick = function() {
|
||||
win = window.open(chrome.extension.getURL('chapter-editor/editor.html'), '_blank');
|
||||
win.focus();
|
||||
// win = window.open(chrome.extension.getURL('chapter-editor/editor.html'), '_blank');
|
||||
// win.focus();
|
||||
|
||||
// chrome.tabs.create({url:"editor.html"});
|
||||
|
||||
var list = document.getElementById('chapters');
|
||||
var allPages = getEbookPages();
|
||||
|
||||
for (var i = 0; i < allPages.length; i++) {
|
||||
var listItem = document.createElement('li');
|
||||
var label = document.createElement('span');
|
||||
label.innerHTML = allPages[i].title;
|
||||
label.class = 'menu-item-full';
|
||||
listItem.appendChild(label);
|
||||
list.appendChild(listItem);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
document.getElementById('savePage').onclick = function() {
|
||||
localStorage.removeItem('ebook');
|
||||
function dispatch(action, justAddToBuffer) {
|
||||
if (!justAddToBuffer) {
|
||||
localStorage.removeItem('ebook');
|
||||
}
|
||||
chrome.tabs.query({
|
||||
currentWindow: true,
|
||||
active: true
|
||||
}, function(tab) {
|
||||
chrome.tabs.sendMessage(
|
||||
tab[0].id,
|
||||
{
|
||||
type: 'extract-page'
|
||||
},
|
||||
function (response) {
|
||||
|
||||
// chrome.tabs.sendMessage(
|
||||
// tab[0].id, {
|
||||
// type: action
|
||||
// },
|
||||
// function(response) {
|
||||
// alert('nnn 3' + response);
|
||||
// var allPages = getEbookPages();
|
||||
// allPages.push(response);
|
||||
// saveEbookPages(allPages);
|
||||
// if (!justAddToBuffer) {
|
||||
// buildEbook();
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
chrome.tabs.executeScript(tab[0].id, {
|
||||
file: 'chapter-editor/jquery.js'
|
||||
});
|
||||
|
||||
chrome.tabs.executeScript(tab[0].id, {
|
||||
file: 'pure-parser.js'
|
||||
});
|
||||
|
||||
chrome.tabs.executeScript(tab[0].id, {
|
||||
file: 'extractHtml.js'
|
||||
}, function() {
|
||||
// if (chrome.runtime.lastError) {
|
||||
// alert(JSON.stringify(chrome.runtime.lastError));
|
||||
// throw Error("Unable to inject script into tab " + tabId);
|
||||
// }
|
||||
chrome.tabs.sendMessage(tab[0].id, {
|
||||
type: action
|
||||
}, function(response) {
|
||||
var allPages = getEbookPages();
|
||||
allPages.push(response);
|
||||
saveEbookPages(allPages);
|
||||
buildEbook();
|
||||
}
|
||||
);
|
||||
if (!justAddToBuffer) {
|
||||
buildEbook();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('savePage').onclick = function() {
|
||||
dispatch('extract-page', false);
|
||||
};
|
||||
|
||||
document.getElementById('saveSelection').onclick = function() {
|
||||
localStorage.removeItem('ebook');
|
||||
chrome.tabs.query({
|
||||
currentWindow: true,
|
||||
active: true
|
||||
}, function(tab) {
|
||||
chrome.tabs.sendMessage(
|
||||
tab[0].id,
|
||||
{
|
||||
type: 'extract-selection'
|
||||
},
|
||||
function (response) {
|
||||
var allPages = getEbookPages();
|
||||
allPages.push(response);
|
||||
saveEbookPages(allPages);
|
||||
buildEbook();
|
||||
}
|
||||
);
|
||||
});
|
||||
dispatch('extract-selection', false);
|
||||
};
|
||||
|
||||
document.getElementById('title').onclick = function() {
|
||||
chrome.tabs.query({
|
||||
currentWindow: true,
|
||||
active: true
|
||||
}, function(tab) {
|
||||
chrome.tabs.sendMessage(
|
||||
tab[0].id, {
|
||||
type: 'get-title'
|
||||
},
|
||||
function(response) {
|
||||
var title = localStorage.getItem('title');
|
||||
if (title === null) {
|
||||
title = [];
|
||||
} else {
|
||||
title = JSON.parse(title);
|
||||
}
|
||||
title.push(response);
|
||||
localStorage.setItem('title', JSON.stringify(title));
|
||||
}
|
||||
);
|
||||
});
|
||||
document.getElementById('pageChapter').onclick = function() {
|
||||
dispatch('extract-page', true);
|
||||
};
|
||||
|
||||
document.getElementById('selectionChapter').onclick = function() {
|
||||
dispatch('extract-selection', true);
|
||||
};
|
||||
|
||||
document.getElementById('saveChapters').onclick = function() {
|
||||
buildEbook();
|
||||
};
|
||||
|
|
|
@ -74,7 +74,6 @@ function deferredAddZip(url, filename, zip) {
|
|||
// http://ebooks.stackexchange.com/questions/1183/what-is-the-minimum-required-content-for-a-valid-epub
|
||||
function buildEbook() {
|
||||
console.log('Prepare Content...');
|
||||
|
||||
var allPages = getEbookPages();
|
||||
var zip = new JSZip();
|
||||
|
||||
|
@ -185,7 +184,6 @@ function buildEbook() {
|
|||
|
||||
|
||||
|
||||
|
||||
///////////////
|
||||
///////////////
|
||||
var imgs = oebps.folder("images");
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
var allImgSrc = {};
|
||||
|
||||
//////
|
||||
|
||||
function getCurrentUrl() {
|
||||
|
@ -253,6 +252,6 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|||
content: tmpContent
|
||||
};
|
||||
|
||||
sendResponse(result);
|
||||
console.log('Html Extracted');
|
||||
sendResponse(result);
|
||||
});
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
@import 'https://fonts.googleapis.com/css?family=Galada';
|
||||
|
||||
* {
|
||||
/*font-family: 'Galada', cursive !important;*/
|
||||
}
|
||||
|
||||
body, html {
|
||||
/*font-family: 'Galada', cursive !important;*/
|
||||
}
|
BIN
icon.png
Normal file
BIN
icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -12,16 +12,15 @@
|
|||
|
||||
"content_scripts": [{
|
||||
"matches": ["<all_urls>"],
|
||||
"css": ["fonts.css"],
|
||||
"js": ["chapter-editor/jquery.js", "filesaver.js", "jszip.js", "jszip-utils.js", "pure-parser.js", "extractHtml.js"]
|
||||
"js": ["chapter-editor/jquery.js", "pure-parser.js", "extractHtml.js"]
|
||||
}],
|
||||
|
||||
"background": {
|
||||
"scripts": ["background2.js"]
|
||||
"scripts": []
|
||||
},
|
||||
|
||||
"browser_action": {
|
||||
"default_icon": "",
|
||||
"default_icon": "icon.png",
|
||||
"default_title": "Beastify",
|
||||
"default_popup": "chapter-editor/menu.html"
|
||||
},
|
||||
|
@ -29,7 +28,8 @@
|
|||
"permissions": [
|
||||
"contextMenus",
|
||||
"activeTab",
|
||||
"storage"
|
||||
"storage",
|
||||
"tabs"
|
||||
]
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
chrome.runtime.onMessage.addListener(function(request) {
|
||||
console.log('rrrrrrrrrr', request.type);
|
||||
|
||||
|
||||
});
|
6
sanitize-html.min.js
vendored
6
sanitize-html.min.js
vendored
File diff suppressed because one or more lines are too long
7955
sanitize.js
7955
sanitize.js
File diff suppressed because one or more lines are too long
37
test.html
37
test.html
|
@ -1,37 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>test ebook</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- <div class="contect">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, sit ne eius falli clita. An eum viderer dolorem, et clita mnesarchum mei. Nec dico congue ea, cum eu enim similique. Denique oporteat at nam, pri saperet pericula conceptam eu, per summo omnium suavitate ad. Aliquip accumsan detracto id vel, eu habeo eripuit salutatus has, his laoreet vituperata at.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, sit ne eius falli clita. An eum viderer dolorem, et clita mnesarchum mei. Nec dico congue ea, cum eu enim similique. Denique oporteat at nam, pri saperet pericula conceptam eu, per summo omnium suavitate ad. Aliquip accumsan detracto id vel, eu habeo eripuit salutatus has, his laoreet vituperata at.
|
||||
Lorem ipsum dolor sit amet, sit ne eius falli clita. An eum viderer dolorem, et clita mnesarchum mei. Nec dico congue ea, cum eu enim similique. Denique oporteat at nam, pri saperet pericula conceptam eu, per summo omnium suavitate ad. Aliquip accumsan detracto id vel, eu habeo eripuit salutatus has, his laoreet vituperata at.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, <a href="https://www.google.com">google</a> sit ne eius falli clita. An eum viderer dolorem, et clita mnesarchum mei. Nec dico congue ea, cum eu enim similique. Denique oporteat at nam, pri saperet pericula conceptam eu, per summo omnium suavitate ad. Aliquip accumsan detracto id vel, eu habeo eripuit salutatus has, his laoreet vituperata at.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, sit ne eius falli clita. An eum viderer dolorem, et clita mnesarchum mei.
|
||||
Nec dico congue ea, cum eu enim similique.
|
||||
<img src="http://i.imgur.com/khaB4fN.png" alt="" />
|
||||
Denique oporteat at nam, pri saperet pericula conceptam eu, per summo omnium suavitate ad.
|
||||
Aliquip accumsan detracto id vel, eu habeo eripuit salutatus has, his laoreet vituperata at.
|
||||
</p>
|
||||
</div> -->
|
||||
<div class="content">
|
||||
<p>p1</p>
|
||||
<p>p2</p>
|
||||
<p>p3</p>
|
||||
<p>p4 <a href="https://www.google.com">google</a></p>
|
||||
<p>p5</p>
|
||||
<p>p6 <img src="http://i.imgur.com/khaB4fN.png" alt="" /></p>
|
||||
<p>p7</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
533
test.js
533
test.js
|
@ -1,533 +0,0 @@
|
|||
// document.body.style.border = "5px solid red";
|
||||
|
||||
|
||||
// https://stuk.github.io/jszip/
|
||||
// https://github.com/eligrey/FileSaver.js/
|
||||
|
||||
|
||||
var cssFileName = 'ebook.css';
|
||||
var pageName = 'ebook.xhtml';
|
||||
var ebookName = "ebook-" + document.title + ".epub";
|
||||
var imageIndex = 0;
|
||||
var allImgSrc = {};
|
||||
var allExternalLinks = [];
|
||||
|
||||
//////
|
||||
|
||||
function getHtmlAsString(htmlContent) {
|
||||
try {
|
||||
var tmp = document.createElement('div');
|
||||
tmp.appendChild(htmlContent.cloneNode(true));
|
||||
var dirty = '<div>' + tmp.innerHTML + '</div>';
|
||||
return dirty;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function force(contentString) {
|
||||
try {
|
||||
var tagOpen = '@@@';
|
||||
var tagClose = '###';
|
||||
var inlineElements = ['h1', 'h2', 'h3', 'sup', 'b', 'i', 'em', 'code', 'pre', 'p'];
|
||||
|
||||
var $content = $(contentString);
|
||||
|
||||
$content.find('img').each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + 'img src="' + getImageSrc($(elem).attr('src')) + '"' + tagClose + tagOpen + '/img' + tagClose + '</span>');
|
||||
});
|
||||
|
||||
$content.find('a').each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + 'a href="' + getHref($(elem).attr('href')) + '"' + tagClose + $(elem).html() + tagOpen + '/a' + tagClose + '</span>');
|
||||
});
|
||||
|
||||
if ($('*').length < 3000) { // TODO
|
||||
inlineElements.forEach(function (tagName) {
|
||||
$content.find(tagName).each(function (index, elem) {
|
||||
$(elem).replaceWith('<span>' + tagOpen + tagName + tagClose + $(elem).html() + tagOpen + '/' + tagName + tagClose + '</span>');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
contentString = $content.text();
|
||||
|
||||
var tagOpenRegex = new RegExp(tagOpen, 'gi');
|
||||
var tagCloseRegex = new RegExp(tagClose, 'gi');
|
||||
contentString = contentString.replace(tagOpenRegex, '<');
|
||||
contentString = contentString.replace(tagCloseRegex, '>');
|
||||
contentString = contentString.replace(/&/gi, '&'); // TODO ??
|
||||
contentString = contentString.replace(/&/gi, '&');
|
||||
|
||||
return contentString;
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
//////
|
||||
function getImageSrc(srcTxt) {
|
||||
if (!srcTxt) {
|
||||
return '';
|
||||
}
|
||||
allImgSrc[srcTxt] = 'img-' + (imageIndex++) + '.' + getFileExtension(srcTxt);
|
||||
return '../images/' + allImgSrc[srcTxt];
|
||||
}
|
||||
|
||||
function getHref(hrefTxt) {
|
||||
if (!hrefTxt) {
|
||||
return '';
|
||||
}
|
||||
if (hrefTxt.indexOf('#') === 0) {
|
||||
hrefTxt = window.location.href + hrefTxt;
|
||||
}
|
||||
if (hrefTxt.indexOf('/') === 0) {
|
||||
hrefTxt = window.location.protocol + '//' + window.location.hostname + hrefTxt;
|
||||
}
|
||||
// hrefTxt = escape(hrefTxt); // TODO
|
||||
return hrefTxt;
|
||||
}
|
||||
|
||||
// https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
|
||||
function sanitize(rawContentString) {
|
||||
|
||||
var srcTxt = '';
|
||||
var dirty = null;
|
||||
try {
|
||||
// dirty = getHtmlAsString(rawContent);
|
||||
wdirty = $.parseHTML(rawContentString);
|
||||
$wdirty = $(wdirty);
|
||||
$wdirty.find('script, style, svg, canvas, noscript').remove();
|
||||
$wdirty.find('*:empty').not('img').remove();
|
||||
|
||||
dirty = $wdirty.html();
|
||||
|
||||
// dirty = dirty.replace(/ /gi, '');
|
||||
// dirty = HTMLtoXML(dirty);
|
||||
|
||||
////////////////
|
||||
|
||||
|
||||
return force(dirty);
|
||||
|
||||
|
||||
// var dirty = '<div>' + document.getElementsByTagName('body')[0].innerHTML + '</div>';
|
||||
|
||||
var results = '';
|
||||
var lastFragment = '';
|
||||
var lastTag = '';
|
||||
var inList = false;
|
||||
var allowedTags = ['div', 'p', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'blockquote',
|
||||
'img', 'a', 'ol', 'ul', 'li', 'b', 'i', 'sup', 'strong', 'strike',
|
||||
'table', 'tr', 'td', 'th', 'thead', 'tbody', 'pre', 'em'
|
||||
];
|
||||
var allowedTextTags = ['h4', 'h5', 'h6', 'span'];
|
||||
|
||||
HTMLParser(dirty, {
|
||||
start: function(tag, attrs, unary) {
|
||||
lastTag = tag;
|
||||
if (allowedTags.indexOf(tag) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag === 'ol' || tag === 'ul') {
|
||||
inList = true;
|
||||
}
|
||||
if (tag === 'li' && !inList) {
|
||||
tag = 'p';
|
||||
}
|
||||
|
||||
var tattrs = null;
|
||||
if (tag === 'img') {
|
||||
tattrs = attrs.filter(function(attr) {
|
||||
return attr.name === 'src';
|
||||
}).map(function(attr) {
|
||||
return getImageSrc(attr.escaped);
|
||||
});
|
||||
lastFragment = tattrs.length === 0 ? '<img></img>' : '<img src="' + tattrs[0] + '" alt=""></img>';
|
||||
} else if (tag === 'a') {
|
||||
tattrs = attrs.filter(function(attr) {
|
||||
return attr.name === 'href';
|
||||
}).map(function(attr) {
|
||||
return getHref(attr.escaped);
|
||||
});
|
||||
lastFragment = tattrs.length === 0 ? '<a>' : '<a href="' + tattrs[0] + '">';
|
||||
} else {
|
||||
lastFragment = '<' + tag + '>';
|
||||
}
|
||||
|
||||
results += lastFragment;
|
||||
lastFragment = '';
|
||||
},
|
||||
end: function(tag) {
|
||||
if (allowedTags.indexOf(tag) < 0 || tag === 'img') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag === 'ol' || tag === 'ul') {
|
||||
inList = false;
|
||||
}
|
||||
if (tag === 'li' && !inList) {
|
||||
tag = 'p';
|
||||
}
|
||||
|
||||
results += "</" + tag + ">\n";
|
||||
},
|
||||
chars: function(text) {
|
||||
if (lastTag !== '' && allowedTags.indexOf(lastTag) < 0) {
|
||||
return;
|
||||
}
|
||||
results += text;
|
||||
},
|
||||
comment: function(text) {
|
||||
// results += "<!--" + text + "-->";
|
||||
}
|
||||
});
|
||||
|
||||
// results = results.replace(/<([^>]+?)>\s*<\/\1>/gim, '');
|
||||
results = results.replace(/&[a-z]+;/gim, '');
|
||||
|
||||
return results;
|
||||
|
||||
} catch (e) {
|
||||
console.trace();
|
||||
console.log(e);
|
||||
|
||||
return force(dirty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getPageUrl(url) {
|
||||
return url.toLowerCase().replace(/\s+/g,'_').replace(/[^a-z0-9_]/g,'') + Math.floor(Math.random() * 10000) + '.xhtml';
|
||||
}
|
||||
|
||||
var pageIndex = 0;
|
||||
function getPageTitle(title) {
|
||||
try {
|
||||
if (title.trim() === '') {
|
||||
return 'page-' + pageIndex++;
|
||||
}
|
||||
var tmp = title;
|
||||
return title;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
function bibi(inp) {
|
||||
return inp;
|
||||
}
|
||||
|
||||
function getEbookPages() {
|
||||
try {
|
||||
var allPages = localStorage.getItem('ebook');
|
||||
if (!allPages) {
|
||||
allPages = [];
|
||||
} else {
|
||||
allPages = JSON.parse(allPages);
|
||||
}
|
||||
return allPages;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
console.log('Start saving...');
|
||||
|
||||
var allPages = getEbookPages();
|
||||
|
||||
alert();
|
||||
|
||||
var pageSrc = '';
|
||||
if (request.type === 'whole-page') {
|
||||
pageSrc = document.getElementsByTagName('body')[0];
|
||||
allPages.push({
|
||||
url: getPageUrl(document.title),
|
||||
title: bibi(document.title), //gatPageTitle(document.title),
|
||||
content: getHtmlAsString(pageSrc)
|
||||
});
|
||||
localStorage.setItem('ebook', JSON.stringify(allPages));
|
||||
buildEbook();
|
||||
} else if (request.type === 'selection') {
|
||||
pageSrc = getSelectedNodes();
|
||||
allPages.push({
|
||||
url: getPageUrl(document.title),
|
||||
title: bibi(document.title),
|
||||
content: getHtmlAsString(pageSrc)
|
||||
});
|
||||
console.log('PUSH', JSON.stringify(allPages));
|
||||
localStorage.setItem('ebook', JSON.stringify(allPages));
|
||||
buildEbook();
|
||||
} else if (request.type === 'page-to-buffer') {
|
||||
pageSrc = document.getElementsByTagName('body')[0];
|
||||
allPages.push({
|
||||
url: getPageUrl(document.title),
|
||||
title: bibi(document.title), //gatPageTitle(document.title),
|
||||
content: getHtmlAsString(pageSrc)
|
||||
});
|
||||
console.log('merge');
|
||||
localStorage.setItem('ebook', JSON.stringify(allPages));
|
||||
} else if (request.type === 'show-buffer') {
|
||||
// window.open(chrome.extension.getURL('chapter-editor/chapter-editor.html'), 'Chapter Editor');
|
||||
|
||||
chrome.tabs.create({
|
||||
url: chrome.extension.getURL('chapter-editor/chapter-editor.html'),
|
||||
active: false
|
||||
}, function(tab) {
|
||||
// After the tab has been created, open a window to inject the tab
|
||||
chrome.windows.create({
|
||||
tabId: tab.id,
|
||||
type: 'popup',
|
||||
focused: true
|
||||
// incognito, top, left, ...
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
function getSelectedNodes() {
|
||||
if (document.selection) {
|
||||
// return document.selection.createRange().parentElement();
|
||||
return document.selection.createRange();
|
||||
} else {
|
||||
var selection = window.getSelection();
|
||||
if (selection.rangeCount > 0) {
|
||||
var range = selection.getRangeAt(0);
|
||||
var selectionContents = range.cloneContents();
|
||||
return selectionContents;
|
||||
// console.log(selectionContents.children.length, selectionContents.children[0].outerHTML);
|
||||
}
|
||||
// return selection.getRangeAt(0);
|
||||
// return selection.createRange();
|
||||
}
|
||||
}
|
||||
|
||||
function prepareEbookContent(page) {
|
||||
var cleanContent = sanitize(page.content);
|
||||
|
||||
alert();
|
||||
|
||||
return '<?xml version="1.0" encoding="utf-8"?>' +
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">' +
|
||||
'<head>' +
|
||||
'<title>' + page.title + '</title>' +
|
||||
'<link href="' + cssFileName + '" rel="stylesheet" type="text/css" />' +
|
||||
'</head><body>' +
|
||||
cleanContent +
|
||||
'</body></html>';
|
||||
}
|
||||
|
||||
function getImagesIndex() {
|
||||
return Object.keys(allImgSrc).reduce(function(prev, elem, index) {
|
||||
return prev + '\n' + '<item href="images/' + allImgSrc[elem] + '" id="img' + index + '" media-type="image/' + getFileExtension(elem) + '"/>';
|
||||
}, '');
|
||||
}
|
||||
|
||||
function getExternalLinksIndex() { // TODO ???
|
||||
return allExternalLinks.reduce(function(prev, elem, index) {
|
||||
return prev + '\n' + '<item href="' + elem + '" />';
|
||||
}, '');
|
||||
}
|
||||
|
||||
function getFileExtension(fileName) {
|
||||
var tmpFileName = fileName.split('.').pop();
|
||||
if (tmpFileName.indexOf('?') > 0) {
|
||||
tmpFileName = tmpFileName.split('?')[0];
|
||||
}
|
||||
if (tmpFileName.trim() === '') {
|
||||
return 'jpg'; //TODO
|
||||
}
|
||||
return tmpFileName;
|
||||
}
|
||||
|
||||
// function walkDOM(main) {
|
||||
// var arr = [];
|
||||
// var loop = function(main) {
|
||||
// do {
|
||||
// try {
|
||||
// if (allowElements.indexOf(main.tagName.toLowerCase()) > -1) {
|
||||
// arr.push(main);
|
||||
// }
|
||||
// } catch (e) {
|
||||
// }
|
||||
// if (main.hasChildNodes()) {
|
||||
// loop(main.firstChild);
|
||||
// }
|
||||
// }
|
||||
// while (main = main.nextSibling);
|
||||
// }
|
||||
// loop(main);
|
||||
// return arr;
|
||||
// }
|
||||
|
||||
|
||||
function deferredAddZip(url, filename, zip) {
|
||||
var deferred = $.Deferred();
|
||||
JSZipUtils.getBinaryContent(url, function(err, data) {
|
||||
if (err) {
|
||||
deferred.reject(err);
|
||||
} else {
|
||||
zip.file(filename, data, {
|
||||
binary: true
|
||||
});
|
||||
deferred.resolve(data);
|
||||
}
|
||||
});
|
||||
return deferred;
|
||||
}
|
||||
|
||||
// http://ebooks.stackexchange.com/questions/1183/what-is-the-minimum-required-content-for-a-valid-epub
|
||||
function buildEbook() {
|
||||
var allPages = getEbookPages();
|
||||
var zip = new JSZip();
|
||||
|
||||
zip.file('mimetype', 'application/epub+zip');
|
||||
|
||||
var metaInfFolder = zip.folder("META-INF");
|
||||
metaInfFolder.file('container.xml',
|
||||
'<?xml version="1.0"?>' +
|
||||
'<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">' +
|
||||
'<rootfiles>' +
|
||||
'<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>' +
|
||||
'</rootfiles>' +
|
||||
'</container>'
|
||||
);
|
||||
|
||||
|
||||
var oebps = zip.folder("OEBPS");
|
||||
oebps.file('toc.xhtml',
|
||||
'<?xml version="1.0" encoding="utf-8"?>' +
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">' +
|
||||
'<head>' +
|
||||
'<title>toc.xhtml</title>' +
|
||||
'<link href="' + cssFileName + '" rel="stylesheet" type="text/css" />' +
|
||||
'</head>' +
|
||||
'<body>' +
|
||||
'<nav id="toc" epub:type="toc">' +
|
||||
'<h1 class="frontmatter">Table of Contents</h1>' +
|
||||
'<ol class="contents">' +
|
||||
// '<li><a href="pages/' + pageName + '">' + ebookName + '</a></li>' +
|
||||
allPages.reduce(function (prev, page) {
|
||||
return prev + '\n' + '<li><a href="pages/' + page.url + '">' + page.title + '</a></li>';
|
||||
}, '') +
|
||||
'</ol>' +
|
||||
'</nav>' +
|
||||
'</body>' +
|
||||
'</html>'
|
||||
);
|
||||
|
||||
oebps.file('toc.ncx',
|
||||
'<?xml version="1.0" encoding="UTF-8" ?>' +
|
||||
'<ncx version="2005-1" xml:lang="en" xmlns="http://www.daisy.org/z3986/2005/ncx/">' +
|
||||
'<head>' +
|
||||
'<meta name="dtb:uid" content="isbn"/>' +
|
||||
'<meta name="dtb:depth" content="1"/>' +
|
||||
'</head>' +
|
||||
'<docTitle>' +
|
||||
'<text></text>' +
|
||||
'</docTitle>' +
|
||||
'<navMap>' +
|
||||
// '<content src="pages/' + pageName + '" />' +
|
||||
allPages.reduce(function (prev, page, index) {
|
||||
return prev + '\n' +
|
||||
'<navPoint id="ebook' + index + '" playOrder="' + (index+1) + '">' +
|
||||
'<navLabel><text>' + page.title + '</text></navLabel>' +
|
||||
'<content src="pages/' + page.url + '" />' +
|
||||
'</navPoint>';
|
||||
}, '') +
|
||||
'</navMap>' +
|
||||
'</ncx>'
|
||||
);
|
||||
|
||||
oebps.file(cssFileName, '');
|
||||
|
||||
var pagesFolder = oebps.folder('pages');
|
||||
allPages.forEach(function (page) {
|
||||
pagesFolder.file(page.url,
|
||||
prepareEbookContent(page)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
oebps.file('content.opf',
|
||||
'<?xml version="1.0" encoding="UTF-8" ?>' +
|
||||
'<package xmlns="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/" unique-identifier="db-id" version="3.0">' +
|
||||
'<metadata>' +
|
||||
'<dc:title id="t1">Title</dc:title>' +
|
||||
'<dc:identifier id="db-id">isbn</dc:identifier>' +
|
||||
'<meta property="dcterms:modified">2014-03-27T09:14:09Z</meta>' +
|
||||
'<dc:language>en</dc:language>' +
|
||||
'</metadata>' +
|
||||
'<manifest>' +
|
||||
'<item id="toc" properties="nav" href="toc.xhtml" media-type="application/xhtml+xml" />' +
|
||||
'<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />' +
|
||||
'<item id="template_css" href="' + cssFileName + '" media-type="text/css" />' +
|
||||
// '<item id="ebook" href="pages/' + pageName + '" media-type="application/xhtml+xml" />' + //properties="remote-resources"
|
||||
allPages.reduce(function (prev, page, index) {
|
||||
return prev + '\n' + '<item id="ebook' + index + '" href="pages/' + page.url + '" media-type="application/xhtml+xml" />';
|
||||
}, '') +
|
||||
getImagesIndex() +
|
||||
getExternalLinksIndex() +
|
||||
'</manifest>' +
|
||||
'<spine toc="ncx">' +
|
||||
// '<itemref idref="ebook" />' +
|
||||
allPages.reduce(function (prev, page, index) {
|
||||
return prev + '\n' + '<itemref idref="ebook' + index + '" />';
|
||||
}, '') +
|
||||
'</spine>' +
|
||||
'</package>'
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////
|
||||
///////////////
|
||||
var imgs = oebps.folder("images");
|
||||
var imgsPromises = [];
|
||||
// allImgSrc.forEach(function (imgSrc, index) {
|
||||
Object.keys(allImgSrc).forEach(function(imgSrc, index) {
|
||||
var tmpDeffered = deferredAddZip(imgSrc, allImgSrc[imgSrc], imgs);
|
||||
imgsPromises.push(tmpDeffered);
|
||||
});
|
||||
|
||||
var done = false;
|
||||
|
||||
$.when.apply($, imgsPromises).done(function() {
|
||||
done = true;
|
||||
zip.generateAsync({
|
||||
type: "blob"
|
||||
})
|
||||
.then(function(content) {
|
||||
saveAs(content, ebookName);
|
||||
});
|
||||
console.log("done !");
|
||||
}).fail(function(err) {
|
||||
alert(err);
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
zip.generateAsync({
|
||||
type: "blob"
|
||||
})
|
||||
.then(function(content) {
|
||||
saveAs(content, ebookName);
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
///////////// clean
|
||||
localStorage.removeItem('ebook');
|
||||
allImgSrc = {};
|
||||
imageIndex = 0;
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue