From bf97194208e75cf5c6e8a445f22df5b71ab1c5fb Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 18 Nov 2022 13:07:00 +0800 Subject: [PATCH] Create a highlight of the selected text when a user saves --- .../Share/ShareExtensionViewModel.swift | 4 +- .../Sources/Models/PageScrapePayload.swift | 26 +++++++++-- .../Services/DataService/DataService.swift | 2 +- .../Sources/ShareExtension/ShareExtension.js | 45 ++++++++++++------- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionViewModel.swift b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionViewModel.swift index 54d0ce76e..e0c075476 100644 --- a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionViewModel.swift @@ -87,7 +87,7 @@ public class ShareExtensionViewModel: ObservableObject { let hostname = URL(string: payload.url)?.host ?? "" switch payload.contentType { - case let .html(html: _, title: title): + case let .html(html: _, title: title, _): self.title = title ?? "" self.url = hostname case .none: @@ -143,7 +143,7 @@ public class ShareExtensionViewModel: ObservableObject { localPdfURL: localUrl, url: pageScrapePayload.url ) - case let .html(html, title): + case let .html(html, title, _): newRequestID = try await services.dataService.createPage( id: requestId, originalHtml: html, diff --git a/apple/OmnivoreKit/Sources/Models/PageScrapePayload.swift b/apple/OmnivoreKit/Sources/Models/PageScrapePayload.swift index b21265db9..aafd4eb4c 100644 --- a/apple/OmnivoreKit/Sources/Models/PageScrapePayload.swift +++ b/apple/OmnivoreKit/Sources/Models/PageScrapePayload.swift @@ -8,11 +8,26 @@ import UniformTypeIdentifiers let URLREGEX = #"[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"# +public struct HighlightData { + public let highlightHTML: String + public let highlightText: String + + public static func make(dict: NSDictionary?) -> HighlightData? { + if let dict = dict, + let highlightHTML = dict["highlightHTML"] as? String, + let highlightText = dict["highlightText"] as? String + { + return HighlightData(highlightHTML: highlightHTML, highlightText: highlightText) + } + return nil + } +} + public struct PageScrapePayload { public enum ContentType { case none - case html(html: String, title: String?) case pdf(localUrl: URL) + case html(html: String, title: String?, highlightData: HighlightData?) } public let url: String @@ -33,9 +48,9 @@ public struct PageScrapePayload { self.contentType = .pdf(localUrl: localUrl) } - init(url: String, title: String?, html: String) { + init(url: String, title: String?, html: String, highlightData: HighlightData?) { self.url = url - self.contentType = .html(html: html, title: title) + self.contentType = .html(html: html, title: title, highlightData: highlightData) } } @@ -317,7 +332,10 @@ private extension PageScrapePayload { } if let html = html { - return PageScrapePayload(url: url, title: title, html: html) + return PageScrapePayload(url: url, + title: title, + html: html, + highlightData: HighlightData.make(dict: results)) } return PageScrapePayload(url: url) diff --git a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift index 92628976e..3c640c914 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift @@ -179,7 +179,7 @@ public final class DataService: ObservableObject { linkedItem.contentReader = "PDF" linkedItem.tempPDFURL = localUrl linkedItem.title = PDFUtils.titleFromPdfFile(pageScrape.url) - case let .html(html: html, title: title): + case let .html(html: html, title: title, highlightData: _): linkedItem.contentReader = "WEB" linkedItem.originalHtml = html linkedItem.title = title ?? PDFUtils.titleFromPdfFile(pageScrape.url) diff --git a/apple/Sources/ShareExtension/ShareExtension.js b/apple/Sources/ShareExtension/ShareExtension.js index 22e7ddda5..15aa00efc 100644 --- a/apple/Sources/ShareExtension/ShareExtension.js +++ b/apple/Sources/ShareExtension/ShareExtension.js @@ -11,34 +11,47 @@ function iconURL() { } ShareExtension.prototype = { - getHighlightHTML: function() { + markHighlightSelection: () => { try { - var sel = window.getSelection() - return (function () { - var html = ""; - var sel = window.getSelection(); - if (sel.rangeCount) { - var container = document.createElement("div"); - for (var i = 0, len = sel.rangeCount; i < len; ++i) { - container.appendChild(sel.getRangeAt(i).cloneContents()); - } - html = container.innerHTML; + const sel = window.getSelection(); + if (sel.rangeCount) { + const range = sel.getRangeAt(0) + const endMarker = document.createElement("span") + const startMarker = document.createElement("span") + endMarker.setAttribute("data-omnivore-highlight-end", true) + startMarker.setAttribute("data-omnivore-highlight-start", true) + + var container = document.createElement("div"); + for (var i = 0, len = sel.rangeCount; i < len; ++i) { + container.appendChild(sel.getRangeAt(i).cloneContents()); } - return html; - })() - } catch { - + + const endRange = range.cloneRange() + endRange.collapse(false) + endRange.insertNode(endMarker) + + range.insertNode(startMarker) + + return { + highlightHTML: container.innerHTML, + highlightText: container.innerText + } + } + } catch(error) { + console.log("ERROR", error) } return null }, run: function(arguments) { + const highlightData = this.markHighlightSelection() + arguments.completionFunction({ 'url': window.location.href, 'title': document.title.toString(), 'iconURL': iconURL(), 'contentType': document.contentType, 'originalHTML': new XMLSerializer().serializeToString(document), - 'highlightHTML': this.getHighlightHTML() + ...highlightData }); } };