mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
More EPUB CFI fixes
This commit is contained in:
parent
2dba4bfa0f
commit
e4ebea9dcc
@ -8,8 +8,7 @@
|
|||||||
(http://code.google.com/p/epub-revision/source/browse/trunk/src/samples/cfi/epubcfi.js)
|
(http://code.google.com/p/epub-revision/source/browse/trunk/src/samples/cfi/epubcfi.js)
|
||||||
Improvements with respect to that code:
|
Improvements with respect to that code:
|
||||||
1. Works on all browsers (WebKit, Firefox and IE >= 8)
|
1. Works on all browsers (WebKit, Firefox and IE >= 8)
|
||||||
2. Works if the point is after the last text character in an element
|
2. Works for elements that are scrollable (i.e. have their own scrollbars)
|
||||||
3. Works for elements that are scrollable (i.e. have their own scrollbars)
|
|
||||||
|
|
||||||
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.
|
||||||
@ -127,9 +126,9 @@ find_offset_for_point = (x, y, node, cdoc) ->
|
|||||||
|
|
||||||
if not last_child
|
if not last_child
|
||||||
throw "#{node} has no children"
|
throw "#{node} has no children"
|
||||||
# The point must be after the last bit of text
|
# The point must be after the last bit of text/in the padding/border, we dont know
|
||||||
pos = 0
|
# how to get a good point in this case
|
||||||
return [last_child, last_child.nodeValue.length]
|
throw "Point (#{x}, #{y}) is in the padding/border of #{node}, so cannot calculate offset"
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -192,9 +191,11 @@ class CanonicalFragmentIdentifier
|
|||||||
offset or= 0
|
offset or= 0
|
||||||
while true
|
while true
|
||||||
p = node.previousSibling
|
p = node.previousSibling
|
||||||
if (p?.nodeType not in [3, 4, 5, 6])
|
if not p or p.nodeType > 8
|
||||||
break
|
break
|
||||||
offset += p.nodeValue.length
|
# log("previous sibling:"+ p + " " + p?.nodeType + " length: " + p?.nodeValue?.length)
|
||||||
|
if p.nodeType not in [2, 8] and p.nodeValue?.length?
|
||||||
|
offset += p.nodeValue.length
|
||||||
node = p
|
node = p
|
||||||
cfi = ":" + offset + cfi
|
cfi = ":" + offset + cfi
|
||||||
else # Not handled
|
else # Not handled
|
||||||
@ -332,6 +333,7 @@ class CanonicalFragmentIdentifier
|
|||||||
if nn.nodeType in [3, 4, 5, 6] and nn.nodeValue?.length # Text node, entity, cdata
|
if nn.nodeType in [3, 4, 5, 6] and nn.nodeValue?.length # Text node, entity, cdata
|
||||||
next = nn
|
next = nn
|
||||||
break
|
break
|
||||||
|
node = nn
|
||||||
if not next
|
if not next
|
||||||
if offset > len
|
if offset > len
|
||||||
error = "Offset out of range: #{ offset }"
|
error = "Offset out of range: #{ offset }"
|
||||||
@ -391,14 +393,11 @@ class CanonicalFragmentIdentifier
|
|||||||
py = ((y + cwin.scrollY - target.offsetTop)*100)/target.offsetHeight
|
py = ((y + cwin.scrollY - target.offsetTop)*100)/target.offsetHeight
|
||||||
tail = "#{ tail }@#{ fstr px },#{ fstr py }"
|
tail = "#{ tail }@#{ fstr px },#{ fstr py }"
|
||||||
else if name != 'audio'
|
else if name != 'audio'
|
||||||
if cdoc.caretRangeFromPoint # WebKit
|
# Get the test offset
|
||||||
range = cdoc.caretRangeFromPoint(x, y)
|
# We use a custom function instead of caretRangeFromPoint as
|
||||||
if range
|
# caretRangeFromPoint does weird things when the point falls in the
|
||||||
target = range.startContainer
|
# padding of the element
|
||||||
offset = range.startOffset
|
if cdoc.createRange
|
||||||
else
|
|
||||||
throw "Failed to find range from point (#{ x }, #{ y })"
|
|
||||||
else if cdoc.createRange
|
|
||||||
[target, offset] = find_offset_for_point(x, y, target, cdoc)
|
[target, offset] = find_offset_for_point(x, y, target, cdoc)
|
||||||
else
|
else
|
||||||
throw this.CREATE_RANGE_ERR
|
throw this.CREATE_RANGE_ERR
|
||||||
|
@ -28,10 +28,15 @@ mark_and_reload = (evt) ->
|
|||||||
# Remove image in case the click was on the image itself, we want the cfi to
|
# Remove image in case the click was on the image itself, we want the cfi to
|
||||||
# be on the underlying element
|
# be on the underlying element
|
||||||
ms = document.getElementById("marker")
|
ms = document.getElementById("marker")
|
||||||
ms.parentNode?.removeChild(ms)
|
if ms
|
||||||
|
ms.parentNode?.removeChild(ms)
|
||||||
|
|
||||||
fn = () ->
|
fn = () ->
|
||||||
window.current_cfi = window.cfi.at(evt.clientX, evt.clientY)
|
try
|
||||||
|
window.current_cfi = window.cfi.at(evt.clientX, evt.clientY)
|
||||||
|
catch err
|
||||||
|
log("Failed to calculate cfi: #{ err }")
|
||||||
|
return
|
||||||
if window.current_cfi
|
if window.current_cfi
|
||||||
epubcfi = "#epubcfi(#{ window.current_cfi })"
|
epubcfi = "#epubcfi(#{ window.current_cfi })"
|
||||||
newloc = window.location.href.replace(/#.*$/, '') + epubcfi
|
newloc = window.location.href.replace(/#.*$/, '') + epubcfi
|
||||||
|
@ -33,15 +33,21 @@
|
|||||||
border: solid 1px black;
|
border: solid 1px black;
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}
|
||||||
|
#whitespace {
|
||||||
|
border: 20px solid gray;
|
||||||
|
margin: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<h1 id="first-h1">Testing EPUB CFI</h1>
|
<h1 id="first-h1">Testing EPUB CFI</h1>
|
||||||
<div id="current-cfi">Current CFI: None</div>
|
<div id="current-cfi">Current CFI: None</div>
|
||||||
|
<p><a href="/">Reset</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 bold and not bold text</p>
|
<p>Scroll down and click on some elements. Make sure to hit both bold and not bold text</p>
|
||||||
<div id="overflow"> But I must explain to you how all this mistaken
|
<div id="overflow">But I must explain to you how all this mistaken
|
||||||
idea of denouncing pleasure and praising pain was born and I
|
idea of denouncing pleasure and praising pain was born and I
|
||||||
will give you a complete account of the system, and expound the
|
will give you a complete account of the system, and expound the
|
||||||
actual teachings of the great explorer of the truth, the
|
actual teachings of the great explorer of the truth, the
|
||||||
@ -62,9 +68,34 @@
|
|||||||
demoralized by the charms of pleasure of the moment, so blinded
|
demoralized by the charms of pleasure of the moment, so blinded
|
||||||
by desire, that they cannot foresee
|
by desire, that they cannot foresee
|
||||||
</div>
|
</div>
|
||||||
<h2>Some entities</h2>
|
<h2>Some entities and comments</h2>
|
||||||
<p>Entities: & © § ></p>
|
<p>Entities: & © § > some text after entities</p>
|
||||||
<p>An invisible CDATA: <![CDATA[CDATA]]> followed by some text</p>
|
<p>An invisible Comment: <!-- aaaaaa --> followed by some text</p>
|
||||||
|
<p>An invalid (in HTML) CDATA: <![CDATA[CDATA]]> followed by some text</p>
|
||||||
|
<h2>Margins padding borders</h2>
|
||||||
|
<p>Try clicking in the margins, borders and padding</p>
|
||||||
|
|
||||||
|
<p id="whitespace">But I must explain to you how all this mistaken
|
||||||
|
idea of denouncing pleasure and praising pain was born and I
|
||||||
|
will give you a complete account of the system, and expound the
|
||||||
|
actual teachings of the great explorer of the truth, the
|
||||||
|
master-builder of human happiness. No one rejects, dislikes, or
|
||||||
|
avoids pleasure itself, because it is pleasure, but because
|
||||||
|
those who do not know how to pursue pleasure rationally
|
||||||
|
encounter consequences that are extremely painful. Nor again is
|
||||||
|
there anyone who <b>loves</b> or pursues or desires to obtain pain of
|
||||||
|
itself, because it is pain, but because occasionally
|
||||||
|
circumstances occur in which toil and pain can procure him some
|
||||||
|
great pleasure. To take a trivial example, which of us ever
|
||||||
|
undertakes laborious physical exercise, except to obtain some
|
||||||
|
advantage from it? But who has any right to find fault with a
|
||||||
|
man who chooses to enjoy a pleasure that has no annoying
|
||||||
|
consequences, or one who avoids a pain that produces no
|
||||||
|
resultant pleasure? On the other hand, we denounce with
|
||||||
|
righteous indignation and dislike men who are so beguiled and
|
||||||
|
demoralized by the charms of pleasure of the moment, so blinded
|
||||||
|
by desire, that they cannot foresee</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<img id="marker" style="position: absolute; display:none; z-index:10" src="marker.png" alt="Marker" />
|
<img id="marker" style="position: absolute; display:none; z-index:10" src="marker.png" alt="Marker" />
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user