|
|
@@ -0,0 +1,75 @@
|
|
|
+import Foundation
|
|
|
+
|
|
|
+enum RedditShareBridgeStyle {
|
|
|
+ static let messageHandlerName = "reddoraShare"
|
|
|
+
|
|
|
+ /// WKWebView does not implement navigator.share. Reddit's share button relies on it
|
|
|
+ /// in Safari, so we bridge to the native macOS share sheet.
|
|
|
+ static let injectionScript = """
|
|
|
+ (function() {
|
|
|
+ if (window.__reddoraShareBridgeInstalled) return;
|
|
|
+ window.__reddoraShareBridgeInstalled = true;
|
|
|
+
|
|
|
+ function hasBridge() {
|
|
|
+ return !!(
|
|
|
+ window.webkit &&
|
|
|
+ window.webkit.messageHandlers &&
|
|
|
+ window.webkit.messageHandlers.reddoraShare
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ window.__reddoraShareCallback = function(success) {
|
|
|
+ const resolve = window.__reddoraShareResolve;
|
|
|
+ const reject = window.__reddoraShareReject;
|
|
|
+ window.__reddoraShareResolve = null;
|
|
|
+ window.__reddoraShareReject = null;
|
|
|
+
|
|
|
+ if (success && resolve) {
|
|
|
+ resolve();
|
|
|
+ } else if (!success && reject) {
|
|
|
+ reject(new DOMException('Share canceled', 'AbortError'));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ function nativeShare(data) {
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ if (!hasBridge()) {
|
|
|
+ reject(new DOMException('Share unavailable', 'NotSupportedError'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ window.__reddoraShareResolve = resolve;
|
|
|
+ window.__reddoraShareReject = reject;
|
|
|
+ window.webkit.messageHandlers.reddoraShare.postMessage({
|
|
|
+ title: data && data.title ? String(data.title) : '',
|
|
|
+ text: data && data.text ? String(data.text) : '',
|
|
|
+ url: data && data.url ? String(data.url) : ''
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function canShare(data) {
|
|
|
+ if (!hasBridge()) return false;
|
|
|
+ if (!data) return true;
|
|
|
+ if (data.files && data.files.length) return false;
|
|
|
+ return !!(data.url || data.text || data.title);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Object.defineProperty(navigator, 'share', {
|
|
|
+ value: nativeShare,
|
|
|
+ configurable: true,
|
|
|
+ writable: true
|
|
|
+ });
|
|
|
+ Object.defineProperty(navigator, 'canShare', {
|
|
|
+ value: canShare,
|
|
|
+ configurable: true,
|
|
|
+ writable: true
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ navigator.share = nativeShare;
|
|
|
+ navigator.canShare = canShare;
|
|
|
+ }
|
|
|
+ })();
|
|
|
+ """
|
|
|
+}
|