moved metadata handling to a more general and extensible set of code + fixed a minor bug with loading magazine state...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-02-01 18:10:24 +04:00
parent 46c47fd963
commit 50a6b11213
2 changed files with 82 additions and 20 deletions

View File

@ -55,6 +55,9 @@
[_] BUG: href to existing anchors will mess up layout... [_] BUG: href to existing anchors will mess up layout...
| need to find out how can we disable anchor links from actually | need to find out how can we disable anchor links from actually
| going to the anchor... | going to the anchor...
[X] MINOR BUG: on loading a mag from JSON page widths get messed up...
| ...in cases where content elements have explicit widths pages do
| not get stretched, this can be fixed by simply updating the view
[X] magazine loader and data format... [X] magazine loader and data format...
| this is simple, just use a restyled magazine viewer... | this is simple, just use a restyled magazine viewer...
[X] localize magazine event handler setup to setupMagazineEvents function... [X] localize magazine event handler setup to setupMagazineEvents function...

View File

@ -947,6 +947,59 @@ function resetState(){
* *
**********************************************************************/ **********************************************************************/
// there are two type of metadata handlers:
// - 'as-is', this is a trivial read and write value
// - explicit reader/writer, this will convert the data from html to JSON
// data and back...
JSONMetadata = {
name: 'as-is',
title: 'as-is',
authors: {
reader: function(data){
// NOTE: this might look odd, but we are using JS .map instead
// of the jQuery .map, and they have different signatures...
// ...(index, elem) in jQuery vs. (elem, index) in JS.
return data.split(',').map(function(e){return e.trim()})
},
writer: function(data){
return data.join(', ')
}
}
}
function readMetadata(elem, res, metadata){
if(res == null){
res = {}
}
if(metadata == null){
metadata = JSONMetadata
}
for(var a in metadata){
if(elem.attr(a)){
if(metadata[a] == 'as-is'){
res[a] = elem.attr(a)
} else {
res[a] = metadata[a].reader(elem.attr(a))
}
}
}
return res
}
function writeMetadata(elem, res, metadata){
if(metadata == null){
metadata = JSONMetadata
}
for(var a in metadata){
if(elem[a]){
if(metadata[a] == 'as-is'){
res.attr(a, elem[a])
} else {
res.attr(a, metadata[e].writer(elem[a]))
}
}
}
return elem
}
function buildJSON(export_bookmarks, export_position){ function buildJSON(export_bookmarks, export_position){
function _getContent(_, elem){ function _getContent(_, elem){
elem = $(elem) elem = $(elem)
@ -967,6 +1020,9 @@ function buildJSON(export_bookmarks, export_position){
} }
// other... // other...
// NOTE: with how the selector that maps this is constructed
// we'll never go into here, but for future compatibility
// and idiot-proofness this code will stay... for now...
} else { } else {
var res = { var res = {
type: 'raw-html', type: 'raw-html',
@ -975,23 +1031,15 @@ function buildJSON(export_bookmarks, export_position){
} }
} }
// metadata... // metadata...
if(elem.attr('authors')){ readMetadata(elem, res)
// NOTE: this might look odd, but we are using JS .map instead
// of the jQuery .map, and they have different signatures...
// ...(index, elem) in jQuery vs. (elem, index) in JS.
res.authors = $(elem.attr('authors').split(',')).map(function(e){return e.trim()})
}
// XXX more metadata...
// XXX
return res return res
} }
var res = { // read the basic metadata set for the magazine...
title: $('.magazine').attr('title'), var res = readMetadata($('.magazine'))
// this can contain pages or arrays... res.pages = $('.magazine > .page, .magazine > .article').map(_getContent).toArray(),
pages: $('.magazine > .page, .magazine > .article').map(_getContent).toArray(), res.bookmarks = export_bookmarks ? buildBookmarkList() : []
bookmarks: export_bookmarks ? buildBookmarkList() : [],
}
if(export_position){ if(export_position){
res.position = getPageNumber() res.position = getPageNumber()
} }
@ -1000,16 +1048,20 @@ function buildJSON(export_bookmarks, export_position){
function loadJSON(data, ignore_chrome){ function loadJSON(data, ignore_chrome){
function _build(block, elem){ function _build(block, elem){
// page...
if(elem.type == 'page'){ if(elem.type == 'page'){
var res = createPage(elem.content) var res = createPage(elem.content)
.addClass(elem['class']) .addClass(elem['class'])
.appendTo(block) .appendTo(block)
// cover...
} else if(elem.type == 'cover'){ } else if(elem.type == 'cover'){
var res = createCoverPage(elem.content) var res = createCoverPage(elem.content)
.addClass(elem['class']) .addClass(elem['class'])
.appendTo(block) .appendTo(block)
// article...
} else if(elem.type == 'article') { } else if(elem.type == 'article') {
// buiold an article... // buiold an article...
var res = createEmptyArticle() var res = createEmptyArticle()
@ -1019,19 +1071,24 @@ function loadJSON(data, ignore_chrome){
$(elem.pages).each(function(_, e){ $(elem.pages).each(function(_, e){
_build(res, e) _build(res, e)
}) })
} else if(elem.type == 'article') {
// other...
// NOTE: on a wll-formed JSON we'll never go in here, but just
// in case...
} else if(elem.type == 'raw-html') {
var res = createPage(elem.content) var res = createPage(elem.content)
.addClass(elem['class']) .addClass(elem['class'])
.appendTo(block) .appendTo(block)
} }
// metadata... // metadata...
if(elem.authors){ writeMetadata(elem, res)
res.attr('authors', elem.authors.join(', '))
}
// XXX more metadata...
// XXX
} }
// create an empty magazine...
var mag = createEmptyMagazine(data.title) var mag = createEmptyMagazine(data.title)
writeMetadata(mag, data)
// build the actual strcture...
$(data.pages).each(function(_, e){ $(data.pages).each(function(_, e){
_build(mag, e) _build(mag, e)
}) })
@ -1116,6 +1173,8 @@ function loadMagazineChrome(position, bookmarks){
setupNavigator() setupNavigator()
setCurrentPage(position) setCurrentPage(position)
loadBookmarks(bookmarks != null ? bookmarks : []) loadBookmarks(bookmarks != null ? bookmarks : [])
// XXX do we need to cover this with a splash???
updateView()
} }