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 @@ __docformat__ = 'restructuredtext en'
'''
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 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
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)