EPUB CFI basically works. Now for the more comprehensive testing.

This commit is contained in:
Kovid Goyal 2012-01-04 21:50:52 +05:30
parent 6f1824c2eb
commit 5fb8a6d833
5 changed files with 87 additions and 35 deletions

View file

@ -58,16 +58,6 @@ get_current_time = (target) -> # {{{
fstr(ans)
# }}}
set_current_time = (target, val) -> # {{{
if target.currentTime == undefined
return
if target.readyState == 4 or target.readyState == "complete"
target.currentTime = val
else
fn = -> target.currentTime = val
target.addEventListener("canplay", fn, false)
#}}}
class CanonicalFragmentIdentifier
@ -76,13 +66,23 @@ class CanonicalFragmentIdentifier
constructor: () ->
set_current_time: (target, val) -> # {{{
if target.currentTime == undefined
return
if target.readyState == 4 or target.readyState == "complete"
target.currentTime = val
else
fn = -> target.currentTime = val
target.addEventListener("canplay", fn, false)
#}}}
encode: (doc, node, offset, tail) -> # {{{
cfi = tail or ""
# Handle the offset, if any
switch node.nodeType
when 1 # Element node
if typeoff(offset) == 'number'
if typeof(offset) == 'number'
node = node.childNodes.item(offset)
when 3, 4, 5, 6 # Text/entity/CDATA node
offset or= 0
@ -136,7 +136,7 @@ class CanonicalFragmentIdentifier
node = doc
until cfi.length < 1 or error
if ( (r = cfi.match(simple_node_regex)) is not null ) # Path step
if (r = cfi.match(simple_node_regex)) # Path step
target = parseInt(r[1])
assertion = r[2]
if assertion
@ -318,22 +318,31 @@ class CanonicalFragmentIdentifier
try_list = [{start:0, end:0, a:0.5}, {start:0, end:1, a:1}, {start:-1, end:0, a:0}]
else
try_list = [{start:0, end:0, a:0.5}, {start:-1, end:0, a:0}, {start:0, end:1, a:1}]
k = 0
a = null
rects = null
node_len = node.nodeValue.length
until rects or rects.length or k >= try_list.length
t = try_list[k++]
start_offset = r.offset + t.start
end_offset = r.offset + t.end
a = t.a
if start_offset < 0 or end_offset >= node_len
continue
range.setStart(node, start_offset)
range.setEnd(node, end_offset)
rects = range.getClientRects()
offset = r.offset
for i in [0, 1]
# Try reducing the offset by 1 if we get no match as if it refers to the position after the
# last character we wont get a match with getClientRects
offset = r.offset - i
if offset < 0
offset = 0
k = 0
until rects?.length or k >= try_list.length
t = try_list[k++]
start_offset = offset + t.start
end_offset = offset + t.end
a = t.a
if start_offset < 0 or end_offset >= node_len
continue
range.setStart(node, start_offset)
range.setEnd(node, end_offset)
rects = range.getClientRects()
if rects?.length
break
if not rects or not rects.length
if not rects?.length
log("Could not find caret position: rects: #{ rects } offset: #{ r.offset }")
return null

View file

@ -6,19 +6,59 @@
Released under the GPLv3 License
###
log = (error) ->
if error
if window?.console?.log
window.console.log(error)
else if process?.stdout?.write
process.stdout.write(error + '\n')
viewport_top = (node) ->
$(node).offset().top - window.pageYOffset
viewport_left = (node) ->
$(node).offset().left - window.pageXOffset
window.onload = ->
h1 = document.getElementsByTagName('h1')[0]
x = h1.scrollLeft + 150
y = viewport_top(h1) + h1.offsetHeight/2
e = document.elementFromPoint x, y
if e.getAttribute('id') != 'first-h1'
alert 'Failed to find top h1'
return
alert window.cfi.at x, y
show_cfi = (dont_seek) ->
if window.current_cfi
pos = window.cfi.point(window.current_cfi)
ms = document.getElementById("marker").style
if pos
ms.visibility = "visible"
ms.top = (pos.y - 30) + window.scrollY + "px"
ms.left = (pos.x - 1) + window.scrollX + "px"
if not dont_seek
if typeof pos.time == "number"
window.cfi.set_current_time(pos.node, pos.time)
scrollTo(0, pos.y - 30)
null
RELOAD = true
mark_and_reload = (evt) ->
window.current_cfi = window.cfi.at(evt.clientX, evt.clientY)
if not RELOAD
show_cfi(true)
if window.current_cfi
fn = () ->
newloc = window.location.href.replace(/#.*$/, '') + "#epubcfi(#{ window.current_cfi })"
window.location.replace(newloc)
if RELOAD
window.location.reload()
setTimeout(fn, 1)
null
window.onload = ->
window.onscroll = show_cfi
window.onresize = show_cfi
document.onclick = mark_and_reload
for iframe in document.getElementsByTagName("iframe")
iframe.contentWindow.onscroll = show_cfi
r = location.hash.match(/#epubcfi\((.+)\)$/)
if r
window.current_cfi = r[1]
setTimeout(show_cfi, 1)
null

View file

@ -8,6 +8,8 @@
</head>
<body>
<h1 id="first-h1" style="border: solid 1px red">Testing CFI functionality</h1>
<img id="marker" style="position: absolute; visibility: hidden;" src="marker.png" alt="Marker" />
<p>0123</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

View file

@ -10,7 +10,8 @@
'''
Utilities to help with developing coffeescript based apps
'''
import time, SimpleHTTPServer, SocketServer, os, subprocess, cStringIO
import time, SimpleHTTPServer, SocketServer, os, subprocess
from io import BytesIO
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
@ -28,7 +29,7 @@ def send_head(self):
self.send_header("Content-Length", bytes(len(raw)))
self.send_header("Last-Modified", self.date_time_string(int(mtime)))
self.end_headers()
return cStringIO.StringIO(raw)
return BytesIO(raw)
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)