Skip to content

Commit cba6550

Browse files
committed
Safari plugin #15: send selected text from Safari to text field in the app
1 parent 43bc87b commit cba6550

File tree

7 files changed

+60
-22
lines changed

7 files changed

+60
-22
lines changed

ReaderTranslator.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
F06DB10E23450B6000C2DE90 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06DB10C23450B6000C2DE90 /* View.swift */; };
2525
F06DB1122345ECC000C2DE90 /* StatusBarView_Voice_Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06DB1112345ECC000C2DE90 /* StatusBarView_Voice_Toggle.swift */; };
2626
F06DB1132345ECC000C2DE90 /* StatusBarView_Voice_Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06DB1112345ECC000C2DE90 /* StatusBarView_Voice_Toggle.swift */; };
27+
F06DB117234611BB00C2DE90 /* ExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06DB115234611BB00C2DE90 /* ExtensionManager.swift */; };
28+
F06DB1182346172D00C2DE90 /* ExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06DB115234611BB00C2DE90 /* ExtensionManager.swift */; };
2729
F075443A234479DA00E1D88E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0754439234479DA00E1D88E /* AppDelegate.swift */; };
2830
F075443E234479DB00E1D88E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F075443D234479DB00E1D88E /* Assets.xcassets */; };
2931
F0754441234479DB00E1D88E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F0754440234479DB00E1D88E /* Preview Assets.xcassets */; };
@@ -138,6 +140,7 @@
138140
F06DB109234504FD00C2DE90 /* EditorNSTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorNSTextView.swift; sourceTree = "<group>"; };
139141
F06DB10C23450B6000C2DE90 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
140142
F06DB1112345ECC000C2DE90 /* StatusBarView_Voice_Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarView_Voice_Toggle.swift; sourceTree = "<group>"; };
143+
F06DB115234611BB00C2DE90 /* ExtensionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionManager.swift; sourceTree = "<group>"; };
141144
F0754437234479DA00E1D88E /* ReaderTranslatorMac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReaderTranslatorMac.app; sourceTree = BUILT_PRODUCTS_DIR; };
142145
F0754439234479DA00E1D88E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
143146
F075443D234479DB00E1D88E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -391,6 +394,7 @@
391394
children = (
392395
F0AA69D7232E978E007CC07B /* Store.swift */,
393396
F0039EC223447E24002F3F95 /* SharedContainer.swift */,
397+
F06DB115234611BB00C2DE90 /* ExtensionManager.swift */,
394398
);
395399
path = Stores;
396400
sourceTree = "<group>";
@@ -681,6 +685,7 @@
681685
F0BB436C2344842200ADBEF1 /* ReaderView.swift in Sources */,
682686
F0BB437A2344845000ADBEF1 /* StatusBarView_Zoom.swift in Sources */,
683687
F0BB43812344846200ADBEF1 /* ReaderView_PDF.swift in Sources */,
688+
F06DB117234611BB00C2DE90 /* ExtensionManager.swift in Sources */,
684689
F0BB43722344843D00ADBEF1 /* FavoriteVoiceName.swift in Sources */,
685690
F0BB43712344843900ADBEF1 /* UserDefault.swift in Sources */,
686691
F0BB437C2344845000ADBEF1 /* StatusBarView_PdfPage.swift in Sources */,
@@ -695,6 +700,7 @@
695700
buildActionMask = 2147483647;
696701
files = (
697702
F075445423447A2800E1D88E /* SafariExtensionViewController.swift in Sources */,
703+
F06DB1182346172D00C2DE90 /* ExtensionManager.swift in Sources */,
698704
F075445223447A2800E1D88E /* SafariExtensionHandler.swift in Sources */,
699705
F0039EC423447E24002F3F95 /* SharedContainer.swift in Sources */,
700706
);

ReaderTranslator.xcodeproj/xcuserdata/filimo.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212
<key>ReaderTranslator.xcscheme_^#shared#^_</key>
1313
<dict>
1414
<key>orderHint</key>
15-
<integer>2</integer>
15+
<integer>0</integer>
1616
</dict>
1717
<key>ReaderTranslatorMac.xcscheme_^#shared#^_</key>
1818
<dict>
1919
<key>orderHint</key>
20-
<integer>0</integer>
20+
<integer>1</integer>
2121
</dict>
2222
<key>ReaderTranslatorSafari.xcscheme_^#shared#^_</key>
2323
<dict>
2424
<key>orderHint</key>
25-
<integer>1</integer>
25+
<integer>2</integer>
2626
</dict>
2727
</dict>
2828
<key>SuppressBuildableAutocreation</key>

