Skip to content

Commit c403181

Browse files
committed
handle pdf w/text representation
1 parent e8d953f commit c403181

1 file changed

Lines changed: 132 additions & 33 deletions

File tree

previewers/betatest/js/refiqdacore.js

Lines changed: 132 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -282,35 +282,61 @@ function parseData2(data) {
282282

283283
if (selections != null && selections.length != 0) {
284284
selections.forEach(function(selection) {
285-
let selectionMatches = sourceMatches + selection.getAttribute("creatingUser") + selection.getAttribute("modifyingUser");
286-
selectionMatches = selectionMatches + getCodeRelatedGUIDs(selection);
287-
288-
// Get position information for PlainTextSelection
289-
let selectionName = selection.getAttribute("name");
290-
let startPos = selection.getAttribute("startPosition");
291-
let endPos = selection.getAttribute("endPosition");
292-
let plainTextPath = source.getAttribute("plainTextPath");
293-
let sourceGuid = source.getAttribute("guid");
294-
295-
// Create tooltip-enabled name if we have position data
296-
let displayName = selectionName;
297-
if (selection.nodeName === "PDFSelection") {
298-
let page = selection.getAttribute("page");
299-
let firstX = selection.getAttribute("firstX");
300-
let firstY = selection.getAttribute("firstY");
301-
let secondX = selection.getAttribute("secondX");
302-
let secondY = selection.getAttribute("secondY");
303-
displayName = createPdfSelectionWithTooltip(selectionName, page, firstX, firstY, secondX, secondY, sourceGuid);
304-
} else if (selection.nodeName === "PlainTextSelection" && startPos && endPos && plainTextPath) {
305-
displayName = createSelectionWithTooltip(selectionName, startPos, endPos, plainTextPath, sourceGuid);
285+
let displayName;
286+
let selectionMatches;
287+
let guid;
288+
let codes;
289+
290+
if (selection.isMerged) {
291+
// Handle merged selection object
292+
let pdfSel = selection.pdfSelection;
293+
let textSel = selection.plainTextSelection;
294+
let selectionName = pdfSel.getAttribute("name");
295+
guid = pdfSel.getAttribute("guid");
296+
codes = getCodeNames(pdfSel); // Codes are on the PDF selection
297+
298+
selectionMatches = sourceMatches +
299+
pdfSel.getAttribute("creatingUser") + pdfSel.getAttribute("modifyingUser") +
300+
textSel.getAttribute("creatingUser") + textSel.getAttribute("modifyingUser") +
301+
getCodeRelatedGUIDs(pdfSel);
302+
303+
let sourceGuid = source.getAttribute("guid");
304+
305+
displayName = createMergedSelectionWithTooltip(selectionName, pdfSel, textSel, sourceGuid);
306+
307+
} else {
308+
// Handle regular selection node
309+
let selectionName = selection.getAttribute("name");
310+
guid = selection.getAttribute("guid");
311+
codes = getCodeNames(selection);
312+
selectionMatches = sourceMatches + selection.getAttribute("creatingUser") + selection.getAttribute("modifyingUser") + getCodeRelatedGUIDs(selection);
313+
314+
let sourceGuid = source.getAttribute("guid");
315+
displayName = selectionName; // Default display name
316+
317+
if (selection.nodeName === "PDFSelection") {
318+
let page = selection.getAttribute("page");
319+
let firstX = selection.getAttribute("firstX");
320+
let firstY = selection.getAttribute("firstY");
321+
let secondX = selection.getAttribute("secondX");
322+
let secondY = selection.getAttribute("secondY");
323+
displayName = createPdfSelectionWithTooltip(selectionName, page, firstX, firstY, secondX, secondY, sourceGuid);
324+
} else if (selection.nodeName === "PlainTextSelection") {
325+
let startPos = selection.getAttribute("startPosition");
326+
let endPos = selection.getAttribute("endPosition");
327+
let plainTextPath = source.getAttribute("plainTextPath");
328+
if (startPos && endPos && plainTextPath) {
329+
displayName = createSelectionWithTooltip(selectionName, startPos, endPos, plainTextPath, sourceGuid);
330+
}
331+
}
306332
}
307333

308334
annotationRows.push({
309-
sourceRef: createSourceReference(source),
335+
sourceRef: createSourceReference(source, zipUrl),
310336
type: source.nodeName,
311337
name: displayName,
312-
codes: getCodeNames(selection),
313-
guid: selection.getAttribute("guid"),
338+
codes: codes,
339+
guid: guid,
314340
matches: selectionMatches
315341
});
316342
});
@@ -791,12 +817,44 @@ function createRefiqdaFilterFunction(dataTable) {
791817
}
792818

793819
function getSelections(source) {
794-
let children = source.getElementsByTagName("*");
795820
let selections = [];
796-
for (let child of children) {
797-
if (child.nodeName.endsWith("Selection")) {
798-
// console.log(child.getAttribute("name"));
799-
selections.push(child);
821+
// If it's a PDF source, we look for both PDF and PlainText selections to merge them
822+
if (source.nodeName === "PDFSource") {
823+
const representation = source.querySelector("Representation");
824+
const plainTextSelections = new Map();
825+
826+
// Map PlainTextSelections by their GUID from the Representation, if it exists
827+
if (representation) {
828+
for (const pts of representation.getElementsByTagName("PlainTextSelection")) {
829+
plainTextSelections.set(pts.getAttribute("guid"), pts);
830+
}
831+
}
832+
833+
// Process PDFSelections
834+
for (const pdfSel of source.getElementsByTagName("PDFSelection")) {
835+
const guid = pdfSel.getAttribute("guid");
836+
const matchingPlainTextSel = plainTextSelections.get(guid);
837+
838+
if (matchingPlainTextSel) {
839+
// Found a pair, create a merged object
840+
selections.push({
841+
isMerged: true,
842+
pdfSelection: pdfSel,
843+
plainTextSelection: matchingPlainTextSel
844+
});
845+
// Remove from map so we don't process it again
846+
plainTextSelections.delete(guid);
847+
} else {
848+
// It's a PDF-only selection
849+
selections.push(pdfSel);
850+
}
851+
}
852+
} else {
853+
// For other source types, get direct children ending in "Selection"
854+
for (const child of source.children) {
855+
if (child.nodeName.endsWith("Selection")) {
856+
selections.push(child);
857+
}
800858
}
801859
}
802860
return selections;
@@ -816,18 +874,18 @@ function getCodeRelatedGUIDs(selection) {
816874
}
817875

818876
function getCodeNames(selection) {
819-
let codeNames = '';
877+
let codeNameList = [];
820878
let codings = selection.getElementsByTagName("Coding");
821879
if (codings != null) {
822880
for (let coding of codings) {
823881
let codeId = coding.getElementsByTagName("CodeRef")[0].getAttribute("targetGUID");
824882
let code = codeMap.get(codeId);
825883
if (code != null) {
826-
codeNames = codeNames + ' ' + code.getAttribute("name");
884+
codeNameList.push(code.getAttribute("name"));
827885
}
828886
}
829887
}
830-
return codeNames;
888+
return codeNameList.join(', ');
831889
}
832890

833891
// Update the createSelectionWithTooltip function to use a simpler data structure
@@ -844,6 +902,39 @@ function createSelectionWithTooltip(selectionName, startPos, endPos, plainTextPa
844902
return spanHtml;
845903
}
846904

905+
function createMergedSelectionWithTooltip(selectionName, pdfSel, plainTextSel, sourceGuid) {
906+
// Extract data from both selection types
907+
const page = pdfSel.getAttribute("page");
908+
const firstX = pdfSel.getAttribute("firstX");
909+
const firstY = pdfSel.getAttribute("firstY");
910+
const secondX = pdfSel.getAttribute("secondX");
911+
const secondY = pdfSel.getAttribute("secondY");
912+
913+
const startPos = plainTextSel.getAttribute("startPosition");
914+
const endPos = plainTextSel.getAttribute("endPosition");
915+
const plainTextPath = plainTextSel.closest("Representation").getAttribute("plainTextPath");
916+
917+
// Create the HTML content for the Tippy tooltip
918+
let tooltipContent = `Page: ${page} (X:${firstX}, Y:${firstY}) to (X:${secondX}, Y:${secondY})`;
919+
920+
// Create a span with data attributes for both PDF and Text functionality
921+
let spanHtml = '<span class="selection-with-excerpt selection-with-pdf-coords" ' +
922+
'data-tippy-content="' + tooltipContent + '" ' +
923+
'data-page="' + page + '" ' +
924+
'data-first-x="' + firstX + '" ' +
925+
'data-first-y="' + firstY + '" ' +
926+
'data-second-x="' + secondX + '" ' +
927+
'data-second-y="' + secondY + '" ' +
928+
'data-start="' + startPos + '" ' +
929+
'data-end="' + endPos + '" ' +
930+
'data-path="' + plainTextPath + '" ' +
931+
'data-source-guid="' + sourceGuid + '">' +
932+
selectionName +
933+
'</span>';
934+
935+
return spanHtml;
936+
}
937+
847938
function createPdfSelectionWithTooltip(selectionName, page, firstX, firstY, secondX, secondY, sourceGuid) {
848939
// Create the HTML content for the Tippy tooltip
849940
let tooltipContent = `Page: ${page}<br>From: (X:${firstX}, Y:${firstY})<br>To: (X:${secondX}, Y:${secondY})`;
@@ -957,7 +1048,15 @@ function initializeExcerptTooltips() {
9571048
loadTextExcerpt(plainTextPath, startPos, endPos, sourceGuid)
9581049
.then(excerpt => {
9591050
if (excerpt) {
960-
const formattedContent = formatExcerptTooltip(excerpt, startPos, endPos);
1051+
let formattedContent = formatExcerptTooltip(excerpt, startPos, endPos);
1052+
// For merged selections, prepend the PDF coordinate info
1053+
if (element.classList.contains('selection-with-pdf-coords')) {
1054+
const pdfInfo = element.getAttribute('data-tippy-content');
1055+
if (pdfInfo) {
1056+
const pdfHtml = `<div style="padding: 8px 8px 0 8px; font-family: sans-serif; font-size: 11px; color: #666;">${pdfInfo}</div>`;
1057+
formattedContent = pdfHtml + formattedContent;
1058+
}
1059+
}
9611060
instance.setContent(formattedContent);
9621061
element.setAttribute('data-tooltip-loaded', 'true');
9631062
} else {

0 commit comments

Comments
 (0)