More work on EPUB CFI

This commit is contained in:
Kovid Goyal 2012-01-17 06:38:15 +05:30
parent 891c9b45af
commit 0411a32344
3 changed files with 33 additions and 7 deletions

View File

@ -13,6 +13,7 @@
3. Much more comprehensive testing/error handling 3. Much more comprehensive testing/error handling
4. Properly encodes/decodes assertions 4. Properly encodes/decodes assertions
5. Handles points in the padding of elements consistently 5. Handles points in the padding of elements consistently
6. Has a utility method to calculate the CFI for the current viewport position robustly
To check if this script is compatible with the current browser, call To check if this script is compatible with the current browser, call
window.cfi.is_compatible() it will throw an exception if not compatible. window.cfi.is_compatible() it will throw an exception if not compatible.
@ -86,7 +87,7 @@ window_scroll_pos = (win=window) -> # {{{
return [x, y] return [x, y]
# }}} # }}}
viewport_to_document = (x, y, doc) -> # {{{ viewport_to_document = (x, y, doc=window?.document) -> # {{{
until doc == window.document until doc == window.document
# We are in a frame # We are in a frame
frame = doc.defaultView.frameElement frame = doc.defaultView.frameElement
@ -573,13 +574,36 @@ class CanonicalFragmentIdentifier
minx = max(-winx, -winw) minx = max(-winx, -winw)
maxx = winw maxx = winw
get_cfi = (x, y) -> dist = (p1, p2) ->
Math.sqrt(Math.pow(p1[0]-p2[0], 2), Math.pow(p1[1]-p2[1], 2))
get_cfi = (ox, oy) ->
try try
cfi = this.at(x, y) cfi = this.at(ox, oy)
point = this.point(cfi)
catch err catch err
cfi = null cfi = null
# TODO: calculate point and check that it is close to current pos
cfi if point.range != null
r = point.range
rect = r.getClientRects()[0]
x = (point.a*rect.left + (1-point.a)*rect.right)
y = (rect.top + rect.bottom)/2
[x, y] = viewport_to_document(x, y, r.startContainer.ownerDocument)
else
node = point.node
r = node.getBoundingClientRect()
[x, y] = viewport_to_document(r.left, r.top, node.ownerDocument)
if typeof(point.x) == 'number' and node.offsetWidth
x += (point.x*node.offsetWidth)/100
if typeof(point.y) == 'number' and node.offsetHeight
y += (point.y*node.offsetHeight)/100
if dist(viewport_to_document(ox, oy), [x, y]) > 50
cfi = null
return cfi
x_loop = (cury) -> x_loop = (cury) ->
for direction in [-1, 1] for direction in [-1, 1]

View File

@ -23,6 +23,7 @@
indignation and dislike men who are so beguiled and demoralized by indignation and dislike men who are so beguiled and demoralized by
the charms of pleasure of the moment, so blinded by desire, that the charms of pleasure of the moment, so blinded by desire, that
they cannot foresee</p> they cannot foresee</p>
<p><img src="marker.png" width="300" height="300" alt="Test image"/></p>
</body> </body>
</html> </html>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Testing EPUB CFI</title> <title>Testing cfi.coffee</title>
<script type="text/javascript" src="cfi.coffee"></script> <script type="text/javascript" src="cfi.coffee"></script>
<script type="text/javascript" src="cfi-test.coffee"></script> <script type="text/javascript" src="cfi-test.coffee"></script>
<style type="text/css"> <style type="text/css">
@ -46,7 +46,8 @@
</head> </head>
<body> <body>
<div id="container"> <div id="container">
<h1 id="first-h1">Testing EPUB CFI</h1> <h1 id="first-h1">Testing cfi.coffee</h1>
<p>Click anywhere and the location will be marked with a marker, whose position is set via a CFI.</p>
<p><a id="reset" href="/">Reset CFI to None</a></p> <p><a id="reset" href="/">Reset CFI to None</a></p>
<h2>A div with scrollbars</h2> <h2>A div with scrollbars</h2>
<p>Scroll down and click on some elements. Make sure to hit both <p>Scroll down and click on some elements. Make sure to hit both