ReaderTranslator/Components/WebView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ extension PageWebView {
195195
override public var keyCommands: [UIKeyCommand]? {
196196
//Voice selected text with any key since performCommand isn't fired because PageWebView isn't the first responder.
197197
SpeechSynthesizer.speak(stopSpeaking: true, isVoiceEnabled: true)
198-
return [.init(input: "1", modifierFlags: .command, action: #selector(performCommand))]
198+
return [.init(input: "1", modifierFlags: .command, eventName: #selector(performCommand))]
199199
}
200200

201201
@objc func performCommand(sender: UIKeyCommand) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// ExtensionListener.swift
3+
// ReaderTranslator
4+
//
5+
// Created by Viktor Kushnerov on 10/3/19.
6+
// Copyright © 2019 Viktor Kushnerov. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
class SafariExtensionManager {
12+
typealias onMessageChangedType = (_ name: String) -> ()
13+
14+
static private let center = CFNotificationCenterGetDarwinNotifyCenter()
15+
16+
static private let domainName = "by.filimo.ReaderTranslatorMac.ReaderTranslatorSafari"
17+
static private let notificationName = "onMessagedChanged"
18+
static private var eventName: CFString { "\(domainName).\(notificationName)" as CFString }
19+
20+
private var onMessageChanged: onMessageChangedType?
21+
22+
func start(onMessageChanged: @escaping onMessageChangedType) {
23+
self.onMessageChanged = onMessageChanged
24+
CFNotificationCenterAddObserver(Self.center, Unmanaged.passRetained(self).toOpaque(), callBack, Self.eventName, nil, .deliverImmediately)
25+
}
26+
27+
deinit {
28+
CFNotificationCenterRemoveEveryObserver(Self.center, Unmanaged.passRetained(self).toOpaque())
29+
}
30+
31+
private var callBack: CFNotificationCallback = { (_, observer, name, object, _) -> () in
32+
if let observer = observer, let name = name {
33+
let safariExtensionManagerSelf = Unmanaged<SafariExtensionManager>.fromOpaque(observer).takeUnretainedValue()
34+
safariExtensionManagerSelf.onMessageChanged?(name.rawValue as String)
35+
}
36+
}
37+
38+
static func didMessageChanged() {
39+
CFNotificationCenterPostNotification(center, .init(eventName), nil, nil, true)
40+
}
41+
}
42+

ReaderTranslator/Views/ReaderView/ReaderView_Safari.swift

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,20 @@ import SwiftUI
1010

1111
struct ReaderView_Safari: View {
1212
@ObservedObject private var store = Store.shared
13-
static private var timer = Timer()
1413

1514
var body: some View {
1615
Group {
1716
#if os(macOS)
1817
if store.viewMode == .safari {
19-
// EditorNSTextView(text: $text)
2018
Text(store.selectedText)
21-
.onAppear {
22-
print("ReaderView_Safari_onAppear")
23-
ReaderView_Safari.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
24-
print("ReaderView_Safari_timer", self.store.selectedText)
25-
if self.store.selectedText == SharedContainer.string() { return }
26-
self.store.selectedText = SharedContainer.string()
27-
SpeechSynthesizer.speak()
28-
}
29-
}
30-
.onDisappear {
31-
print("ReaderView_Safari_onDisappear")
32-
ReaderView_Safari.timer.invalidate()
33-
ReaderView_Safari.timer = Timer()
34-
}
3519
}
3620
#endif
3721
}
22+
.onAppear {
23+
SafariExtensionManager().start(onMessageChanged: { notificationName in
24+
self.store.selectedText = SharedContainer.string()
25+
})
26+
}
3827
}
3928
}
4029

ReaderTranslatorSafari/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
<key>CFBundlePackageType</key>
1818
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1919
<key>CFBundleShortVersionString</key>
20-
<string>1.0001</string>
20+
<string>1.1</string>
2121
<key>CFBundleVersion</key>
22-
<string>1.0001</string>
22+
<string>1.1</string>
2323
<key>LSMinimumSystemVersion</key>
2424
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
2525
<key>NSExtension</key>

ReaderTranslatorSafari/SafariExtensionHandler.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class SafariExtensionHandler: SFSafariExtensionHandler {
1818
.removeDuplicates()
1919
.sink { message in
2020
SharedContainer.set(value: message)
21+
SafariExtensionManager.didMessageChanged()
2122
}
2223

2324
return pub

0 commit comments

Comments
 (0)