@design.estate/dees-catalog 3.41.2 → 3.41.3

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.
@@ -142108,6 +142108,7 @@ var viewerStyles = [
142108
142108
  border-radius: 4px;
142109
142109
  overflow: hidden;
142110
142110
  display: inline-block;
142111
+ position: relative;
142111
142112
  }
142112
142113
 
142113
142114
  .page-canvas {
@@ -142116,6 +142117,52 @@ var viewerStyles = [
142116
142117
  image-rendering: crisp-edges;
142117
142118
  }
142118
142119
 
142120
+ /* Text layer for selection */
142121
+ .text-layer {
142122
+ position: absolute;
142123
+ inset: 0;
142124
+ overflow: visible;
142125
+ line-height: 1;
142126
+ text-size-adjust: none;
142127
+ forced-color-adjust: none;
142128
+ transform-origin: 0 0;
142129
+ z-index: 1;
142130
+ user-select: text;
142131
+ -webkit-user-select: text;
142132
+ }
142133
+
142134
+ .text-layer span,
142135
+ .text-layer br {
142136
+ color: transparent;
142137
+ position: absolute;
142138
+ white-space: pre;
142139
+ cursor: text;
142140
+ transform-origin: 0% 0%;
142141
+ user-select: text;
142142
+ -webkit-user-select: text;
142143
+ }
142144
+
142145
+ .text-layer ::selection {
142146
+ background: rgba(0, 100, 200, 0.3);
142147
+ }
142148
+
142149
+ .text-layer br::selection {
142150
+ background: transparent;
142151
+ }
142152
+
142153
+ .text-layer .endOfContent {
142154
+ display: block;
142155
+ position: absolute;
142156
+ inset: 100% 0 0;
142157
+ z-index: 0;
142158
+ cursor: default;
142159
+ user-select: none;
142160
+ }
142161
+
142162
+ .text-layer.selecting .endOfContent {
142163
+ top: 0;
142164
+ }
142165
+
142119
142166
  .pdf-viewer.with-sidebar .viewer-main {
142120
142167
  margin-left: 0;
142121
142168
  }
@@ -142221,6 +142268,7 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142221
142268
  __publicField(this, "currentRenderPromise", null);
142222
142269
  __publicField(this, "thumbnailRenderTasks", []);
142223
142270
  __publicField(this, "pageRenderTasks", /* @__PURE__ */ new Map());
142271
+ __publicField(this, "textLayerRenderTasks", /* @__PURE__ */ new Map());
142224
142272
  __publicField(this, "canvas");
142225
142273
  __publicField(this, "ctx");
142226
142274
  __publicField(this, "viewerMain", null);
@@ -142393,6 +142441,7 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142393
142441
  <div class="page-wrapper" data-page="${item.page}">
142394
142442
  <div class="canvas-container">
142395
142443
  <canvas class="page-canvas" data-page="${item.page}"></canvas>
142444
+ <div class="text-layer" data-page="${item.page}"></div>
142396
142445
  </div>
142397
142446
  </div>
142398
142447
  `
@@ -142465,7 +142514,8 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142465
142514
  this.pageData = Array.from({ length: this.totalPages }, (_4, i11) => ({
142466
142515
  page: i11 + 1,
142467
142516
  rendered: false,
142468
- rendering: false
142517
+ rendering: false,
142518
+ textLayerRendered: false
142469
142519
  }));
142470
142520
  this.loading = false;
142471
142521
  await this.updateComplete;
@@ -142571,6 +142621,7 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142571
142621
  pageInfo.rendered = true;
142572
142622
  pageInfo.rendering = false;
142573
142623
  this.pageRenderTasks.delete(pageNum);
142624
+ await this.renderTextLayer(pageNum);
142574
142625
  this.requestUpdate("pageData");
142575
142626
  } catch (error) {
142576
142627
  if (error?.name !== "RenderingCancelledException") {
@@ -142580,6 +142631,100 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142580
142631
  this.pageRenderTasks.delete(pageNum);
142581
142632
  }
142582
142633
  }
142634
+ async renderTextLayer(pageNum) {
142635
+ const pageInfo = this.pageData.find((p7) => p7.page === pageNum);
142636
+ if (!pageInfo || pageInfo.textLayerRendered) return;
142637
+ try {
142638
+ const textLayerDiv = this.shadowRoot?.querySelector(
142639
+ `.text-layer[data-page="${pageNum}"]`
142640
+ );
142641
+ if (!textLayerDiv) return;
142642
+ textLayerDiv.innerHTML = "";
142643
+ const page = await this.pdfDocument.getPage(pageNum);
142644
+ const textContent = await page.getTextContent();
142645
+ const viewport = this.computeViewport(page);
142646
+ const pdfjs = await import("https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/+esm");
142647
+ textLayerDiv.style.width = `${viewport.width}px`;
142648
+ textLayerDiv.style.height = `${viewport.height}px`;
142649
+ textLayerDiv.style.setProperty("--scale-factor", String(viewport.scale));
142650
+ const textLayerRenderTask = pdfjs.renderTextLayer({
142651
+ textContentSource: textContent,
142652
+ container: textLayerDiv,
142653
+ viewport
142654
+ });
142655
+ this.textLayerRenderTasks.set(pageNum, textLayerRenderTask);
142656
+ await textLayerRenderTask.promise;
142657
+ const endOfContent = document.createElement("div");
142658
+ endOfContent.className = "endOfContent";
142659
+ textLayerDiv.appendChild(endOfContent);
142660
+ let isDragging = false;
142661
+ let anchorNode = null;
142662
+ let anchorOffset = 0;
142663
+ const getTextPositionFromPoint = (x3, y5) => {
142664
+ const spans = Array.from(textLayerDiv.querySelectorAll("span"));
142665
+ for (const span of spans) {
142666
+ const rect = span.getBoundingClientRect();
142667
+ if (x3 >= rect.left && x3 <= rect.right && y5 >= rect.top && y5 <= rect.bottom) {
142668
+ const textNode = span.firstChild;
142669
+ if (textNode && textNode.nodeType === Node.TEXT_NODE) {
142670
+ const text9 = textNode.textContent || "";
142671
+ const charWidth = rect.width / text9.length;
142672
+ const relativeX = x3 - rect.left;
142673
+ const offset = Math.min(Math.round(relativeX / charWidth), text9.length);
142674
+ return { node: textNode, offset };
142675
+ }
142676
+ }
142677
+ }
142678
+ return null;
142679
+ };
142680
+ const handleMouseUp = () => {
142681
+ if (isDragging) {
142682
+ isDragging = false;
142683
+ anchorNode = null;
142684
+ textLayerDiv.classList.remove("selecting");
142685
+ }
142686
+ document.removeEventListener("mouseup", handleMouseUp);
142687
+ document.removeEventListener("mousemove", handleMouseMove);
142688
+ };
142689
+ const handleMouseMove = (e11) => {
142690
+ if (!isDragging || !anchorNode) return;
142691
+ e11.preventDefault();
142692
+ const pos = getTextPositionFromPoint(e11.clientX, e11.clientY);
142693
+ if (pos) {
142694
+ const selection = window.getSelection();
142695
+ if (selection) {
142696
+ try {
142697
+ selection.setBaseAndExtent(anchorNode, anchorOffset, pos.node, pos.offset);
142698
+ } catch (err) {
142699
+ }
142700
+ }
142701
+ }
142702
+ };
142703
+ textLayerDiv.addEventListener("mousedown", (e11) => {
142704
+ if (e11.button !== 0) return;
142705
+ const pos = getTextPositionFromPoint(e11.clientX, e11.clientY);
142706
+ if (pos) {
142707
+ e11.preventDefault();
142708
+ isDragging = true;
142709
+ anchorNode = pos.node;
142710
+ anchorOffset = pos.offset;
142711
+ textLayerDiv.classList.add("selecting");
142712
+ const selection = window.getSelection();
142713
+ selection?.removeAllRanges();
142714
+ document.addEventListener("mousemove", handleMouseMove);
142715
+ document.addEventListener("mouseup", handleMouseUp);
142716
+ }
142717
+ });
142718
+ pageInfo.textLayerRendered = true;
142719
+ page.cleanup?.();
142720
+ this.textLayerRenderTasks.delete(pageNum);
142721
+ } catch (error) {
142722
+ if (error?.name !== "RenderingCancelledException") {
142723
+ console.error(`Error rendering text layer for page ${pageNum}:`, error);
142724
+ }
142725
+ this.textLayerRenderTasks.delete(pageNum);
142726
+ }
142727
+ }
142583
142728
  updateCurrentPage() {
142584
142729
  if (!this.viewerMain) return;
142585
142730
  const scrollTop = this.viewerMain.scrollTop;
@@ -142776,6 +142921,7 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142776
142921
  this.pageData.forEach((page) => {
142777
142922
  page.rendered = false;
142778
142923
  page.rendering = false;
142924
+ page.textLayerRendered = false;
142779
142925
  });
142780
142926
  this.pageRenderTasks.forEach((task) => {
142781
142927
  try {
@@ -142784,55 +142930,130 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142784
142930
  }
142785
142931
  });
142786
142932
  this.pageRenderTasks.clear();
142933
+ this.textLayerRenderTasks.forEach((task) => {
142934
+ try {
142935
+ task.cancel?.();
142936
+ } catch (error) {
142937
+ }
142938
+ });
142939
+ this.textLayerRenderTasks.clear();
142787
142940
  this.requestUpdate();
142788
142941
  this.updateComplete.then(() => {
142789
142942
  this.renderVisiblePages();
142790
142943
  });
142791
142944
  }
142792
- downloadPdf() {
142793
- const link3 = document.createElement("a");
142794
- link3.href = this.pdfUrl;
142795
- link3.download = this.pdfUrl.split("/").pop() || "document.pdf";
142796
- link3.click();
142945
+ async downloadPdf() {
142946
+ if (!this.pdfDocument) return;
142947
+ try {
142948
+ const data = await this.pdfDocument.getData();
142949
+ const blob = new Blob([data.buffer], { type: "application/pdf" });
142950
+ const blobUrl = URL.createObjectURL(blob);
142951
+ const link3 = document.createElement("a");
142952
+ link3.href = blobUrl;
142953
+ link3.download = this.pdfUrl ? this.pdfUrl.split("/").pop() || "document.pdf" : "document.pdf";
142954
+ link3.click();
142955
+ setTimeout(() => URL.revokeObjectURL(blobUrl), 1e3);
142956
+ } catch (error) {
142957
+ console.error("Error downloading PDF:", error);
142958
+ }
142797
142959
  }
142798
- printPdf() {
142799
- window.open(this.pdfUrl, "_blank")?.print();
142960
+ async printPdf() {
142961
+ if (!this.pdfDocument) return;
142962
+ try {
142963
+ const data = await this.pdfDocument.getData();
142964
+ const blob = new Blob([data.buffer], { type: "application/pdf" });
142965
+ const pdfUrl = URL.createObjectURL(blob);
142966
+ const htmlContent = `
142967
+ <!DOCTYPE html>
142968
+ <html>
142969
+ <head>
142970
+ <title>Print PDF</title>
142971
+ <style>
142972
+ * { margin: 0; padding: 0; }
142973
+ html, body { width: 100%; height: 100%; overflow: hidden; }
142974
+ iframe { width: 100%; height: 100%; border: none; }
142975
+ @media print {
142976
+ html, body, iframe { width: 100%; height: 100%; }
142977
+ }
142978
+ </style>
142979
+ </head>
142980
+ <body>
142981
+ <iframe src="${pdfUrl}" type="application/pdf"></iframe>
142982
+ <script>
142983
+ window.onload = function() {
142984
+ setTimeout(function() {
142985
+ window.focus();
142986
+ window.print();
142987
+ }, 500);
142988
+ };
142989
+ window.onafterprint = function() {
142990
+ window.close();
142991
+ };
142992
+ // Safety close after 2 minutes
142993
+ setTimeout(function() { window.close(); }, 120000);
142994
+ <\/script>
142995
+ </body>
142996
+ </html>
142997
+ `;
142998
+ const htmlBlob = new Blob([htmlContent], { type: "text/html" });
142999
+ const htmlUrl = URL.createObjectURL(htmlBlob);
143000
+ const printWindow = window.open(htmlUrl, "_blank", "width=800,height=600");
143001
+ if (printWindow) {
143002
+ const checkClosed = setInterval(() => {
143003
+ if (printWindow.closed) {
143004
+ clearInterval(checkClosed);
143005
+ URL.revokeObjectURL(pdfUrl);
143006
+ URL.revokeObjectURL(htmlUrl);
143007
+ }
143008
+ }, 500);
143009
+ setTimeout(() => {
143010
+ clearInterval(checkClosed);
143011
+ URL.revokeObjectURL(pdfUrl);
143012
+ URL.revokeObjectURL(htmlUrl);
143013
+ }, 12e4);
143014
+ } else {
143015
+ window.open(pdfUrl, "_blank");
143016
+ setTimeout(() => URL.revokeObjectURL(pdfUrl), 6e4);
143017
+ URL.revokeObjectURL(htmlUrl);
143018
+ }
143019
+ } catch (error) {
143020
+ console.error("Error printing PDF:", error);
143021
+ }
142800
143022
  }
142801
143023
  /**
142802
143024
  * Provide context menu items for right-click functionality
142803
143025
  */
142804
143026
  getContextMenuItems() {
142805
- return [
142806
- {
142807
- name: "Open PDF in New Tab",
142808
- iconName: "lucide:ExternalLink",
142809
- action: async () => {
142810
- window.open(this.pdfUrl, "_blank");
142811
- }
142812
- },
142813
- { divider: true },
142814
- {
142815
- name: "Copy PDF URL",
143027
+ const items = [];
143028
+ const selection = window.getSelection();
143029
+ const selectedText = selection?.toString() || "";
143030
+ if (selectedText) {
143031
+ items.push({
143032
+ name: "Copy",
142816
143033
  iconName: "lucide:Copy",
142817
143034
  action: async () => {
142818
- await navigator.clipboard.writeText(this.pdfUrl);
143035
+ await navigator.clipboard.writeText(selectedText);
142819
143036
  }
142820
- },
143037
+ });
143038
+ items.push({ divider: true });
143039
+ }
143040
+ items.push(
142821
143041
  {
142822
143042
  name: "Download PDF",
142823
143043
  iconName: "lucide:Download",
142824
143044
  action: async () => {
142825
- this.downloadPdf();
143045
+ await this.downloadPdf();
142826
143046
  }
142827
143047
  },
142828
143048
  {
142829
143049
  name: "Print PDF",
142830
143050
  iconName: "lucide:Printer",
142831
143051
  action: async () => {
142832
- this.printPdf();
143052
+ await this.printPdf();
142833
143053
  }
142834
143054
  }
142835
- ];
143055
+ );
143056
+ return items;
142836
143057
  }
142837
143058
  get canZoomIn() {
142838
143059
  return this.viewportMode !== "custom" || this.currentZoom < this.MANUAL_MAX_ZOOM;
@@ -142956,6 +143177,13 @@ var DeesPdfViewer = class extends (_a73 = DeesElement, _pdfUrl_dec = [n5({ type:
142956
143177
  }
142957
143178
  });
142958
143179
  this.pageRenderTasks.clear();
143180
+ this.textLayerRenderTasks.forEach((task) => {
143181
+ try {
143182
+ task.cancel?.();
143183
+ } catch (error) {
143184
+ }
143185
+ });
143186
+ this.textLayerRenderTasks.clear();
142959
143187
  for (const task of this.thumbnailRenderTasks || []) {
142960
143188
  try {
142961
143189
  task.cancel();