@papyrus-sdk/ui-react-native 0.2.35 → 0.2.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +322 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +323 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -8
- package/runtime/epubAnnotations.js +280 -6
- package/runtime/epubReader.js +1 -1
- package/runtime/index.html +293 -8
- package/runtime/runtime.js +293 -8
- package/runtime/comicRuntime.test.ts +0 -241
- package/runtime/documentLoadRuntime.test.ts +0 -172
- package/runtime/epubAnnotations.test.ts +0 -35
- package/runtime/epubReader.test.ts +0 -74
- package/runtime/epubRuntime.test.ts +0 -48
- package/runtime/epubScrollDiagnostics.test.ts +0 -107
- package/runtime/epubSelectionMenu.test.ts +0 -39
package/dist/index.mjs
CHANGED
|
@@ -20559,7 +20559,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20559
20559
|
var doc=contents.document,win=contents.window,start=null,blocked=false;
|
|
20560
20560
|
function point(e){var t=e.changedTouches&&e.changedTouches[0]||e.touches&&e.touches[0];return t?{x:t.clientX,y:t.clientY,time:Date.now()}:null;}
|
|
20561
20561
|
function selected(){return Boolean(String(win.getSelection()||'').trim()) || config.blocked();}
|
|
20562
|
-
function interactive(target){return Boolean(target && target.closest && target.closest('a,button,input,textarea,select,[contenteditable="true"],[data-papyrus-overlay]'));}
|
|
20562
|
+
function interactive(target){return Boolean(target && target.closest && target.closest('a,button,input,textarea,select,[contenteditable="true"],[data-papyrus-overlay],[data-papyrus-ink-capture]'));}
|
|
20563
20563
|
function begin(e){start=point(e);blocked=e.touches.length!==1 || selected() || interactive(e.target);}
|
|
20564
20564
|
function invalidateScroll(finish){if(config.current() && start && finish && config.mode()==='chapter-scroll' && !blocked && !selected() && Math.abs(finish.y-start.y)>12 && Math.abs(finish.y-start.y)>Math.abs(finish.x-start.x) && config.interact)config.interact();}
|
|
20565
20565
|
function move(e){if(e.touches.length!==1)blocked=true;invalidateScroll(point(e));}
|
|
@@ -20584,6 +20584,84 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20584
20584
|
typeof anchor.href === 'string' && !/^(javascript|data):/i.test(anchor.href) &&
|
|
20585
20585
|
typeof anchor.quote === 'string' && anchor.quote.length > 0 && anchor.quote.length <= 100000;
|
|
20586
20586
|
}
|
|
20587
|
+
function simplifyPath(points, tolerance, maxPoints) {
|
|
20588
|
+
if (!Array.isArray(points) || points.length <= 2) return Array.isArray(points) ? points.slice() : [];
|
|
20589
|
+
tolerance = Number.isFinite(tolerance) ? Math.max(0, tolerance) : 1.5;
|
|
20590
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 512;
|
|
20591
|
+
var keep = new Uint8Array(points.length); keep[0] = 1; keep[points.length - 1] = 1;
|
|
20592
|
+
var stack = [[0, points.length - 1]], toleranceSquared = tolerance * tolerance;
|
|
20593
|
+
while (stack.length) {
|
|
20594
|
+
var interval = stack.pop(), first = interval[0], last = interval[1], a = points[first], b = points[last];
|
|
20595
|
+
var dx = b.x - a.x, dy = b.y - a.y, lengthSquared = dx * dx + dy * dy, maxDistance = toleranceSquared, split = -1;
|
|
20596
|
+
for (var i = first + 1; i < last; i++) {
|
|
20597
|
+
var p = points[i], ratio = lengthSquared ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSquared)) : 0;
|
|
20598
|
+
var px = a.x + ratio * dx, py = a.y + ratio * dy, ox = p.x - px, oy = p.y - py, distance = ox * ox + oy * oy;
|
|
20599
|
+
if (distance > maxDistance) { maxDistance = distance; split = i; }
|
|
20600
|
+
}
|
|
20601
|
+
if (split >= 0) { keep[split] = 1; stack.push([first, split], [split, last]); }
|
|
20602
|
+
}
|
|
20603
|
+
var result = []; for (var j = 0; j < points.length; j++) if (keep[j]) result.push(points[j]);
|
|
20604
|
+
if (result.length <= maxPoints) return result;
|
|
20605
|
+
var capped = []; for (var k = 0; k < maxPoints; k++) capped.push(result[Math.round(k * (result.length - 1) / (maxPoints - 1))]);
|
|
20606
|
+
return capped;
|
|
20607
|
+
}
|
|
20608
|
+
function compactGesturePoints(points, maxPoints) {
|
|
20609
|
+
if (!Array.isArray(points)) return [];
|
|
20610
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 1024;
|
|
20611
|
+
if (points.length <= maxPoints) return points.slice();
|
|
20612
|
+
var compacted = [];
|
|
20613
|
+
for (var i = 0; i < maxPoints; i++) compacted.push(points[Math.round(i * (points.length - 1) / (maxPoints - 1))]);
|
|
20614
|
+
return compacted;
|
|
20615
|
+
}
|
|
20616
|
+
function densifyPath(points, maxStep, maxPoints) {
|
|
20617
|
+
if (!Array.isArray(points) || !points.length) return [];
|
|
20618
|
+
if (points.length === 1) return points.slice();
|
|
20619
|
+
maxStep = Number.isFinite(maxStep) ? Math.max(1, maxStep) : 12;
|
|
20620
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 512;
|
|
20621
|
+
var cumulative = [0], total = 0;
|
|
20622
|
+
for (var i = 1; i < points.length; i++) {
|
|
20623
|
+
if (![points[i-1].x,points[i-1].y,points[i].x,points[i].y].every(Number.isFinite)) return [];
|
|
20624
|
+
total += Math.hypot(points[i].x-points[i-1].x, points[i].y-points[i-1].y);
|
|
20625
|
+
cumulative.push(total);
|
|
20626
|
+
}
|
|
20627
|
+
if (!total) return [points[0], points[points.length-1]];
|
|
20628
|
+
var intervals = Math.min(maxPoints-1, Math.max(1, Math.ceil(total/maxStep))), result = [], segment = 1;
|
|
20629
|
+
for (var sample = 0; sample <= intervals; sample++) {
|
|
20630
|
+
var distance = total*sample/intervals;
|
|
20631
|
+
while (segment < cumulative.length-1 && cumulative[segment] < distance) segment++;
|
|
20632
|
+
var start = points[segment-1], end = points[segment], span = cumulative[segment]-cumulative[segment-1];
|
|
20633
|
+
var ratio = span ? (distance-cumulative[segment-1])/span : 0;
|
|
20634
|
+
result.push({x:start.x+(end.x-start.x)*ratio,y:start.y+(end.y-start.y)*ratio});
|
|
20635
|
+
}
|
|
20636
|
+
return result;
|
|
20637
|
+
}
|
|
20638
|
+
function createSpatialIndex(entries, cellSize) {
|
|
20639
|
+
cellSize = Number.isFinite(cellSize) ? Math.max(8, cellSize) : 64;
|
|
20640
|
+
var cells = new Map();
|
|
20641
|
+
entries.forEach(function(entry) {
|
|
20642
|
+
var left = Math.floor(entry.left / cellSize), right = Math.floor(entry.right / cellSize);
|
|
20643
|
+
var top = Math.floor(entry.top / cellSize), bottom = Math.floor(entry.bottom / cellSize);
|
|
20644
|
+
for (var x = left; x <= right; x++) for (var y = top; y <= bottom; y++) {
|
|
20645
|
+
var key = x + ':' + y, bucket = cells.get(key); if (!bucket) { bucket = []; cells.set(key, bucket); } bucket.push(entry);
|
|
20646
|
+
}
|
|
20647
|
+
});
|
|
20648
|
+
return {cells:cells,cellSize:cellSize};
|
|
20649
|
+
}
|
|
20650
|
+
function queryNearestTextRect(index, x, y, maxDistance) {
|
|
20651
|
+
if (!index || !Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(maxDistance) || maxDistance < 0) return null;
|
|
20652
|
+
var size = index.cellSize, minX = Math.floor((x-maxDistance)/size), maxX = Math.floor((x+maxDistance)/size);
|
|
20653
|
+
var minY = Math.floor((y-maxDistance)/size), maxY = Math.floor((y+maxDistance)/size), seen = new Set(), best = null;
|
|
20654
|
+
for (var cx=minX; cx<=maxX; cx++) for (var cy=minY; cy<=maxY; cy++) {
|
|
20655
|
+
var bucket = index.cells.get(cx+':'+cy); if (!bucket) continue;
|
|
20656
|
+
bucket.forEach(function(entry) {
|
|
20657
|
+
if (seen.has(entry)) return; seen.add(entry);
|
|
20658
|
+
var nearestX = Math.max(entry.left,Math.min(entry.right,x)), nearestY = Math.max(entry.top,Math.min(entry.bottom,y));
|
|
20659
|
+
var dx=x-nearestX,dy=y-nearestY,distance=Math.sqrt(dx*dx+dy*dy);
|
|
20660
|
+
if (distance<=maxDistance && (!best || distance<best.distance)) best={entry:entry,distance:distance,x:nearestX,y:nearestY};
|
|
20661
|
+
});
|
|
20662
|
+
}
|
|
20663
|
+
return best;
|
|
20664
|
+
}
|
|
20587
20665
|
function textNodes(document) {
|
|
20588
20666
|
var walker = document.createTreeWalker(document.body, 4);
|
|
20589
20667
|
var nodes = [], text = '', node;
|
|
@@ -20633,13 +20711,205 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20633
20711
|
if(win.getComputedStyle(doc.body).position==='static')doc.body.style.position='relative';
|
|
20634
20712
|
doc.body.appendChild(overlay);
|
|
20635
20713
|
var registry = new Map(), hitRegions = [];
|
|
20714
|
+
var inkRegistry = new Map(), rangeCache = new Map(), spatialIndex = null, activeGesture = null, inkConfig = {enabled:false,preset:'ink'};
|
|
20715
|
+
var inkSvg = doc.createElementNS('http://www.w3.org/2000/svg','svg');
|
|
20716
|
+
inkSvg.setAttribute('data-papyrus-ink-overlay','');
|
|
20717
|
+
inkSvg.style.cssText = 'position:absolute;left:0;top:0;overflow:visible;pointer-events:none;z-index:1';
|
|
20718
|
+
overlay.appendChild(inkSvg);
|
|
20719
|
+
var previewSvg = doc.createElementNS('http://www.w3.org/2000/svg','svg');
|
|
20720
|
+
previewSvg.setAttribute('data-papyrus-ink-preview-overlay','');
|
|
20721
|
+
previewSvg.style.cssText = 'position:fixed;left:0;top:0;overflow:hidden;pointer-events:none;z-index:2147482999';
|
|
20722
|
+
doc.documentElement.appendChild(previewSvg);
|
|
20723
|
+
var inkCanvas = doc.createElement('canvas');
|
|
20724
|
+
inkCanvas.dataset.papyrusInkCapture = '';
|
|
20725
|
+
inkCanvas.style.cssText = 'position:fixed;left:0;top:0;width:1px;height:1px;z-index:2147483000;background:transparent;pointer-events:none;touch-action:none';
|
|
20726
|
+
doc.documentElement.appendChild(inkCanvas);
|
|
20727
|
+
var inkContext = null; try { if(typeof win.CanvasRenderingContext2D==='function')inkContext = inkCanvas.getContext('2d'); } catch (_) {}
|
|
20728
|
+
function resizeCanvas() {
|
|
20729
|
+
var ratio = Math.max(1,Math.min(3,win.devicePixelRatio || 1));
|
|
20730
|
+
var width=Math.max(1,Math.min(4096,win.innerWidth||1));
|
|
20731
|
+
var height=Math.max(1,Math.min(4096,win.innerHeight||1));
|
|
20732
|
+
inkCanvas.style.width=width+'px';inkCanvas.style.height=height+'px';
|
|
20733
|
+
previewSvg.setAttribute('width',String(width));previewSvg.setAttribute('height',String(height));
|
|
20734
|
+
previewSvg.setAttribute('viewBox','0 0 '+width+' '+height);
|
|
20735
|
+
inkCanvas.width = Math.round(width*ratio); inkCanvas.height = Math.round(height*ratio);
|
|
20736
|
+
if (inkContext) { inkContext.setTransform(ratio,0,0,ratio,0,0); inkContext.clearRect(0,0,width,height); }
|
|
20737
|
+
}
|
|
20738
|
+
function collectTextRects() {
|
|
20739
|
+
var walker = doc.createTreeWalker(doc.body,4), node, entries=[];
|
|
20740
|
+
while ((node=walker.nextNode())) {
|
|
20741
|
+
var parent=node.parentElement;
|
|
20742
|
+
if (!parent || parent.closest('script,style,noscript,textarea,[data-papyrus-overlay],[data-papyrus-ink-capture]')) continue;
|
|
20743
|
+
var text=node.nodeValue || '', style=win.getComputedStyle(parent), computed=parseFloat(style.lineHeight);
|
|
20744
|
+
for (var start=0; start<text.length;) {
|
|
20745
|
+
var end=Math.min(text.length,start+24), last=text.charCodeAt(end-1), next=text.charCodeAt(end);
|
|
20746
|
+
if(end<text.length&&last>=0xD800&&last<=0xDBFF&&next>=0xDC00&&next<=0xDFFF)end++;
|
|
20747
|
+
var range=doc.createRange(); range.setStart(node,start); range.setEnd(node,end);
|
|
20748
|
+
var rects=[]; try { rects=Array.from(range.getClientRects()); } catch (_) {}
|
|
20749
|
+
rects.forEach(function(rect) {
|
|
20750
|
+
if (!(rect.width>0 && rect.height>0)) return;
|
|
20751
|
+
entries.push({left:rect.left+win.scrollX,top:rect.top+win.scrollY,right:rect.right+win.scrollX,bottom:rect.bottom+win.scrollY,width:rect.width,height:rect.height,
|
|
20752
|
+
node:node,start:start,end:end,lineHeight:Number.isFinite(computed)&&computed>0?computed:rect.height});
|
|
20753
|
+
});
|
|
20754
|
+
start=end;
|
|
20755
|
+
}
|
|
20756
|
+
}
|
|
20757
|
+
return entries;
|
|
20758
|
+
}
|
|
20759
|
+
function rebuildSpatialIndex() { spatialIndex=createSpatialIndex(collectTextRects(),64); rangeCache.clear(); }
|
|
20760
|
+
function inkViewportExtent() {
|
|
20761
|
+
var root=doc.documentElement,body=doc.body,bodyRect=body.getBoundingClientRect();
|
|
20762
|
+
var width=root.clientWidth||body.clientWidth||bodyRect.width||win.innerWidth||1;
|
|
20763
|
+
var height=root.clientHeight||body.clientHeight||bodyRect.height||win.innerHeight||1;
|
|
20764
|
+
return Math.max(1,Math.min(4096,width),Math.min(4096,height));
|
|
20765
|
+
}
|
|
20766
|
+
function inkStrokeWidthPx(width,preset) {
|
|
20767
|
+
var scale=preset==='highlight'?0.8:preset==='underline'?0.1:0.15;
|
|
20768
|
+
return Math.max(1,Math.min(24,(Number.isFinite(width)?width:0.006)*inkViewportExtent()*scale));
|
|
20769
|
+
}
|
|
20770
|
+
function closestGlyph(entry,x,y,maxDistance) {
|
|
20771
|
+
var source=(entry.node.nodeValue || '').slice(entry.start,entry.end), best=null, offset=0;
|
|
20772
|
+
for (var glyph of source) {
|
|
20773
|
+
var range=doc.createRange(); range.setStart(entry.node,entry.start+offset); range.setEnd(entry.node,entry.start+offset+glyph.length); offset+=glyph.length;
|
|
20774
|
+
var rects=[]; try { rects=Array.from(range.getClientRects()); } catch (_) {}
|
|
20775
|
+
rects.forEach(function(rect) {
|
|
20776
|
+
if (!(rect.width>0 && rect.height>0)) return;
|
|
20777
|
+
var nx=Math.max(rect.left+win.scrollX,Math.min(rect.right+win.scrollX,x)), ny=Math.max(rect.top+win.scrollY,Math.min(rect.bottom+win.scrollY,y));
|
|
20778
|
+
var dx=x-nx,dy=y-ny,distance=Math.sqrt(dx*dx+dy*dy);
|
|
20779
|
+
if (distance<=maxDistance && (!best || distance<best.distance)) best={range:range,rect:rect,distance:distance};
|
|
20780
|
+
});
|
|
20781
|
+
}
|
|
20782
|
+
if (!best || typeof contents.cfiFromRange!=='function') return null;
|
|
20783
|
+
var quote=best.range.toString(), cfiRange; try { cfiRange=contents.cfiFromRange(best.range); } catch (_) { return null; }
|
|
20784
|
+
if (!quote || typeof cfiRange!=='string' || !/^epubcfi\\([^\\n<>]+\\)$/.test(cfiRange)) return null;
|
|
20785
|
+
var lineHeight=Math.max(1,entry.lineHeight || best.rect.height), px=x-(best.rect.left+win.scrollX), py=y-(best.rect.top+win.scrollY);
|
|
20786
|
+
return {cfiRange:cfiRange,quote:quote,x:Math.max(-3,Math.min(3,px/lineHeight)),y:Math.max(-3,Math.min(3,py/lineHeight))};
|
|
20787
|
+
}
|
|
20788
|
+
function renderInkAnnotation(annotation,keep,bodyRect) {
|
|
20789
|
+
var baseRect=bodyRect || doc.body.getBoundingClientRect() || {left:0,top:0};
|
|
20790
|
+
var data=annotation.epubInk;
|
|
20791
|
+
if (!data || data.version!==1 || data.kind!=='epub-ink' || !Array.isArray(data.segments)) return;
|
|
20792
|
+
keep.add(annotation.id);
|
|
20793
|
+
var group=inkRegistry.get(annotation.id);
|
|
20794
|
+
if (!group) { group=doc.createElementNS('http://www.w3.org/2000/svg','g'); group.setAttribute('data-epub-ink-id',annotation.id); inkSvg.appendChild(group); inkRegistry.set(annotation.id,group); }
|
|
20795
|
+
group.replaceChildren();
|
|
20796
|
+
var color=/^#[0-9a-f]{6}$/i.test(annotation.color)?annotation.color:'#2563eb';
|
|
20797
|
+
var opacity=Number.isFinite(annotation.opacity)?Math.max(0,Math.min(1,annotation.opacity)):1;
|
|
20798
|
+
var preset=['ink','highlight','underline'].indexOf(data.preset)>=0?data.preset:'ink';
|
|
20799
|
+
var stroke=inkStrokeWidthPx(annotation.strokeWidth,preset);
|
|
20800
|
+
data.segments.forEach(function(segment) {
|
|
20801
|
+
if (segment.href!==options.href || !Array.isArray(segment.points)) return;
|
|
20802
|
+
var paths=[], current=[];
|
|
20803
|
+
segment.points.forEach(function(point) {
|
|
20804
|
+
var range=rangeCache.get(point.cfiRange);
|
|
20805
|
+
if (!range) { try { range=contents.range(point.cfiRange); } catch (_) { range=null; } if (range) rangeCache.set(point.cfiRange,range); }
|
|
20806
|
+
if (!range || range.toString()!==point.quote) { if(current.length>1)paths.push(current);current=[];return; }
|
|
20807
|
+
var rect; try { rect=range.getBoundingClientRect(); } catch (_) { rect=null; }
|
|
20808
|
+
if (!rect || !(rect.width>0 && rect.height>0)) { if(current.length>1)paths.push(current);current=[];return; }
|
|
20809
|
+
var lineHeight=Math.max(1,rect.height), x=rect.left-baseRect.left+point.x*lineHeight, y=rect.top-baseRect.top+point.y*lineHeight;
|
|
20810
|
+
var previous=current[current.length-1], jumpLimit=Math.max(24,lineHeight*2.5);
|
|
20811
|
+
if (previous && Math.hypot(x-previous.x,y-previous.y)>jumpLimit) { if(current.length>1)paths.push(current);current=[]; }
|
|
20812
|
+
current.push({x:x,y:y,lineHeight:lineHeight});
|
|
20813
|
+
});
|
|
20814
|
+
if(current.length>1)paths.push(current);
|
|
20815
|
+
paths.forEach(function(points) {
|
|
20816
|
+
var d='M '+points[0].x.toFixed(1)+' '+points[0].y.toFixed(1);
|
|
20817
|
+
for(var i=1;i<points.length;i++){var prev=points[i-1],point=points[i],mx=(prev.x+point.x)/2,my=(prev.y+point.y)/2;d+=' Q '+prev.x.toFixed(1)+' '+prev.y.toFixed(1)+' '+mx.toFixed(1)+' '+my.toFixed(1);}
|
|
20818
|
+
var last=points[points.length-1];d+=' L '+last.x.toFixed(1)+' '+last.y.toFixed(1);
|
|
20819
|
+
var path=doc.createElementNS('http://www.w3.org/2000/svg','path');path.setAttribute('d',d);path.setAttribute('fill','none');path.setAttribute('stroke',color);path.setAttribute('stroke-width',String(stroke));path.setAttribute('stroke-linecap','round');path.setAttribute('stroke-linejoin','round');path.setAttribute('opacity',String(opacity));group.appendChild(path);
|
|
20820
|
+
});
|
|
20821
|
+
});
|
|
20822
|
+
}
|
|
20823
|
+
function clearPreview() {
|
|
20824
|
+
if(inkContext)inkContext.clearRect(0,0,inkCanvas.width,inkCanvas.height);
|
|
20825
|
+
previewSvg.replaceChildren();
|
|
20826
|
+
}
|
|
20827
|
+
function createPreviewPath(x,y) {
|
|
20828
|
+
var path=doc.createElementNS('http://www.w3.org/2000/svg','path');
|
|
20829
|
+
path.setAttribute('data-papyrus-ink-preview','');path.setAttribute('d','M '+x.toFixed(1)+' '+y.toFixed(1));path.setAttribute('fill','none');
|
|
20830
|
+
path.setAttribute('stroke',inkConfig.color);path.setAttribute('stroke-width',String(inkStrokeWidthPx(inkConfig.strokeWidth,inkConfig.preset)));
|
|
20831
|
+
path.setAttribute('stroke-linecap','round');path.setAttribute('stroke-linejoin','round');path.setAttribute('opacity',String(inkConfig.opacity));
|
|
20832
|
+
path.style.pointerEvents='none';previewSvg.appendChild(path);return path;
|
|
20833
|
+
}
|
|
20834
|
+
function updatePreviewPath(clientX,clientY) {
|
|
20835
|
+
var x=clientX,y=clientY;
|
|
20836
|
+
var gesture=activeGesture;
|
|
20837
|
+
var startsSegment=!gesture.previewPath||gesture.previewPathPoints>=32;
|
|
20838
|
+
if(startsSegment){
|
|
20839
|
+
gesture.previewPath=createPreviewPath(gesture.previewLast?gesture.previewLast.x:x,gesture.previewLast?gesture.previewLast.y:y);
|
|
20840
|
+
gesture.previewPathPoints=1;
|
|
20841
|
+
}
|
|
20842
|
+
if(!startsSegment||gesture.previewLast){
|
|
20843
|
+
var pathData=gesture.previewPath.getAttribute('d')||'';
|
|
20844
|
+
gesture.previewPath.setAttribute('d',pathData+' L '+x.toFixed(1)+' '+y.toFixed(1));
|
|
20845
|
+
gesture.previewPathPoints++;
|
|
20846
|
+
}
|
|
20847
|
+
gesture.previewLast={x:x,y:y};
|
|
20848
|
+
}
|
|
20849
|
+
function cancelGesture() {
|
|
20850
|
+
var gesture=activeGesture; activeGesture=null; clearPreview();
|
|
20851
|
+
if(gesture)try{inkCanvas.releasePointerCapture(gesture.pointerId);}catch(_){}
|
|
20852
|
+
}
|
|
20853
|
+
function commitGesture() {
|
|
20854
|
+
var gesture=activeGesture; activeGesture=null; clearPreview();
|
|
20855
|
+
if(!gesture || !alive || !options.isCurrent() || !inkConfig.enabled || !spatialIndex) return;
|
|
20856
|
+
var simplified=simplifyPath(gesture.points,1.5,512), anchorSamples=densifyPath(simplified,12,512), segments=[], current=[];
|
|
20857
|
+
anchorSamples.forEach(function(point) {
|
|
20858
|
+
var coarse=queryNearestTextRect(spatialIndex,point.x,point.y,28);
|
|
20859
|
+
var cutoff=coarse?Math.max(12,Math.min(28,0.8*coarse.entry.lineHeight)):12;
|
|
20860
|
+
var anchored=coarse && closestGlyph(coarse.entry,point.x,point.y,cutoff);
|
|
20861
|
+
if(!anchored){if(current.length>1)segments.push({href:options.href,spineIndex:options.spineIndex,points:current});current=[];return;}
|
|
20862
|
+
current.push(anchored);
|
|
20863
|
+
});
|
|
20864
|
+
if(current.length>1)segments.push({href:options.href,spineIndex:options.spineIndex,points:current});
|
|
20865
|
+
segments=segments.slice(0,64);
|
|
20866
|
+
var pointCount=segments.reduce(function(total,segment){return total+segment.points.length;},0);
|
|
20867
|
+
if(!pointCount)return;
|
|
20868
|
+
var width=Math.max(1,doc.documentElement.scrollWidth,win.innerWidth),height=Math.max(1,doc.documentElement.scrollHeight,win.innerHeight);
|
|
20869
|
+
var normalized=simplified.map(function(p){return {x:Math.max(0,Math.min(1,p.x/width)),y:Math.max(0,Math.min(1,p.y/height))};});
|
|
20870
|
+
var minX=Math.min.apply(null,normalized.map(function(p){return p.x;})),maxX=Math.max.apply(null,normalized.map(function(p){return p.x;}));
|
|
20871
|
+
var minY=Math.min.apply(null,normalized.map(function(p){return p.y;})),maxY=Math.max.apply(null,normalized.map(function(p){return p.y;}));
|
|
20872
|
+
var first=segments[0].points[0], href=segments[0].href, documentId=typeof options.documentId==='function'?options.documentId():options.documentId;
|
|
20873
|
+
var annotation={id:'epub-ink-'+Date.now()+'-'+Math.random().toString(36).slice(2,9),type:'ink',pageIndex:(options.spineIndex||0)+1,
|
|
20874
|
+
rect:{x:minX,y:minY,width:Math.min(1-minX,Math.max(0.001,maxX-minX)),height:Math.min(1-minY,Math.max(0.001,maxY-minY))},path:normalized,color:inkConfig.color,opacity:inkConfig.opacity,strokeWidth:inkConfig.strokeWidth,createdAt:Date.now(),content:first.quote,
|
|
20875
|
+
anchor:{version:1,kind:'epub-cfi',cfiRange:first.cfiRange,href:href,spineIndex:options.spineIndex,documentId:documentId,quote:first.quote},
|
|
20876
|
+
epubInk:{version:1,kind:'epub-ink',documentId:documentId,preset:inkConfig.preset,segments:segments}};
|
|
20877
|
+
if(typeof options.onInkCommit==='function')options.onInkCommit(annotation);
|
|
20878
|
+
}
|
|
20879
|
+
function pointerDown(event) {
|
|
20880
|
+
if(!inkConfig.enabled || !alive || !options.isCurrent() || event.button!==undefined && event.button!==0)return;
|
|
20881
|
+
if(activeGesture){cancelGesture();return;}
|
|
20882
|
+
event.preventDefault();event.stopPropagation();
|
|
20883
|
+
activeGesture={pointerId:event.pointerId,points:[{x:event.clientX+win.scrollX,y:event.clientY+win.scrollY}],last:{x:event.clientX,y:event.clientY},previewPath:null,previewPathPoints:0,previewLast:null};
|
|
20884
|
+
updatePreviewPath(event.clientX,event.clientY);
|
|
20885
|
+
try{inkCanvas.setPointerCapture(event.pointerId);}catch(_){}
|
|
20886
|
+
}
|
|
20887
|
+
function pointerMove(event) {
|
|
20888
|
+
if(!activeGesture || activeGesture.pointerId!==event.pointerId)return;
|
|
20889
|
+
if(!options.isCurrent()||!inkConfig.enabled){cancelGesture();return;}
|
|
20890
|
+
event.preventDefault();event.stopPropagation();
|
|
20891
|
+
var point={x:event.clientX+win.scrollX,y:event.clientY+win.scrollY};activeGesture.points.push(point);
|
|
20892
|
+
if(activeGesture.points.length>2048)activeGesture.points=compactGesturePoints(activeGesture.points,1024);
|
|
20893
|
+
if(inkContext){inkContext.beginPath();inkContext.moveTo(activeGesture.last.x,activeGesture.last.y);inkContext.lineTo(event.clientX,event.clientY);inkContext.strokeStyle=inkConfig.color;inkContext.globalAlpha=inkConfig.opacity;inkContext.lineWidth=inkStrokeWidthPx(inkConfig.strokeWidth,inkConfig.preset);inkContext.lineCap='round';inkContext.lineJoin='round';inkContext.stroke();}
|
|
20894
|
+
updatePreviewPath(event.clientX,event.clientY);
|
|
20895
|
+
activeGesture.last={x:event.clientX,y:event.clientY};
|
|
20896
|
+
}
|
|
20897
|
+
function pointerUp(event) {if(!activeGesture || activeGesture.pointerId!==event.pointerId)return;event.preventDefault();event.stopPropagation();var end={x:event.clientX+win.scrollX,y:event.clientY+win.scrollY},last=activeGesture.points[activeGesture.points.length-1];if(Math.hypot(end.x-last.x,end.y-last.y)>0.5){activeGesture.points.push(end);updatePreviewPath(event.clientX,event.clientY);}commitGesture();}
|
|
20898
|
+
function pointerCancel(event) {if(activeGesture && (event.pointerId===undefined || activeGesture.pointerId===event.pointerId))cancelGesture();}
|
|
20899
|
+
resizeCanvas();rebuildSpatialIndex();
|
|
20900
|
+
inkCanvas.addEventListener('pointerdown',pointerDown);inkCanvas.addEventListener('pointermove',pointerMove);inkCanvas.addEventListener('pointerup',pointerUp);inkCanvas.addEventListener('pointercancel',pointerCancel);inkCanvas.addEventListener('lostpointercapture',pointerCancel);
|
|
20901
|
+
win.addEventListener('blur',pointerCancel);
|
|
20636
20902
|
function render() {
|
|
20637
20903
|
frame = 0; if (!alive || !options.isCurrent()) return;
|
|
20638
|
-
var keep = new Set(), noteGroups = new Map();
|
|
20904
|
+
var keep = new Set(), keepInk = new Set(), noteGroups = new Map();
|
|
20639
20905
|
hitRegions = [];
|
|
20906
|
+
var bodyRect=doc.body.getBoundingClientRect() || {left:0,top:0};
|
|
20907
|
+
inkSvg.setAttribute('width',String(Math.max(doc.documentElement.scrollWidth,win.innerWidth)));
|
|
20908
|
+
inkSvg.setAttribute('height',String(Math.max(doc.documentElement.scrollHeight,win.innerHeight)));
|
|
20640
20909
|
options.annotations().forEach(function(annotation) {
|
|
20641
20910
|
var anchor = annotation.anchor;
|
|
20642
20911
|
if (!validAnchor(anchor) || anchor.href !== options.href || anchor.documentId && options.documentId && anchor.documentId !== options.documentId) return;
|
|
20912
|
+
if(annotation.type==='ink' && annotation.epubInk){renderInkAnnotation(annotation,keepInk,bodyRect);return;}
|
|
20643
20913
|
var range = resolveRange(contents,anchor); if (!range) return;
|
|
20644
20914
|
var rects = Array.from(range.getClientRects()).filter(function(r){return r.width>0 && r.height>0;});
|
|
20645
20915
|
if (!rects.length) return;
|
|
@@ -20678,22 +20948,26 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20678
20948
|
group.button.addEventListener('click',function(e){e.stopPropagation();if(options.isCurrent())options.onTap(group.ids[0],group.ids);});
|
|
20679
20949
|
});
|
|
20680
20950
|
registry.forEach(function(group,id){if (!keep.has(id)) {group.remove();registry.delete(id);}});
|
|
20951
|
+
inkRegistry.forEach(function(group,id){if (!keepInk.has(id)) {group.remove();inkRegistry.delete(id);}});
|
|
20681
20952
|
}
|
|
20682
20953
|
function schedule() { if (alive && !frame) frame = win.requestAnimationFrame(render); }
|
|
20954
|
+
function rebuildAndSchedule(){if(!alive)return;rebuildSpatialIndex();schedule();}
|
|
20955
|
+
function handleResize(){resizeCanvas();rebuildAndSchedule();}
|
|
20956
|
+
function handleDocumentLoad(){rebuildAndSchedule();}
|
|
20683
20957
|
function tapMarkup(event) {
|
|
20684
20958
|
if(!alive || !options.isCurrent() || String(win.getSelection() || '').length || event.target.closest('[data-papyrus-overlay]'))return;
|
|
20685
20959
|
var hit=hitRegions.find(function(item){return item.rects.some(function(r){return event.clientX>=r.left && event.clientX<=r.right && event.clientY>=r.top && event.clientY<=r.bottom;});});
|
|
20686
20960
|
if(hit) {event.stopPropagation();options.onTap(hit.id);}
|
|
20687
20961
|
}
|
|
20688
20962
|
doc.addEventListener('click',tapMarkup);
|
|
20689
|
-
var observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(
|
|
20963
|
+
var observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(rebuildAndSchedule) : null;
|
|
20690
20964
|
if (observer) observer.observe(doc.body);
|
|
20691
|
-
win.addEventListener('resize',
|
|
20692
|
-
if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(schedule);
|
|
20965
|
+
win.addEventListener('resize',handleResize);win.addEventListener('scroll',schedule); doc.addEventListener('load',handleDocumentLoad,true);
|
|
20966
|
+
if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(function(){if(alive){rebuildSpatialIndex();schedule();}});
|
|
20693
20967
|
schedule();
|
|
20694
|
-
return {schedule:schedule, hit:function(x,y){return hitRegions.some(function(item){return item.rects.some(function(r){return x>=r.left && x<=r.right && y>=r.top && y<=r.bottom;});});}, range:function(anchor){return resolveRange(contents,anchor);}, destroy:function(){alive=false;if(frame)win.cancelAnimationFrame(frame);if(observer)observer.disconnect();win.removeEventListener('resize',
|
|
20968
|
+
return {schedule:schedule, setInkMode:function(config){var preset=['ink','highlight','underline'].indexOf(config?.preset)>=0?config.preset:'ink';inkConfig={enabled:!!config?.enabled,preset:preset,color:/^#[0-9a-f]{6}$/i.test(config?.color)?config.color:'#2563eb',opacity:Number.isFinite(config?.opacity)?Math.max(0,Math.min(1,config.opacity)):1,strokeWidth:Number.isFinite(config?.strokeWidth)?Math.max(0.0025,Math.min(0.02,config.strokeWidth)):0.006};inkCanvas.style.pointerEvents=inkConfig.enabled?'auto':'none';if(!inkConfig.enabled)cancelGesture();}, invalidateLayout:rebuildAndSchedule, hit:function(x,y){return hitRegions.some(function(item){return item.rects.some(function(r){return x>=r.left && x<=r.right && y>=r.top && y<=r.bottom;});});}, range:function(anchor){return resolveRange(contents,anchor);}, destroy:function(){alive=false;cancelGesture();if(frame)win.cancelAnimationFrame(frame);if(observer)observer.disconnect();win.removeEventListener('resize',handleResize);win.removeEventListener('scroll',schedule);win.removeEventListener('blur',pointerCancel);doc.removeEventListener('load',handleDocumentLoad,true);doc.removeEventListener('click',tapMarkup);inkCanvas.removeEventListener('pointerdown',pointerDown);inkCanvas.removeEventListener('pointermove',pointerMove);inkCanvas.removeEventListener('pointerup',pointerUp);inkCanvas.removeEventListener('pointercancel',pointerCancel);inkCanvas.removeEventListener('lostpointercapture',pointerCancel);inkCanvas.remove();previewSvg.remove();overlay.remove();doc.body.style.position=originalPosition;registry.clear();inkRegistry.clear();rangeCache.clear();}};
|
|
20695
20969
|
}
|
|
20696
|
-
return {validAnchor:validAnchor,recoverRange:recoverRange,resolveRange:resolveRange,selection:selection,install:install};
|
|
20970
|
+
return {validAnchor:validAnchor,simplifyPath:simplifyPath,compactGesturePoints:compactGesturePoints,densifyPath:densifyPath,createSpatialIndex:createSpatialIndex,queryNearestTextRect:queryNearestTextRect,recoverRange:recoverRange,resolveRange:resolveRange,selection:selection,install:install};
|
|
20697
20971
|
});
|
|
20698
20972
|
|
|
20699
20973
|
/* @papyrus-epub-annotations:end */
|
|
@@ -20709,6 +20983,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20709
20983
|
let annotationDocumentId;
|
|
20710
20984
|
let annotationLabels = {};
|
|
20711
20985
|
let epubAnnotations = [];
|
|
20986
|
+
let epubInkMode = {enabled:false,color:'#2563eb',opacity:1,strokeWidth:0.006};
|
|
20712
20987
|
const epubAnnotationRenderers = new Map();
|
|
20713
20988
|
let spineItems = [];
|
|
20714
20989
|
let textPages = [];
|
|
@@ -21823,11 +22098,14 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21823
22098
|
if (href && window.PapyrusEpubAnnotations) {
|
|
21824
22099
|
const renderer = window.PapyrusEpubAnnotations.install(contents, {
|
|
21825
22100
|
href, get documentId() { return annotationDocumentId; },
|
|
22101
|
+
spineIndex:contents.sectionIndex,
|
|
21826
22102
|
isCurrent: () => session === documentSessionId && activeRendition === rendition,
|
|
21827
22103
|
pageWidth: () => activeRendition.layout?.width || viewer.clientWidth,
|
|
21828
22104
|
annotations: () => epubAnnotations, labels: () => annotationLabels,
|
|
22105
|
+
onInkCommit: annotation => sendEvent('EPUB_INK_CREATED',{documentSessionId:session,annotation}),
|
|
21829
22106
|
onTap: (id, ids) => sendEvent("EPUB_ANNOTATION_TAP", {documentSessionId: session, id, ids}),
|
|
21830
22107
|
});
|
|
22108
|
+
renderer.setInkMode(epubInkMode);
|
|
21831
22109
|
epubAnnotationRenderers.set(contents,renderer);
|
|
21832
22110
|
}
|
|
21833
22111
|
const frame = contents && contents.document ? contents.document.defaultView.frameElement : null;
|
|
@@ -21919,7 +22197,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21919
22197
|
sendEvent('EPUB_TEXT_SELECTED', payload);
|
|
21920
22198
|
});
|
|
21921
22199
|
['rendered','resized','layout','relocated'].forEach(name => rendition.on(name, () => {
|
|
21922
|
-
if (selectionSession === documentSessionId && selectionRendition === rendition) epubAnnotationRenderers.forEach(renderer => renderer.schedule());
|
|
22200
|
+
if (selectionSession === documentSessionId && selectionRendition === rendition) epubAnnotationRenderers.forEach(renderer => name==='relocated'?renderer.schedule():renderer.invalidateLayout());
|
|
21923
22201
|
}));
|
|
21924
22202
|
rendition.on('relocated', (location) => {
|
|
21925
22203
|
if (selectionSession !== documentSessionId || selectionRendition !== rendition) return;
|
|
@@ -22216,6 +22494,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22216
22494
|
documentSessionId = payload.documentSessionId || null;
|
|
22217
22495
|
epubAnnotations = [];
|
|
22218
22496
|
annotationDocumentId = undefined;
|
|
22497
|
+
epubInkMode = {enabled:false,color:'#2563eb',opacity:1,strokeWidth:0.006};
|
|
22219
22498
|
zoom = 1.0;
|
|
22220
22499
|
epubViewMode = payload.epubMode === "chapter-scroll" ? "continuous" : "single";
|
|
22221
22500
|
epubLocation = null;
|
|
@@ -22347,6 +22626,12 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22347
22626
|
}
|
|
22348
22627
|
sendResponse(id,true,null);return;
|
|
22349
22628
|
}
|
|
22629
|
+
if (kind === 'set-epub-ink-mode') {
|
|
22630
|
+
if(currentType!=='epub'||!documentSessionId||payload.documentSessionId!==documentSessionId)throw new Error('Stale EPUB ink session');
|
|
22631
|
+
epubInkMode={enabled:payload.enabled===true,preset:['ink','highlight','underline'].indexOf(payload.preset)>=0?payload.preset:'ink',color:/^#[0-9a-f]{6}$/i.test(payload.color||'')?payload.color:'#2563eb',opacity:Number.isFinite(payload.opacity)?Math.max(0,Math.min(1,payload.opacity)):1,strokeWidth:Number.isFinite(payload.strokeWidth)?Math.max(0.0025,Math.min(0.02,payload.strokeWidth)):0.006};
|
|
22632
|
+
epubAnnotationRenderers.forEach(renderer=>renderer.setInkMode(epubInkMode));
|
|
22633
|
+
sendResponse(id,true,null);return;
|
|
22634
|
+
}
|
|
22350
22635
|
if(kind === 'epub-go-to-location'){
|
|
22351
22636
|
if(currentType!=='epub' || payload.documentSessionId!==documentSessionId || !window.PapyrusEpubReader.validCfi(payload.cfi))throw new Error('Invalid EPUB location');
|
|
22352
22637
|
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(()=>{if(payload.documentSessionId!==documentSessionId)return;epubResizeAnchor?.invalidate();return rendition.display(payload.cfi);});
|
|
@@ -25936,9 +26221,15 @@ var parseWebViewInteraction = (raw) => {
|
|
|
25936
26221
|
};
|
|
25937
26222
|
|
|
25938
26223
|
// components/epubAnnotationEvents.ts
|
|
25939
|
-
import { validateAnnotationAnchor } from "@papyrus-sdk/core";
|
|
26224
|
+
import { validateAnnotationAnchor, validateEpubInkData } from "@papyrus-sdk/core";
|
|
26225
|
+
var EPUB_INK_PRESETS = ["ink", "highlight", "underline"];
|
|
26226
|
+
function resolveEpubInkMode(input) {
|
|
26227
|
+
if (!input.isLoaded || input.documentType !== "epub") return null;
|
|
26228
|
+
const preset = EPUB_INK_PRESETS.includes(input.preset) ? input.preset : "ink";
|
|
26229
|
+
return { enabled: input.activeTool === "ink" && EPUB_INK_PRESETS.includes(input.preset), preset, color: input.color, opacity: input.opacity, strokeWidth: input.strokeWidth };
|
|
26230
|
+
}
|
|
25940
26231
|
function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
25941
|
-
if (!session || raw.length >
|
|
26232
|
+
if (!session || raw.length > 75e4) return null;
|
|
25942
26233
|
let message;
|
|
25943
26234
|
try {
|
|
25944
26235
|
message = JSON.parse(raw);
|
|
@@ -25948,6 +26239,13 @@ function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
|
25948
26239
|
const p = message?.payload;
|
|
25949
26240
|
if (message?.type !== "event" || !p || p.documentSessionId !== session) return null;
|
|
25950
26241
|
if (message.name === "EPUB_ANNOTATION_TAP") return typeof p.id === "string" && p.id.length <= 256 ? { kind: "tap", id: p.id, ids: Array.isArray(p.ids) && p.ids.length <= 100 && p.ids.every((id) => typeof id === "string" && id.length <= 256) ? p.ids : void 0 } : null;
|
|
26242
|
+
if (message.name === "EPUB_INK_CREATED") {
|
|
26243
|
+
const a = p.annotation, sidecar = a?.epubInk, first = sidecar?.segments?.[0], point = first?.points?.[0];
|
|
26244
|
+
if (!a || a.type !== "ink" || typeof a.id !== "string" || !a.id || a.id.length > 256 || !Number.isSafeInteger(a.pageIndex) || a.pageIndex < 1 || !validateAnnotationAnchor(a.anchor) || a.anchor.kind !== "epub-cfi" || !validateEpubInkData(sidecar) || !point || a.anchor.cfiRange !== point.cfiRange || a.anchor.quote !== point.quote || a.anchor.href !== first.href || documentId && (sidecar.documentId && sidecar.documentId !== documentId || a.anchor.documentId && a.anchor.documentId !== documentId) || sidecar.documentId && a.anchor.documentId && sidecar.documentId !== a.anchor.documentId) return null;
|
|
26245
|
+
const rect = a.rect, path = a.path;
|
|
26246
|
+
if (!rect || ![rect.x, rect.y, rect.width, rect.height].every((n) => typeof n === "number" && Number.isFinite(n) && n >= 0 && n <= 1) || rect.x + rect.width > 1.000001 || rect.y + rect.height > 1.000001 || !Array.isArray(path) || path.length < 2 || path.length > 512 || path.some((p2) => !p2 || ![p2.x, p2.y].every((n) => typeof n === "number" && Number.isFinite(n) && n >= 0 && n <= 1)) || typeof a.color !== "string" || !/^#[0-9a-f]{6}$/i.test(a.color) || !Number.isFinite(a.createdAt) || a.opacity !== void 0 && (!Number.isFinite(a.opacity) || a.opacity < 0 || a.opacity > 1) || a.strokeWidth !== void 0 && (!Number.isFinite(a.strokeWidth) || a.strokeWidth < 25e-4 || a.strokeWidth > 0.02)) return null;
|
|
26247
|
+
return { kind: "ink", session, annotation: a };
|
|
26248
|
+
}
|
|
25951
26249
|
if (message.name !== "EPUB_TEXT_SELECTED" || !validateAnnotationAnchor(p.anchor) || p.anchor.kind !== "epub-cfi" || p.text !== p.anchor.quote || !Number.isSafeInteger(p.pageIndex) || p.pageIndex < 1) return null;
|
|
25952
26250
|
if (documentId && p.anchor.documentId && p.anchor.documentId !== documentId) return null;
|
|
25953
26251
|
return { kind: "selection", session, text: p.text, pageIndex: p.pageIndex, anchor: { ...p.anchor, documentId: documentId ?? p.anchor.documentId } };
|
|
@@ -25984,7 +26282,7 @@ var WebViewViewer = ({
|
|
|
25984
26282
|
}) => {
|
|
25985
26283
|
const webViewRef = useRef2(null);
|
|
25986
26284
|
const insets = usePapyrusSafeAreaInsets();
|
|
25987
|
-
const { pageTheme, epubReadingMode, setDocumentState, annotations, isLoaded, locale, annotationColor, annotationOpacity, addAnnotation, beginAnnotationDraft, setSelectedAnnotation } = useViewerStore2();
|
|
26285
|
+
const { pageTheme, epubReadingMode, setDocumentState, annotations, isLoaded, locale, annotationColor, annotationOpacity, inkStrokeWidth, activeTool, activeDrawToolPreset, addAnnotation, beginAnnotationDraft, setSelectedAnnotation } = useViewerStore2();
|
|
25988
26286
|
const [selection, setSelection] = useState2(null);
|
|
25989
26287
|
const t = getStrings(locale);
|
|
25990
26288
|
const bridgeEngine = engine;
|
|
@@ -26069,6 +26367,15 @@ var WebViewViewer = ({
|
|
|
26069
26367
|
if (!isLoaded) return;
|
|
26070
26368
|
webViewRef.current?.postMessage(JSON.stringify({ id: "epub-layout", kind: "set-epub-view-mode", payload: { epubMode: epubReadingMode, documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.() } }));
|
|
26071
26369
|
}, [isLoaded, epubReadingMode, bridgeEngine]);
|
|
26370
|
+
useEffect2(() => {
|
|
26371
|
+
if (!isLoaded || documentType !== "epub") return;
|
|
26372
|
+
const inkMode = resolveEpubInkMode({ documentType, isLoaded, activeTool, preset: activeDrawToolPreset, color: annotationColor, opacity: annotationOpacity, strokeWidth: inkStrokeWidth });
|
|
26373
|
+
if (!inkMode) return;
|
|
26374
|
+
webViewRef.current?.postMessage(JSON.stringify({ id: `epub-ink-mode-${Date.now()}`, kind: "set-epub-ink-mode", payload: {
|
|
26375
|
+
...inkMode,
|
|
26376
|
+
documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.()
|
|
26377
|
+
} }));
|
|
26378
|
+
}, [isLoaded, documentType, activeTool, activeDrawToolPreset, annotationColor, annotationOpacity, inkStrokeWidth, bridgeEngine]);
|
|
26072
26379
|
const sendSelectionCommand = (key) => {
|
|
26073
26380
|
webViewRef.current?.postMessage(JSON.stringify({
|
|
26074
26381
|
type: "epub-selection-action",
|
|
@@ -26128,6 +26435,10 @@ var WebViewViewer = ({
|
|
|
26128
26435
|
else setSelectedAnnotation(annotationEvent.id);
|
|
26129
26436
|
return;
|
|
26130
26437
|
}
|
|
26438
|
+
if (annotationEvent?.kind === "ink" && isLoaded && annotationEvent.session === bridgeEngine.getWebViewDocumentSessionId?.()) {
|
|
26439
|
+
addAnnotation(annotationEvent.annotation);
|
|
26440
|
+
setSelection(null);
|
|
26441
|
+
}
|
|
26131
26442
|
const interaction = parseWebViewInteraction(raw);
|
|
26132
26443
|
if (interaction?.kind === "scroll") onScrollOffset?.(interaction.offsetY);
|
|
26133
26444
|
if (interaction?.kind === "tap") onTap?.();
|
|
@@ -32747,7 +33058,7 @@ function buildBottomBarLayout({
|
|
|
32747
33058
|
toolDockOpen
|
|
32748
33059
|
}) {
|
|
32749
33060
|
const leftSlots = [];
|
|
32750
|
-
if (documentType === "pdf") {
|
|
33061
|
+
if (documentType === "pdf" || documentType === "epub") {
|
|
32751
33062
|
leftSlots.push({
|
|
32752
33063
|
key: "annotate",
|
|
32753
33064
|
active: toolDockOpen || activeMobileDestination === "annotate"
|