Skip to content

Commit

Permalink
feat: support safari extension
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangferry committed Sep 9, 2023
1 parent 3095b9f commit 8735032
Show file tree
Hide file tree
Showing 42 changed files with 1,756 additions and 3 deletions.
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![Project Logo](src/assets/img/logo.png)

# SummarAI Chrome Extension
# SummarAI Browser Extension

This browser extension utilizes AI technology to analyze web pages and extract important information.

Expand Down Expand Up @@ -46,6 +46,33 @@ There are two AI modes available for you to choose from:
2. Navigate to the web page you want to summarize and click on the SummerAI icon.
3. The extension will analyze the content of the page and display a summary in the popup.

## Safari

Safari plug-ins are typically used for macOS/iOS systems, you should compile SummarAI.xcodeproj with Xcode.

### macOS

- Check the Allow unsigned extensions option in Safari's developer options.

![](https://cdn.zhangferry.com/Images/202309092301123.png)

### iOS

- Change the developer certificate to yours.

<div style="display: flex;justify-content: space-between;">
<span style="width:40%;display:inline-block">

![长图一 alt](https://cdn.zhangferry.com/Images/WechatIMG553.jpeg)

</span>
<span style="width:40%;display:inline-block">

![图二](https://cdn.zhangferry.com/Images/202309092304234.png)

</span>
</div>

## Support

- For any issues or questions, please contact me.
Expand Down
7 changes: 6 additions & 1 deletion packages/chromium/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -23923,6 +23923,9 @@ https://www.viki.com
Select2._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
var select_default = Select2;

// src/options/ProviderSelect.tsx
var import_classnames23 = __toESM(require_classnames());

// src/utils/utils.ts
var import_webextension_polyfill2 = __toESM(require_browser_polyfill());
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
Expand Down Expand Up @@ -24011,6 +24014,8 @@ https://www.viki.com
console.log("config", config);
console.log("models", models);
}, [config, models]);
const isMobile = window.innerWidth < 768;
const flexClass = isMobile ? "glarity--flex-col" : "glarity--flex-row";
return /* @__PURE__ */ o3(k, { children: /* @__PURE__ */ o3(card_default2, { className: "glarity--card", children: /* @__PURE__ */ o3("div", { className: "glarity--flex glarity--flex-col glarity--gap-3", children: [
/* @__PURE__ */ o3(radio_default2.Group, { value: tab, onChange: (v3) => setTab(v3), children: [
!isSafari && /* @__PURE__ */ o3(k, { children: /* @__PURE__ */ o3(radio_default2, { value: "chatgpt" /* ChatGPT */, children: [
Expand All @@ -24028,7 +24033,7 @@ https://www.viki.com
" ",
/* @__PURE__ */ o3("span", { className: "glarity--font-semibold", children: "charge by usage" })
] }),
/* @__PURE__ */ o3("div", { className: "glarity--flex glarity--flex-row glarity--gap-2 glarity--geist--select", children: [
/* @__PURE__ */ o3("div", { className: (0, import_classnames23.default)("glarity--flex", flexClass, "glarity--gap-2", "glarity--geist--select"), children: [
/* @__PURE__ */ o3(
input_default2,
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"images" : [
{
"filename" : "logo-1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "[email protected]",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions safari/SummarAI/Shared (App)/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "logo-128.png"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions safari/SummarAI/Shared (App)/Base.lproj/Main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

<link rel="stylesheet" href="../Style.css">
<script src="../Script.js" defer></script>
</head>
<body>
<img src="../Icon.png" width="128" height="128" alt="SummarAI Icon">
<p class="platform-ios">You can turn on SummarAI’s Safari extension in Settings.</p>
<p class="platform-mac state-unknown">You can turn on SummarAI’s extension in Safari Extensions preferences.</p>
<p class="platform-mac state-on">SummarAI’s extension is currently on. You can turn it off in Safari Extensions preferences.</p>
<p class="platform-mac state-off">SummarAI’s extension is currently off. You can turn it on in Safari Extensions preferences.</p>
<button class="platform-mac open-preferences">Quit and Open Safari Extensions Preferences…</button>
</body>
</html>
Binary file added safari/SummarAI/Shared (App)/Resources/Icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions safari/SummarAI/Shared (App)/Resources/Script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function show(platform, enabled, useSettingsInsteadOfPreferences) {
document.body.classList.add(`platform-${platform}`);

if (useSettingsInsteadOfPreferences) {
document.getElementsByClassName('platform-mac state-on')[0].innerText = "SummarAI’s extension is currently on. You can turn it off in the Extensions section of Safari Settings.";
document.getElementsByClassName('platform-mac state-off')[0].innerText = "SummarAI’s extension is currently off. You can turn it on in the Extensions section of Safari Settings.";
document.getElementsByClassName('platform-mac state-unknown')[0].innerText = "You can turn on SummarAI’s extension in the Extensions section of Safari Settings.";
document.getElementsByClassName('platform-mac open-preferences')[0].innerText = "Quit and Open Safari Settings…";
}

if (typeof enabled === "boolean") {
document.body.classList.toggle(`state-on`, enabled);
document.body.classList.toggle(`state-off`, !enabled);
} else {
document.body.classList.remove(`state-on`);
document.body.classList.remove(`state-off`);
}
}

function openPreferences() {
webkit.messageHandlers.controller.postMessage("open-preferences");
}

document.querySelector("button.open-preferences").addEventListener("click", openPreferences);
61 changes: 61 additions & 0 deletions safari/SummarAI/Shared (App)/Resources/Style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
* {
-webkit-user-select: none;
-webkit-user-drag: none;
cursor: default;
}

:root {
color-scheme: light dark;

--spacing: 20px;
}

html {
height: 100%;
}

body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;

gap: var(--spacing);
margin: 0 calc(var(--spacing) * 2);
height: 100%;

font: -apple-system-short-body;
text-align: center;
}

body:not(.platform-mac, .platform-ios) :is(.platform-mac, .platform-ios) {
display: none;
}

body.platform-ios .platform-mac {
display: none;
}

body.platform-mac .platform-ios {
display: none;
}

body.platform-ios .platform-mac {
display: none;
}

body:not(.state-on, .state-off) :is(.state-on, .state-off) {
display: none;
}

body.state-on :is(.state-off, .state-unknown) {
display: none;
}

body.state-off :is(.state-on, .state-unknown) {
display: none;
}

button {
font-size: 1em;
}
81 changes: 81 additions & 0 deletions safari/SummarAI/Shared (App)/ViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// ViewController.swift
// Shared (App)
//
// Created by zhangferry on 2023/7/15.
//

import WebKit

#if os(iOS)
import UIKit
typealias PlatformViewController = UIViewController
#elseif os(macOS)
import Cocoa
import SafariServices
typealias PlatformViewController = NSViewController
#endif

let extensionBundleIdentifier = "com.zhangferry.SummarAI.Extension"

class ViewController: PlatformViewController, WKNavigationDelegate, WKScriptMessageHandler {

@IBOutlet var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()

self.webView.navigationDelegate = self

#if os(iOS)
self.webView.scrollView.isScrollEnabled = false
#endif

self.webView.configuration.userContentController.add(self, name: "controller")

self.webView.loadFileURL(Bundle.main.url(forResource: "Main", withExtension: "html")!, allowingReadAccessTo: Bundle.main.resourceURL!)
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
#if os(iOS)
webView.evaluateJavaScript("show('ios')")
#elseif os(macOS)
webView.evaluateJavaScript("show('mac')")

SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionBundleIdentifier) { (state, error) in
guard let state = state, error == nil else {
// Insert code to inform the user that something went wrong.
return
}

DispatchQueue.main.async {
if #available(macOS 13, *) {
webView.evaluateJavaScript("show('mac', \(state.isEnabled), true)")
} else {
webView.evaluateJavaScript("show('mac', \(state.isEnabled), false)")
}
}
}
#endif
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
#if os(macOS)
if (message.body as! String != "open-preferences") {
return;
}

SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionBundleIdentifier) { error in
guard error == nil else {
// Insert code to inform the user that something went wrong.
return
}

DispatchQueue.main.async {
NSApplication.shared.terminate(nil)
}
}
#endif
}

}
Loading

0 comments on commit 8735032

Please sign in to comment.