Closed rkwright closed 9 years ago
@larsvoigt the jQuery highlight plugin inserts spans in the markup in order to "select" character ranges. These spans are not blacklisted by the CFI backend, so this is a strongly discouraged practice (e.g. it potentially breaks bookmarks, etc,). So, ideally you would be able to customise the CFI blacklists with your own "highlight" class, but as it turns out there is no easy way to do this (plus, there are blacklist API "holes" in the current Readium codebase). More information here: https://github.com/readium/readium-cfi-js/issues/30
What you could do is use Readium's existing highlighting mechanism, which does not rely on additional / interspersed span markup. Instead, semi-transparent divs are overlaid on top of the document text (so styling options are limited to an overlay colour), and the positions/dimensions are updated automatically when the page is reflowed (window resized, font enlarged, etc.). See addHighlight(CFI, id, type, styles)
:
https://github.com/readium/readium-shared-js/blob/develop/lib/annotations_module.js#L565
Accessible via the Reader API:
https://github.com/readium/readium-shared-js/blob/develop/js/views/reader_view.js#L1197
...this requires building a CFI expression that represents a single search result:
var cfi = EPUBcfi.Generator.generateCharOffsetRangeComponent(
startTextNode,
charPosInStartTextNode,
endTextNode,
charPosInEndTextNode
blacklistClass,
blacklistElement,
blacklistId,
);
_reader.addHighlight(
SPINE_ID,
cfi,
HIGHLIGHT_ID,
"highlight", //"underline"
undefined // styles
);
Alternatively, you could highlight the browser active text selection for each search result:
addSelectionHighlight(id, type)
https://github.com/readium/readium-shared-js/blob/develop/js/views/reader_view.js#L1210
Thank you @danielweck for your fast response and help. The facts sound good. I will give you feedback as far as possible.
Using the new plugins architecture:
https://github.com/readium/readium-js/blob/develop/dev/index.js#L109
ReadiumSDK.on(ReadiumSDK.Events.PLUGINS_LOADED, function(reader) {
reader.plugins.annotations.initialize({annotationCSSUrl: readerOptions.annotationCSSUrl});
reader.plugins.annotations.on("annotationClicked", function(type, idref, cfi, id) {
console.log("ANNOTATION CLICK: " + id);
reader.plugins.annotations.removeHighlight(id);
});
reader.plugins.annotations.on("textSelectionEvent", function() {
console.log("ANNOTATION SELECT");
reader.plugins.annotations.addSelectionHighlight(Math.floor((Math.random()*1000000)), "highlight");
});
});
I am able to highlight text in reflowable epubs but not for fixed layout, please help.
Dear Daniel, I can highlight selected text, but not save or store in Readium. I have been working on a way to somehow save my annotations in a separate file (in a right position using CFI ) that can be shown as a layer on top of each visible content of the epub3-based book in Readium. Also what is the best way to pass these annotated data to an existing file in Readium (or and DB in Readium)? Or create a new epub3 file consisting just annotations?
Could you please let me know what is your suggestion?
Thanks in advance, Kind regards, Hajar
At this stage there is no proper built-in "annotation" feature in Readium. You would need to extend the "highlight" plugin, or even better: create a new plugin that would implement a persistence backend (save to / load from IndexedDB, LocalStorage etc.) and you would also need a front-end to handle user interaction / edits (delete annotation, change text, etc.) This project is very keen to receive open-source contributions, so let us know if you would like to participate.
Thank you very much Daniel. We are interested in contributing to this project. Please provide me more information. We have been also working on the way to make content safe (disable copy paste or save book content) something like https://read.amazon.com/ Could you please let me know if yo have started this project? I saw somewhere else a comment that Readium is going to make the highlight feature by the end of the year (2016), is this right?
Thanks in advance, Kind regards, Hajar
Hello, regarding your potential open source contributions, please ask Ric Wright @rkwright Regarding highlights, the plugin is available in the develop branch of readium-shared-js, but it is still experimental in the sense that it hasn't been tested enough to be considered production-ready. We are not able to commit to a firm deadline because this is an open source project mostly run by volunteers. We are aware that commercial vendors who use Readium as the foundation / engine for their reading systems usually implement their own annotation framework as "value add" / unique product selling point (when that's the case, the code is likely to remain proprietary).
Regarding copy/paste disabling, this could be a cross-platform generic readium-shared-js plugin, and native apps developers could choose to use their own solution if they wanted to. We are aware that existing Readium-based vendor apps implemented their own protection measures to secure the contents. No open-source code as far as I know, but it probably is pretty trivial JavaScript event handling (preventDefault()).
Hi @danielweck and @larsvoigt I have been working on highlighting text based on CFI. I could integrate epub-search engin in Readim, as search function. Now I can extract CFI of a search keyword in json format. Now I need to highlight my search keyword in the readium. So it is not based on selected text. The only guidance that I could find is https://docs.google.com/document/d/1O8V0C2XaynobpDApnQvGcfgE4aCDj7BiZ5W-4eOupIk/edit#heading=h.nlvujjtmpl2m. But I could not use it to highlight my searched keyword. For example my extracted information in jsn format is: { "filename" : "accessible_epub_3", "epubTitle" : "Accessible EPUB 3", "href" : "ch01.xhtml", "baseCfi" : "/6/16[id-id2611884]!", "id" : "id-id2611884", "cfis" : ["/6/16[id-id2611884]!/4/2[introduction]/4,/1:22,/1:23"] } and I tried to work on cloud-reader. Could you please let me know how should be the right code in order to highlight my example: I tried to adopt "S.reader.plugins.highlights.addSelectionHighlight(Math.floor(1e6 * Math.random()), "test-highlight")" from " r(".icon-annotations").on("click", function () { S.reader.plugins.highlights.addSelectionHighlight(Math.floor(1e6 * Math.random()), "test-highlight") //S.reader.plugins.highlights.addSelectionHighlight('id-id2611884', "/4,/1:22,/1:23", 123, "highlight"); });"
But my problem is how do I need to make a link between Math.floor(1e6 * Math.random()) and 'id-id2611884', "/4,/1:22,/1:23", 123, Or if you could propose me know other ways!
@hajarghaem you want to use addHighlight()
, not addSelectionHighlight()
.
See function parameters:
https://github.com/readium/readium-shared-js/blob/develop/plugins/highlights/manager.js#L155
...and for your information, here is the function logic for a given spine item document:
https://github.com/readium/readium-shared-js/blob/develop/plugins/highlights/controller.js#L151
PS: the Math.random()
call creates some kind of unique identifier for the newly-created highlight (see the id
parameter of both "add highlight" functions).
@danielweck Thank you very much Daniel. When use "S.reader.plugins.highlights.addHighlight("/4/2/1:22,/1:23", 'id-id2611884', 123, "test-highlight");" inside: r(".icon-annotations").on("click", function () { //S.reader.plugins.highlights.addSelectionHighlight(Math.floor(1e6 * Math.random()), "highlight") S.reader.plugins.highlights.addHighlight("/4/2/1:22,/1:23", 'id-id2611884', 123, "highlight"); }); It does not annotate the text.
Could you please let e know if I need to change other parts? Thanks in advance, Hajar
Hello @danielweck,
I tried to enable or disable addSelectionHighlight function via "manager.js and/or controller.js", but nothing changed. It seems that there is not connection between "controller.js and manager.js" with cloud-reader (readium-js-viewer_all.js). I can controller my annotation when I use "npm run http", but not when I use "node node_modules/http-server/bin/http-server -a 127.0.0.1 -p 8080 -c-1 .."
hello, did you build readium-js-viewer from source, and from the develop branch? remember, you need to ensure that the configuration in readium-shared-js/plugins/plugins.cson includes the highlighter plugin.
I followed instruction "https://github.com/readium/readium-js-viewer". as I said I can control when I use "npm run http". But I cannot control highlights in cloud reader.
what branch? what is your plugins.cson configuration?
my plugins.cson includes:
plugins: [
]
# the sharp character indicates a comment in the CSON syntax. you must uncomment the line for the highlights plugin. then use "npm run http" to try the cloud reader from the raw source tree, or "npm run dist+sourcemap" to build the app so you can upload it to your HTTP server.
PS: the highlighter plugin does just that: it highlights text selections. you must implement your own logic on top of this basic functionality, for example to support annotations.
Thanks I try your solution and then update you. For the highlight, I extract CFI via epub-search engine ( fetch this information in a json file). Then in the cloud-reader I added an even in order to activate addHighlight function with my CFI information. Something like we have already had for addSelectionHighlight() in: r(".icon-annotations").on("click", function () { S.reader.plugins.highlights.addSelectionHighlight(Math.floor(1e6 * Math.random()), "highlight") });
When you add your code, do you edit the original (raw) files in the source tree, or do you patch the JavaScript bundles created by RequireJS (build-ouput folder)? Or, do you just add JS code in reader.html?
My recommendation is to customise the original codebase, iteratively test with "npm run http", and compile the final application with "npm run dist+sourcemap" (to deploy / upload to a real HTTP server)
@danielweck The readium-js-viewer_all.js is created after "nppm run dist". Could you please let me know where can I add my code (instead of readium-js-viewer_all.js) before building dist?
Obviously, the answer to your question depends on what you are trying to achieve, but assuming you want to add behaviours after a document (spine item) is loaded and paginated / rendered, then a good starting point would be listen to the PAGINATION_CHANGED
event, as done here in the "reader" view:
readium.reader.on(ReadiumSDK.Events.PAGINATION_CHANGED, function (pageChangeData) {
...
https://github.com/readium/readium-js-viewer/blob/develop/src/js/EpubReader.js#L451
I added my codes in different files: src/css/viewer.css , \src\templates\reader-navbar.html, ...
Hi @danielweck and @larsvoigt , I integrated epub-search in cloud-reader (from the original (raw) files in the source tree ). I also can simply highlight my search keywords. There are still an issue: 1- this is related to PAGINATION_CHANGED. When I am in a page that includes my search word then I can it is highlighted but not other same words that are in other pages (not current page). I have been looking for a way to highlight my search words even in other pages (not current visible page).
Thanks in advance, Hajar
@hajarghaem "pages" for reflowable documents, or fixed layout? If fixed-layout, then of course only the visible page (or two pages) can display highlights. If reflowable documents, then there may be several "pages" (CSS columns) within the same spine item document, and any number of text highlights can be created, even in pages that are not visible.
@hajarghaem.
// open the "page" with the cfi of your keyword
readium.reader.openSpineItemElementCfi(...);
// see daniels hint
readium.reader.on(ReadiumSDK.Events.PAGINATION_CHANGED, function (pageChangeData) {
...
hightlight(cfi)
});
@hajarghaem , as @larsvoigt said, you can navigate to any CFI location using readium.reader.openSpineItemElementCfi()
, or at the time the EPUB is loaded. See here for a more complete answer:
https://github.com/readium/readium-js/issues/143
Thanks @danielweck regarding you previous comment "If reflowable documents, then there may be several "pages" (CSS columns) within the same spine item document, and any number of text highlights can be created, even in pages that are not visible." When I use "SCROLL MODE: Continuous" then I cannot highlight anything! Even with the simple highlight button? I can highlight in reflowable document, the only issue is when I change the SCROLL mode to Continuous, then it cannot highlight.
Yes, unfortunately there is a bug preventing the highlights plugin to function properly in the scroll and fixed layout views. See: https://github.com/readium/readium-shared-js/issues/280 and https://github.com/readium/readium-shared-js/issues/315
Hi @danielweck, Thanks for your time and responses. (goal: Dynamic table of content based on search result) I am going to create a table of content based on my search results. I tried different files (e.g., package_document.js, manifest.js, content_document_fetcher.js ) and functions (e.g., generateTocListDOM) to change the order of table of content based on my conditions. But I just could see some changes when I applied my code in "EpubReader.js" in "$('#readium-toc-body').on('click', 'a', function(e) { ..." . In addition, adding some codes to (package_document.js) in (resourceFetcher.relativeToPackageFetchFileContents(toc, 'text', function (tocDocumentText) { ... ) lets me update the "tocDocumentText" and thus updating the TOC. But obviousley i I have to find a way to make it specific for my Search-TOC and not the Book-TOC. SO in this sptep I have to find a way to enable (package_document.js) to create a second TOC based on my search result. I have to know how I can control TOC (control package_document.js in epubreader.js), please help on this.
Could you please let me know if there is a better way to change the order of table of content, and linking the TOC and their corresponding html page of the book? Thanks in advance!
Submitted by Lars Voigt: lars.voigt@dzb.de
Platform/Browser: CloudReader, All platforms.
I try to highlight text fragments (single words) inside the "epubContentIframe".
$("#epubContentIframe").contents().find('body').highlight("text");
I use the jQuery highlight plugin and I think it works fine. Because I have debug the iframe dom manipulation and it looks good. But at the viewport I can see that the text should be highlighted is lost.
Should I do more to update the viewport? Or there a cleaner way to do that? Readium-JS API?