Last active
August 29, 2015 14:08
-
-
Save lakenen/734c4a548f4fc719dd5d to your computer and use it in GitHub Desktop.
Viewer.js Page Manipulator Plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var viewer = Crocodoc.createViewer(myEl, { | |
url: 'https://view-api.box.com/1/sessions/78983c8bd83b4b03ac719d0f072a7d1d/assets/', | |
plugins: { | |
'page-manipulator': { | |
pages: [ | |
{ | |
page: 1, // re-use (duplicate) page 1 | |
replace: 2, // replace the original page 1 | |
// override whatever links were already on this page | |
links: [{uri: 'https://static.view-api.box.com/images/spindoge.gif', bbox:[0, 0, 375, 285]}], | |
dimensions: { width: 375, height: 285 } | |
}, | |
{ | |
page: 1, // re-use page 1 again | |
after: 3 // after page 3 | |
}, | |
{ | |
// override default dimensions (NOTE: dimensions are in pt) | |
dimensions: { width: 375, height: 285 }, | |
replace: 3, // replace page 3 | |
content: '<svg width="100%" height="100%"><image x="0" y="0" width="500" height="380" xlink:href="https://static.view-api.box.com/images/spindoge.gif"></image></svg>', | |
links: [{uri: 'https://static.view-api.box.com/images/spindoge.gif', bbox:[0, 0, 375, 285]}] | |
}, | |
{ | |
dimensions: { width: 300, height: 300 }, | |
after: -1, // after the last page | |
content: '<form action="#"><input name="foo"/><input type="submit" value="go"/></form>' | |
}, | |
{ | |
page: 1, // re-use page 1 again | |
before: -3 // before the 3rd from last page | |
}, | |
{ | |
remove: 5 // remove page 5 | |
} | |
] | |
} | |
} | |
}); | |
viewer.load(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* a bit of required CSS to override some default properties */ | |
.crocodoc-page-custom.crocodoc-page-text { | |
opacity: 1 !important; | |
display: block !important; | |
} | |
.crocodoc-page-custom .crocodoc-subpx-fix { | |
zoom: initial; | |
width: 100%; | |
height: 100%; | |
-webkit-transform: none; | |
transform: none; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Crocodoc.addDataProvider('page-manipulator', function (scope) { | |
// page manipulator data provider looks for special plugin config | |
var util = scope.getUtility('common'), | |
config = scope.getConfig().plugins['page-manipulator'], | |
pages = [], | |
pageLinks = {}, | |
$metadataPromise; | |
/** | |
* Find the index of the first instance of the given page number | |
* @param {int} page Page number of the page to find | |
* @returns {int} The index of the page or -1 if not found | |
*/ | |
function getPageIndex(page) { | |
if (page < 0) { | |
page = pages.length + page; | |
} | |
var i, l; | |
for (i = 0, l = pages.length; i < l; ++i) { | |
if (pages[i].page === page) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
/** | |
* Initialize objects to keep track of where pages and links are | |
* @param {Object} data The metadata object | |
* @returns {void} | |
*/ | |
function initializePages(data) { | |
var n, | |
exceptions = data.dimensions.exceptions | |
links = data.links; | |
for (n = 1; n <= data.numpages; ++n) { | |
pages.push({ | |
page: n, | |
dimensions: exceptions[n] || null | |
}); | |
} | |
// store link info so we can fix it later | |
util.each(links, function (i, link) { | |
var page = links[i].pagenum; | |
if (!pageLinks[page]) { | |
pageLinks[page] = []; | |
} | |
pageLinks[page].push(links[i]); | |
}); | |
} | |
/** | |
* Add/remove/modify pages according to the config | |
* @returns {void} | |
*/ | |
function manipulatePages() { | |
// insert/replace pages as specified in the config | |
util.each(config.pages || [], function (i, page) { | |
var index = getPageIndex(page.after || page.before || page.replace || page.remove); | |
if (index === -1) { | |
index = pages.length - 1; | |
} | |
if (page.after) { | |
index++; | |
} | |
if (index > pages.length) { | |
index = pages.length; | |
} | |
if (typeof page.replace !== 'undefined') { | |
pages.splice(index, 1, page); | |
} else if (typeof page.remove !== 'undefined') { | |
pages.splice(index, 1); | |
} else { | |
pages.splice(index, 0, page); | |
} | |
}); | |
} | |
/** | |
* Update metadata (modifies data) | |
* @param {Object} data The metadata object | |
* @returns {void} | |
*/ | |
function updateMetadata(data) { | |
var links = [], | |
exceptions = {}; | |
// fix links and dimensions | |
util.each(pages, function (i, page) { | |
var currentPageLinks = page.links || | |
(typeof page.page !== 'undefined' && pageLinks[page.page] || []); | |
currentPageLinks = util.map(currentPageLinks, function (link) { | |
// clone the link so when we modify destination it doesn't mess | |
// up duplicate instances of this page if they exist | |
link = util.extend(true, {}, link, { | |
pagenum: i + 1 | |
}); | |
// fix link destination (find the first page that matches...) | |
if (link.destination) { | |
link.destination.pagenum = getPageIndex(link.destination.pagenum) + 1; | |
} | |
return link; | |
}); | |
links = links.concat(currentPageLinks); | |
// replace the correct dimensions if necessary | |
if (page.dimensions) { | |
exceptions[i + 1] = page.dimensions; | |
} | |
}); | |
// update metadata | |
data.links = links; | |
data.numpages = pages.length; | |
data.dimensions.exceptions = exceptions; | |
} | |
/** | |
* Rewrite the metadata so the viewer knows which pages to load/when | |
* @param {Object} data The metadata object | |
* @returns {Object} The modified metadata object | |
*/ | |
function rewriteMetadata(data) { | |
initializePages(data); | |
manipulatePages(); | |
updateMetadata(data); | |
return data; | |
} | |
return { | |
get: function (type, key) { | |
var $p, | |
dp = scope.getDataProvider(type); | |
switch (type) { | |
case 'metadata': | |
// rewrite metadata response to alter the page structure | |
$p = dp.get(type); | |
$metadataPromise = $p; | |
return $p.then(rewriteMetadata).promise({ | |
abort: $p.abort | |
}); | |
case 'page-svg': | |
case 'page-text': | |
case 'page-img': | |
// need to wait for metadata in order to manipulate page info | |
$p = { abort: function () {} }; | |
return $.when($metadataPromise).then(function () { | |
var page = pages[key - 1]; | |
// if they are requesting a specific page that already exists | |
// (i.e., not a custom page), just get that page | |
if (page.page) { | |
$p = dp.get(type, page.page); | |
return $p; | |
} | |
// inject the custom page content into what is normally the "text" layer | |
if (type === 'page-text') { | |
return '<div class="crocodoc-page-custom crocodoc-page-text">' + (page.content || '') + '</div>'; | |
} | |
// page-img and page-svg are empty for custom pages | |
if (type === 'page-img') { | |
return new Image(); | |
} | |
if (type === 'page-svg') { | |
return '<svg></svg>'; | |
} | |
}).promise({ | |
abort: $p.abort | |
}); | |
} | |
}, | |
destroy: function () { | |
if ($metadataPromise) { | |
$metadataPromise.abort(); | |
} | |
$metadataPromise = config = pages = pageLinks = null; | |
} | |
}; | |
}); | |
Crocodoc.addPlugin('page-manipulator', function (scope) { | |
var util = scope.getUtility('common'); | |
return { | |
init: function () { | |
// use the page-manip data provider in the viewer config | |
util.extend(true, scope.getConfig(), { | |
dataProviders: { | |
metadata: 'page-manipulator', | |
'page-svg': 'page-manipulator', | |
'page-text': 'page-manipulator', | |
'page-img': 'page-manipulator' | |
} | |
}); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment