diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6882459..af80ff6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: echo ::set-output name=TXZ_PATH::$(make where-txz 2>/dev/null | tail -n1) - name: Build All Apps run: | - make allapps + make XCODE=1 allapps env: DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer - name: Create Package diff --git a/Makefile b/Makefile index 5fee099..e427da0 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ bundle_untracked ?= 0 appnames = $(patsubst $(macpin_sites)/%,%.app,$(wildcard $(macpin_sites)/*)) usage help: - @printf '\nusage:\tmake (V=1) \n\ntargets:\n%s' + @printf '\nusage:\tmake (V=1) (XCODE=1) \n\ntargets:\n%s' @printf '\t%s\n' allapps reinstall uninstall test test.app sites/* include eXcode.mk @@ -129,6 +129,7 @@ GH_RELEASE_JSON = '{"tag_name": "v$(VERSION)","target_commitish": "master","name $(xcassets)/%.xcassets: $(macpin_sites)/%/icon.png $(swiftrun_mac) iconify $(icontypes) $< $@ + iconutil --convert icns $@/Icon.iconset $(xcassets)/%.xcassets: templates/xcassets/$(platform)/%/*.png for i in $^; do $(swiftrun_mac) iconify --imageset $$i $@; done @@ -258,6 +259,7 @@ $(appdir)/%.app/Assets.car: $(xcassets)/%.xcassets $(xcassets)/icons8.xcassets xcrun actool --output-format human-readable-text --notices --warnings --print-contents --output-partial-info-plist $@.plist \ --platform $(sdk) --minimum-deployment-target $(target_ver_ios) --target-device iphone --target-device ipad --app-icon AppIcon \ --compress-pngs --compile $(dir $@) $(realpath $(filter %.xcassets, $^)) > /dev/null + cp $(realpath $(filter %.xcassets, $^)/Icon.icns) $(dir $@)/ test -f $@ || { echo "error: $@ was not created by actool!" && cat $@.plist && exit 1; } $(appdir)/%.app/LaunchScreen.nib: templates/$(platform)/LaunchScreen.xib diff --git a/README.md b/README.md index 9e956c0..41ef371 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,9 @@ Custom URL schemes can also be registered to launch a MacPin App from any other ## Included Apps in the [Release](https://github.com/kfix/MacPin/releases) +### selfhosterings +* [Home Assistant.app](https://my.home-assistant.io) + ### Gooblers * [Google Drive.app](https://drive.google.com) * [Google Photos.app](https://photos.google.com) @@ -38,7 +41,7 @@ Custom URL schemes can also be registered to launch a MacPin App from any other ### MetaVerses * [Facebook.app](https://m.facebook.com/home.php) (mobile version!) -* [Messenger.app](https://www.messenger.com/hangouts) +* [Messenger.app](https://www.messenger.com/) * [WhatsApp.app](https://web.whatsapp.com) ### et cetera @@ -95,7 +98,8 @@ app.on('AppFinishedLaunching', function() { ``` ## Hacking MacPin -Building `main` branch requires [macOS 13 "Ventura" with Xcode 14+](https://developer.apple.com/xcode/system-requirements/). +Building `main` branch requires [macOS 13 "Ventura" with Xcode 14+](https://developer.apple.com/xcode/system-requirements/). +Later versions of macOS can build with the [Command Line Tools](https://developer.apple.com/documentation/xcode/installing-the-command-line-tools#Install-the-Command-Line-Tools-package-in-Terminal). All other branches are obsolete & archived for users locked on older macOS (hardware), but they will recieve no updates. diff --git a/Sources/MacPin/WebView.swift b/Sources/MacPin/WebView.swift index 9ce2708..8575da1 100644 --- a/Sources/MacPin/WebView.swift +++ b/Sources/MacPin/WebView.swift @@ -682,6 +682,11 @@ final class MPWebView: WKWebView, WebViewScriptExports { configuration.processPool = configuration.processPool ?? (MPWebView.self.sharedWebProcessPool)! } + // if makeInsecure: + //configuration.processPool._registerURLSchemeAsSecure("http") + //configuration.processPool._registerURLSchemeAsBypassingContentSecurityPolicy("http") + //configuration.processPool._registerURLSchemeAsBypassingContentSecurityPolicy("https") + self.init(frame: CGRect.zero, configuration: configuration) // This is the real init() // its an ObjC++ ctor which is why we couldn't override its impl to do these defaultings @@ -702,6 +707,7 @@ final class MPWebView: WKWebView, WebViewScriptExports { if let context = context { "http".withCString { http in WKContextRegisterURLSchemeAsBypassingContentSecurityPolicy(context, WKStringCreateWithUTF8CString(http)) // FIXME: makeInsecure() toggle! + WKContextRegisterURLSchemeAsSecure(context, WKStringCreateWithUTF8CString(http)) // FIXME: makeInsecure() toggle! } "https".withCString { https in WKContextRegisterURLSchemeAsBypassingContentSecurityPolicy(context, WKStringCreateWithUTF8CString(https)) diff --git a/eXcode.mk b/eXcode.mk index 524bddf..f75d427 100644 --- a/eXcode.mk +++ b/eXcode.mk @@ -70,16 +70,11 @@ verbose ?= ################### # swift scaffolding ################### -# https://github.com/apple/swift-driver -ifeq (1,$(CLTOOLS)) +ifneq (1,$(XCODE)) sdkpath := /$(shell pkgutil --volume / --only-dirs --regexp --files com.apple.pkg.CLTools.* | grep -m1 -E SDKs/MacOSX\\d+.*.sdk$$) $(info [$(eXcode)] $$(sdkpath) := $(sdkpath)) swiftc := /$(shell pkgutil --volume / --only-dirs --files com.apple.pkg.CLTools_Executables | grep -m1 usr/bin$$)/swiftc -sdk $(sdk) -target $(arch)-$(target_$(platform)) $(verbose) - -# not a thing anymore -#swiftbuildbin := /$(patsubst %-build,%,$(shell pkgutil --volume / --only-files --files com.apple.pkg.CLTools_Executables | grep -m1 bin/swift-build$$)) swiftbuildbin := /usr/bin/swift -### XXX: appears CLTools doesn't ship SPM libraries yet, so Package.swift can't be compiled else sdkpath := $(shell xcrun --show-sdk-path --sdk $(sdk)) swiftc := xcrun -sdk $(sdk) swiftc -target $(arch)-$(target_$(platform)) $(verbose) diff --git a/modules/WebKitPrivates/WKProcessPoolPrivate.h b/modules/WebKitPrivates/WKProcessPoolPrivate.h index e888558..f3ebb0c 100644 --- a/modules/WebKitPrivates/WKProcessPoolPrivate.h +++ b/modules/WebKitPrivates/WKProcessPoolPrivate.h @@ -35,6 +35,11 @@ //- (void)_automationCapabilitiesDidChange WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA); //- (void)_setAutomationSession:(_WKAutomationSession *)automationSession WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA); +- (void)_registerURLSchemeAsCanDisplayOnlyIfCanRequest:(NSString *)scheme WK_API_AVAILABLE(macos(10.14), ios(12.0)); +- (void)_registerURLSchemeAsSecure:(NSString *)scheme WK_API_AVAILABLE(macos(12.0), ios(15.0)); +- (void)_registerURLSchemeAsBypassingContentSecurityPolicy:(NSString *)scheme WK_API_AVAILABLE(macos(12.0), ios(15.0)); +- (void)_setDomainRelaxationForbiddenForURLScheme:(NSString *)scheme WK_API_AVAILABLE(macos(12.0), ios(15.0)); + // Test only. Returns web processes running web pages (does not include web processes running service workers) - (size_t)_webPageContentProcessCount WK_API_AVAILABLE(macos(10.13.4), ios(11.3)); diff --git a/sites/Facebook/app.js b/sites/Facebook/app.js index ebde8b0..f3e3dd2 100644 --- a/sites/Facebook/app.js +++ b/sites/Facebook/app.js @@ -10,9 +10,10 @@ var delegate = {}; // our delegate to receive events from the webview app var fbTab, fb = { url: "https://m.facebook.com/home.php", - preinject: ['unpreloader'], // this prevents buffering every video in a feed. If you have a fast Mac and Internet, comment out this line + useSystemAppearance: true, + //preinject: ['unpreloader'], // this prevents buffering every video in a feed. If you have a fast Mac and Internet, comment out this line //postinject: ['styler'], agent: "Mozilla/5.0 (iPad; CPU OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4" - agent: "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2311.38 Mobile Safari/537.36" //news-feed on Chromedroid is full-width + //agent: "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2311.38 Mobile Safari/537.36" //news-feed on Chromedroid is full-width }; fbTab = $.browser.tabSelected = new $.WebView(fb); $.browser.addShortcut("Facebook Home", fb); @@ -21,9 +22,6 @@ delegate.setAgent = function(agent) { $.browser.tabSelected.userAgent = agent; } $.browser.addShortcut('UA: Android 5 / Chrome 36', ["setAgent", "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.2311.38 Mobile Safari/537.36"]); // FB sets margin-* to be 0 on a bunch of elements (header jewels) for chr36 -let enDarken = require('enDarken.js'); -$.browser.addShortcut('Dark Mode', [], enDarken); - function search(query) { $.browser.tabSelected = fbTab; //fbTab.load_url("https://m.facebook.com/graphsearch/str/" + query + "/keywords_top?ref=content_filter&source=typeahead") @@ -58,7 +56,7 @@ delegate.handleUserInputtedInvalidURL = function(query) { }; delegate.AppFinishedLaunching = function() { - $.app.registerURLScheme('facebook'); + //$.app.registerURLScheme('facebook'); //$.app.registerURLScheme('fb'); // claimed by AddressBookUrlForwarder.app http://apple.stackexchange.com/a/105047 //`open -a AddressBookUrlForwarder.app fb://profile/4` to see the Zuckster in safari ... diff --git a/sites/Google_Calendar/app.js b/sites/Google_Calendar/app.js index 4c15bf8..b971026 100644 --- a/sites/Google_Calendar/app.js +++ b/sites/Google_Calendar/app.js @@ -10,6 +10,7 @@ var delegate = {}; // our delegate to receive events from the webview app var calTab, calendar = { transparent: false, + useSystemAppearance: true, url: "https://calendar.google.com" }; var calendarAlt = Object.assign({}, calendar, {url: "https://calendar.google.com/calendar/b/1"}); @@ -144,6 +145,7 @@ delegate.decideNavigationForURL = function(url, tab) { !addr.startsWith("//www.youtube.com") && // yt vids are usually embedded players !addr.startsWith("//youtube.googleapis.com/embed/") && !addr.startsWith("//www.google.com/a/") && + !addr.startsWith("//ogs.google.com") && !addr.startsWith("//myaccount.google.com") && !addr.startsWith("//www.google.com/tools/feedback/content_frame") && !addr.startsWith("//www.google.com/settings") @@ -174,8 +176,6 @@ delegate.handleDragAndDroppedURLs = function(urls) { } } -let enDarken = require('enDarken.js'); - delegate.AppFinishedLaunching = function() { //$.app.registerURLScheme('gcalendar'); //$.app.registerUTI('dyn.???'); // *.ical @@ -197,7 +197,6 @@ delegate.AppFinishedLaunching = function() { ); } - $.browser.addShortcut('Paint It Black', [], enDarken); }; delegate; //return this to macpin diff --git a/sites/Google_Chat/main.js b/sites/Google_Chat/main.js index e4ed0d2..5697269 100644 --- a/sites/Google_Chat/main.js +++ b/sites/Google_Chat/main.js @@ -8,23 +8,22 @@ let browser = new BrowserWindow(); const chat = { url: "https://chat.google.com", + useSystemAppearance: true }; -let chatTab = new WebView(chat); // start loading right way, its a big Closure app +let chatTab = new WebView(chat); // start loading right way, its a big app function unhideApp(tab) { if (tab) browser.tabSelected = tab; browser.unhideApp(); }; -const enDarken = require('enDarken.js'); - const setAgent = function(agent, tab) { tab.userAgent = agent; }; // looks like a reload has to be done for this to take full effect. app.on("decideNavigationForClickedURL", function(url, tab, mainFrame) { if ( !url.startsWith("https://accounts.google.com") - && !url.startsWith("https://hangouts.google.com") + && !url.startsWith("https://ogs.google.com") && !url.startsWith("https://www.google.com/a/") && !url.startsWith("https://g.co") ) { // open all links externally except those above @@ -57,11 +56,9 @@ app.on('handleClickedNotification', (note) => { app.on('AppWillFinishLaunching', (AppUI) => { browser.addShortcut("Log into Google Account", "https://accounts.google.com/signin"); - browser.addShortcut('Dark Mode', [], enDarken); browser.addShortcut('UA: default', [false], setAgent); AppUI.browserController = browser; // make sure main app menu can get at our shortcuts - enDarken(chatTab); }); diff --git a/sites/Google_Drive/app.js b/sites/Google_Drive/app.js index 576eb4a..067778e 100644 --- a/sites/Google_Drive/app.js +++ b/sites/Google_Drive/app.js @@ -9,7 +9,8 @@ var delegate = {}; // our delegate to receive events from the webview app var driveTab, drive = { - url: "https://drive.google.com" + url: "https://drive.google.com", + useSystemAppearance: true, }; var driveAlt = Object.assign({}, drive, {url: "https://drive.google.com/drive/u/1"}); var sheets = Object.assign({}, drive, {url: "https://docs.google.com/spreadsheets/"}); @@ -142,6 +143,7 @@ delegate.decideNavigationForURL = function(url, tab) { !addr.startsWith("//www.youtube.com") && // yt vids are usually embedded players !addr.startsWith("//youtube.googleapis.com/embed/") && !addr.startsWith("//www.google.com/a/") && + !addr.startsWith("//ogs.google.com") && !addr.startsWith("//myaccount.google.com") && !addr.startsWith("//www.google.com/tools/feedback/content_frame") && !addr.startsWith("//www.google.com/settings") @@ -172,8 +174,6 @@ delegate.handleDragAndDroppedURLs = function(urls) { } } -let enDarken = require('enDarken.js'); - delegate.AppFinishedLaunching = function() { $.app.registerURLScheme('gdrive'); //$.app.registerURLScheme('googledrive'); //iOS @@ -187,7 +187,6 @@ delegate.AppFinishedLaunching = function() { $.browser.addShortcut('Presentations', presentation); $.browser.addShortcut("Add a Google log-in", 'https://accounts.google.com/AddSession'); $.browser.addShortcut('Use next Google log-in', ['gotoNextGoogleAccount']); - $.browser.addShortcut("Install 'Open in Google Drive app' service", `http://github.com/kfix/MacPin/tree/master/extras/${escape('Open in Google Drive app.workflow')}`); $.browser.addShortcut('Enable Redirection to external domains', ['toggleRedirection', true]); $.browser.addShortcut('Disable Redirection (default)', ['toggleRedirection', false]); @@ -201,8 +200,5 @@ delegate.AppFinishedLaunching = function() { } ); } - - $.browser.addShortcut('Paint It Black', [], enDarken); - }; delegate; //return this to macpin diff --git a/sites/Google_Maps/app.js b/sites/Google_Maps/app.js index 14a6a01..72ba88b 100644 --- a/sites/Google_Maps/app.js +++ b/sites/Google_Maps/app.js @@ -6,6 +6,7 @@ var delegate = {}; // our delegate to receive events from the webview app var mapsTab, maps = { url: "https://maps.google.com", + useSystemAppearance: true, allowsMagnification: false // lets gmaps JS handle pinch-zooms }; var mapsAlt = Object.assign({}, maps, {url: "https://www.google.com/maps/?authuser=1"}); @@ -59,6 +60,8 @@ delegate.decideNavigationForURL = function(url, tab) { if (!addr.startsWith("//maps.google.com") && !addr.startsWith("//google.com/maps/") && !addr.startsWith("//accounts.google.com") && + !addr.startsWith("//accounts.youtube.com") && + !addr.startsWith("//ogs.google.com") && !addr.startsWith("//www.google.com/a/") && !addr.startsWith("//places.google.com") && !addr.startsWith("//plus.google.com") && @@ -99,8 +102,6 @@ delegate.handleDragAndDroppedURLs = function(urls) { } } -let enDarken = require('enDarken.js'); - delegate.AppFinishedLaunching = function() { $.app.registerURLScheme('gmaps'); //$.app.registerURLScheme('googlemaps'); //IOS? @@ -113,7 +114,6 @@ delegate.AppFinishedLaunching = function() { $.browser.addShortcut('Google Maps API Team blog', "http://googlegeodevelopers.blogspot.com"); $.browser.addShortcut('Classic gMaps', "http://gokml.net/maps"); $.browser.addShortcut("Install 'Show Address in Google Maps app' service", `http://github.com/kfix/MacPin/tree/master/extras/${escape('Show Address in Google Maps app.workflow')}`); - $.browser.addShortcut('Dark Mode', [], enDarken); // TODO: add "Open in Apple Maps", send it http://maps.apple.com lat & long // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html diff --git a/sites/Google_Voice/main.js b/sites/Google_Voice/main.js index 8249f95..1e4f16f 100644 --- a/sites/Google_Voice/main.js +++ b/sites/Google_Voice/main.js @@ -8,6 +8,7 @@ let browser = new BrowserWindow(); const voice = { url: "https://voice.google.com", + useSystemAppearance: true, postinject: ["automators"] }; let voiceTab = new WebView(voice); // start loading right away, it's a big app @@ -23,12 +24,9 @@ const setAgent = function(agent, tab) { tab.userAgent = agent; }; app.on("decideNavigationForClickedURL", function(url, tab, mainFrame) { if ( !url.startsWith("https://talkgadget.google.com") + && !url.startsWith("https://ogs.google.com") && !url.startsWith("https://accounts.google.com") - && !url.startsWith("https://hangouts.google.com") - && !url.startsWith("https://plus.google.com/hangouts/") && !url.startsWith("https://www.google.com/a/") - && !url.startsWith(meet.url) - && !url.startsWith(allo.url) && !url.startsWith(voice.url) && !url.startsWith("https://g.co") ) { // open all links externally except those above @@ -77,7 +75,7 @@ app.on('handleUserInputtedInvalidURL', function(query, tab) { return false; }); -app.on('launchURL', function(url) { // app.openURL(/[sms|hangouts|tel]:.*/) calls this +app.on('launchURL', function(url) { // app.openURL(/[sms|tel]:.*/) calls this console.log("app.js: launching " + url); var comps = url.split(':'), scheme = comps.shift(), diff --git a/sites/Hangouts/app.js b/sites/Hangouts/app.js deleted file mode 100644 index ecc8b3b..0000000 --- a/sites/Hangouts/app.js +++ /dev/null @@ -1,194 +0,0 @@ -/*eslint-env applescript*/ -/*eslint-env es6*/ -/*eslint eqeqeq:0, quotes:0, space-infix-ops:0, curly:0*/ -"use strict"; - -var hangouts = { - transparent: true, - postinject: ["notifier"], // "convopopper"], - preinject: ["styler"], - subscribeTo: ['unhideApp', 'HangoutsRosterReady', 'SwitchToThisTab'], - style: [ "style" ], - url: "https://hangouts.google.com" -}; -var hangoutsAlt = Object.assign({}, hangouts, {url: "https://plus.google.com/u/1/hangouts"}); -$.browser.addShortcut("Google Hangouts", hangouts); -var hangoutsTab = new $.WebView(hangouts); // start loading right way, its a big Closure app -$.browser.addShortcut("Log into Google Account", "https://accounts.google.com/signin"); -$.browser.addShortcut("Open Hangouts tab using secondary Google account", hangoutsAlt); -$.browser.addShortcut("Install Google Voice & Video plugin", "https://encrypted.google.com/tools/dlpage/hangoutplugin"); -$.browser.addShortcut("Get Contacts.app -> Hangouts.app plugin", "http://github.com/kfix/MacPin/tree/master/extras/AddressBookHangoutsPlugin"); -$.browser.addShortcut("Get OSX service for text-selected numbers", "http://github.com/kfix/MacPin/tree/master/extras/Call%20Phone%20with%20Hangouts.workflow"); -$.browser.addShortcut("Google Voice call history", "https://www.google.com/voice/?pli=1#history") -$.browser.addShortcut("(secondary account) Google Voice call history", "https://www.google.com/voice/b/1?pli=1#history") -//var gaia; // your numeric Google ID - -var delegate = {}; // our delegate to receive events from the webview app - -delegate.DidWindowOpenForURL = function(url, child, parent) { child.subscribeTo("SwitchToThisTab"); } //all popped-up tabs can select themselves - -delegate.decideNavigationForClickedURL = function(url) { - if ( - !url.startsWith("https://talkgadget.google.com") - && !url.startsWith("https://accounts.google.com") - && !url.startsWith("https://hangouts.google.com") - && !url.startsWith("https://plus.google.com/hangouts/") - && !url.startsWith("https://www.google.com/a/") - && !url.startsWith("https://voice.google.com") - && !url.startsWith("https://g.co") - ) { // open all links externally except those above - $.app.openURL(url); - return true; - } - if (url.startsWith("https://www.google.com/url?q=")) { - // stripping obnoxious google redirector - url = decodeURIComponent(url.slice(29)); - $.app.openURL(url); - return true; - } - return false; -}; -delegate.decideNavigationForMIME = function() { return false; }; -delegate.decideWindowOpenForURL = function(url) { - if (url.startsWith("https://plus.google.com/hangouts/_/")) { //G+ hangouts a/v chat - if (useChromeAV) - $.app.openURL(url, "com.google.Chrome"); - else - $.browser.tabSelected = new $.WebView({url: url}); - return true; - } - - /* - if (url.startsWith("//talkgadget.google.com/u/0/talkgadget/_/frame")) { - $.browser.tabSelected = new $.WebView({url: url}); // chat pop-out should change tab to new chat tab, and not change size - return true; //doesn't work because parent webViewConfig is not passed through - } - */ - - return false; -}; - -delegate.handleUserInputtedInvalidURL = function(query) { - // assuming the invalid url is a phone number - // check for all-nums or at-sign - hangoutsTab.evalJS("xssRoster(['inputAddress', '"+query+"']);"); - return true; // tell MacPin to stop validating the URL -}; - -delegate.launchURL = function(url) { // $.app.openURL(/[sms|hangouts|tel]:.*/) calls this - console.log("app.js: launching " + url); - var comps = url.split(':'), - scheme = comps.shift(), - addr = comps.shift().replace(/\//g, ''); // de-slashed - switch (scheme) { - case 'hangouts': - // this could be a gmail address or email address that has been linked to a google account, or the Full Name linked to such addresses - // http://handleopenurl.com/scheme/hangouts - // https://productforums.google.com/forum/#!topic/hangouts/-FgLeX50Jck - $.browser.unhideApp(); //user might have switched apps while waiting for roster to load - $.browser.tabSelected = hangoutsTab; - hangoutsTab.evalJS("xssRoster(['inputAddress', '"+addr+"'], ['checkFirstFoundContact']);"); //calls into AppTab[1]:notifier.js - case 'sms': - $.browser.unhideApp(); //user might have switched apps while waiting for roster to load - $.browser.tabSelected = hangoutsTab; - hangoutsTab.evalJS("xssRoster(['inputAddress', '"+addr+"'], ['sendSMS']);"); //calls into AppTab[1]:notifier.js - break; - case 'tel': - // TODO: interpret commas as 2-sec delays and pounds as pounds - if ($.app.pathExists('/Library/Internet Plug-Ins/googletalkbrowserplugin.plugin')) { - // use NPAPI GoogleVoice & Video (Vidyo) plugin in the WebView - // window.a also seems to have a list of loaded plugins - $.browser.unhideApp(); //user might have switched apps while waiting for roster to load - $.browser.tabSelected = hangoutsTab; - hangoutsTab.evalJS("xssRoster(['inputAddress', '"+addr+"'], ['makeCall']);"); // Hangouts now does in-frame phone calls! - // TODO: use callback to get new chatbox frame name, simulate keypress events over it? - } else if ($.app.doesAppExist("com.google.Chrome")) { - // use Chrome's NaCL+WebRTC Hangouts client for A/V chats ( https://webrtchacks.com/hangout-analysis-philipp-hancke/ ) - $.app.openURL("https://plus.google.com/hangouts/_/?hl=en&hpn="+addr+"&hip="+addr+"&hnc=0", "com.google.Chrome"); - } else { - // no plugin or chrome ... - $.browser.tabSelected = new $.WebView({url: "https://encrypted.google.com/tools/dlpage/hangoutplugin"}); //prompt to install plugin - // so how bout that WebRTC in WebKit??? - // https://blog.mozilla.org/webrtc/firefox-is-now-supported-by-google-hangouts-and-meet/ should we pretend to be FireFox 60? - $.app.openURL("tel:"+addr, "com.apple.facetime"); // maybe they have iPhone w/Handoff, so try call w/ facetime - } - break; - case 'https': - if (!url.startsWith("//accounts.google.com")) { $.browser.tabSelected.load_url(url); break; } - default: - $.app.openURL(url); - } -}; - -delegate.SwitchToThisTab = function(tab, msg) { - if (tab) $.browser.tabSelected = tab; -}; - -delegate.receivedHTML5DesktopNotification = function(tab, note) { - if (tab.gaia) note.tag += '__' + tab.gaia // add your Google ID to the notification tag - console.log(Date() + ' [posted HTML5 notification] ' + note); - $.app.postHTML5Notification(note); - return true; -}; - -delegate.handleClickedNotification = function(note) { - let {title, subtitle, msg, id} = note; - console.log("JS: opening user notification for: "+ [title, subtitle, msg, id]); - //$.browser.tabSelected = hangoutsTab; - //hangoutsTab.evalJS('rosterClickOn("button[cpar='+"'"+id+"'"+']");'); - var src = id.split('__'), - cpar = src.shift(), - gaia = src.shift(); - //var [cpar, gaia] = id.split('__'); //ES6...OSX 10.11 ? - for (var tab of $.browser.tabs) { - if ((tab.cpar == cpar) && (tab.gaia == gaia)) { - // a popped out tab already exists for this conversation - $.browser.tabSelected = tab; - } else if (tab.gaia == gaia) { - $.browser.tabSelected = tab; - hangoutsTab.evalJS('rosterClickOn("button[cpar='+"'"+cpar+"'"+']");'); - } - } - return true; -}; - -delegate.unhideApp = function(tab) { - $.browser.tabSelected = tab; - $.browser.unhideApp(); -}; - -delegate.AppFinishedLaunching = function() { - //$.app.registerURLScheme('sms'); // `open -a Messages.app imessage:18004444444` still works - //$.app.registerURLScheme('tel'); // `open -a Facetime.app tel:18004444444` still works - //$.app.registerURLScheme('hangouts'); - // OSX Yosemite safari recognizes and launches sms and tel links to any associated app - // https://github.com/WebKit/webkit/blob/ce77bdb93dbd24df1af5d44a475fe29b5816f8f9/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm#L691 - // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007899 - $.browser.tabSelected = hangoutsTab; -}; - -//addEventListener('HangoutsRosterReady', function(e){...}, false); ?? -delegate.HangoutsRosterReady = function(tab) { // notifier.js will call this when roster div is created - if ($.launchedWithURL != '') { //app was launched by an opened URL or a clicked notification - probably a [sms|tel]: link - this.launchURL($.launchedWithURL); - $.launchedWithURL = ''; - } -/* - // this is your UID for G+: https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get?userId=me&_h=6& - // GET https://www.googleapis.com/plus/v1/people/me?key={YOUR_API_KEY} - tab.evalJS('myGAIA();', function(res, err) { - if (res != '') { - var gaia = res; - console.log("Logged in as https://plus.google.com/"+gaia); - tab.gaia = gaia; - //Object.defineProperty(tab, 'gaia', {value: gaia, writable: false}); - } else { - console.log(err); - //$.browser.tabSelected = new $.WebView({url: hangouts.url}); // G+ login prompt - } - }); -*/ - $.browser.addShortcut("Test call to MCI ANAC", "tel:18004444444"); -}; - -delegate; //return this to macpin diff --git a/sites/Hangouts/convopopper.js b/sites/Hangouts/convopopper.js deleted file mode 100644 index 7d41f96..0000000 --- a/sites/Hangouts/convopopper.js +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-env browser */ -/*eslint eqeqeq:0, quotes:0, space-infix-ops:0, curly:0*/ - -if ((window.name == 'preld') || ~window.name.indexOf('gtn_')) { //frame-id ^gtn_ this is a chatbox iframe - var btn; - function autoPop() { - // auto-tab all opened chats (via window.open) - if (btn = document.querySelector('button[title="Pop-out"]')) { - console.log("got a pop-out button!"); - console.log(btn); - //btn.click(); - // goog.testing.events.fireClickSequence() - // https://google.github.io/closure-library/api/source/closure/goog/testing/events/events.js.src.html#l165 - // https://github.com/google/closure-library/blob/master/closure/goog/testing/events/events.js#L165 - // https://github.com/google/closure-library/blob/master/closure/goog/events/browserevent.js - // https://developers.google.com/closure/library/docs/introduction#evs - // https://developers.google.com/closure/library/docs/closurebuilder - btn[Object.keys(btn)[0]].$.click[0].proxy(); // btn.closure_lm_54596 ... - } - - //setTimeout(webkit.messageHandlers.SwitchToThisTab.postMessage, 3000, []); - } - - setTimeout(autoPop, 4000); - webkit.messageHandlers.SwitchToThisTab.postMessage([]); -}; diff --git a/sites/Hangouts/icon.png b/sites/Hangouts/icon.png deleted file mode 100644 index 839e9ac..0000000 Binary files a/sites/Hangouts/icon.png and /dev/null differ diff --git a/sites/Hangouts/notifier.js b/sites/Hangouts/notifier.js deleted file mode 100644 index efca1a6..0000000 --- a/sites/Hangouts/notifier.js +++ /dev/null @@ -1,287 +0,0 @@ -function xss_eval(event) { - console.log('origin['+event.origin +'] called @'+window.name+'.postMessage() -> req: '+event.data); - - if ( event.origin != "https://hangouts.google.com" ) return; //only handle messages from main frame - - var calls = event.data.slice(); - for (argv of calls) { - func = argv.shift(); - if ( eval("typeof "+func+" === 'function'") ){ - console.log('@'+window.name+'.xss_eval() -> '+func+'() -> args: ' + argv); - func = eval(func) - //res = func.apply(this, argv); //splat - res = func(...argv); //spread - //event.source is origin's .window, could send result of func there with postMessage() - } - } - -} - -if (window == top) { - window.dispatchEvent(new Event('resize')); //resize the roster per styler.js on cold reloads in fullscreen - /* - delete all the junk nodes in between these - */ - - //function gotoConversations() { document.querySelector('div[data-tooltip="Conversations"]') ;} //need to do a goog.closure.events.CLICK - function getRoster() { return document.getElementById('gtn-roster-iframe-id-b'); } - function xssRoster() { /* ([func1, arg1, arg2], [func2, arg1, arg2])*/ - // make arg[0] == iframe.id ? - getRoster().contentWindow.postMessage(Array.prototype.slice.call(arguments), '*'); // ordered dispatch - //for (var i = 0; i < arguments.length; i++) { // immediate dispatch - // var call = arguments[i]; - // getRoster().contentWindow.postMessage(call, '*'); - //} - } - - function myGAIA(){ return document.querySelector('a[aria-label^=Profile]').getAttribute('href').split('/').pop(); } - - function rosterClickOn(sel) { xssRoster(['clickOn', sel]); } - - //addEventListener("message", xss_eval, false); // intercept new chat window dispositions in the main content pane - -} else { - function evalMain(req) { top.postMessage([req], '*'); } - //addEventListener("message", xss_eval, false); // intercept loooots of data to individual chat iframes - // https://github.com/tdryer/hangups/blob/master/hangups/pblite.py - // https://github.com/tdryer/hangups/blob/master/hangups/schemas.py - // http://protobuf.axo.io/#objc -} - -if (window.name == 'gtn-roster-iframe-id-b') { -//IIFE? - - var roster; - - function clickOn(sel) { if (el = document.querySelector(sel)) el.click(); } - function getTopConversation() { return document.querySelector('button[cpar]'); } //gets 1st convers in roster - // cpar=_ - // SMS forwarded messages have ephermeral GAIA's (persist for length of conversation history?) - // cathartic messages just have cpar= - - function notifyMessages(msgs) { - for (el of msgs) { // el should be a