Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[@lexical/devtools] Feature: Added full Safari support #6105

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
**/dist/**
**/build/**
**/npm/**
**/.output/**
**/.browser-profiles/**
**/__tests__/integration/fixtures/**
packages/**/.wxt/**
packages/playwright
Expand Down
76 changes: 38 additions & 38 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions packages/lexical-devtools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

This is the source code for the Lexical DevTools browser extension.

[link-edge]: https://microsoftedge.microsoft.com/addons/detail/lexical-developer-tools/pclbkaofdgafcfhlnimcdhhkkhcabpcb 'Version published on Edge Add-ons Store'
[link-firefox]: https://addons.mozilla.org/en-US/firefox/addon/lexical-developer-tools/ 'Version published on Mozilla Add-ons'

[<img src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/74.1.0/edge/edge.svg" width="48" alt="Chrome" valign="middle">][link-edge] [<img valign="middle" src="https://img.shields.io/badge/dynamic/json?label=%20&query=%24.version&url=https%3A%2F%2Fmicrosoftedge.microsoft.com%2Faddons%2Fgetproductdetailsbycrxid%2Fpclbkaofdgafcfhlnimcdhhkkhcabpcb">][link-edge]

[<img src="https://cdnjs.cloudflare.com/ajax/libs/browser-logos/74.1.0/firefox/firefox.svg" width="48" alt="Firefox" valign="middle">][link-firefox] [<img valign="middle" src="https://img.shields.io/amo/v/lexical-developer-tools.svg?label=%20">][link-firefox]

## Local development

Lexical DevTools extension uses [WXT](https://wxt.dev/) framework to simplify development. Please refer to [WXT Development Guide](https://wxt.dev/guide/development.html) for comprehensive documentation.
Expand All @@ -18,6 +25,27 @@ $ npm run dev
- WXT Framework debugging: `DEBUG_WXT=1 npm run dev`
- If you detach the Dev Tools in a separate window, and press `Cmd+Option+I` while Dev Tools window is focused, you will invoke the Dev Tools for the Dev Tools window.

**Safari:**

To develop and run Safari version of the extension you (obviously) need a Mac and Xcode installed. Safari on the contrary to other browsers doesn't accept web extensions as a zip archive but rather requires you to [wrap it in native code (Swift) wrapper](https://developer.apple.com/documentation/safariservices/safari_web_extensions/converting_a_web_extension_for_safari/). Fortunately this process is mostly automated here.

```bash
# Install Xcode

# Environment setup
sudo xcode-select -s /Applications/Xcode.app
xcodebuild --install
sudo xcodebuild -license
xcodebuild -runFirstLaunch

# Normal operation
npm run dev:safari

# Build & upload to Apple Connect
BUILD_VERSION=0 npm run safari:archive
PASSWORD="XXX" npm run safari:upload
```

## Design

This extension follows typical [Browser DevTools architecture](https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools) that includes sereral independent contexts that communicate via events or extension APIs.
Expand Down
11 changes: 7 additions & 4 deletions packages/lexical-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
"dev": "wxt",
"dev:firefox": "wxt -b firefox",
"dev:edge": "wxt -b edge",
"dev:safari": "xcrun safari-web-extension-converter --macos-only --no-prompt .output/safari-mv2",
"dev:safari": "npm run build:safari -- --mode development && xcodebuild -configuration Debug -scheme Lexical\\ Developer\\ Tools -project ./safari-xcode//Lexical\\ Developer\\ Tools/Lexical\\ Developer\\ Tools.xcodeproj && echo \"Open Safari, allow unsigned extensions in developer settings, enable extension in extensions manager (if needed)\"",
"safari:convert": "xcrun safari-web-extension-converter --app-name 'Lexical Developer Tools' --project-location ./safari-xcode --macos-only --no-prompt --force --no-open .output/safari-mv2",
"safari:archive": "npm run build:safari && node safari-xcode/versioning.mjs && xcodebuild -destination 'generic/platform=macOS' -configuration Release -scheme Lexical\\ Developer\\ Tools -project ./safari-xcode/Lexical\\ Developer\\ Tools/Lexical\\ Developer\\ Tools.xcodeproj clean build CONFIGURATION_BUILD_DIR=./dist/ && xcrun productbuild --sign=\"3rd Party Mac Developer Installer: EPAM SISTEMZ, IOOO (K36CA7QL4T\" --component=./safari-xcode/Lexical\\ Developer\\ Tools/dist/Lexical\\ Developer\\ Tools.app /Applications ./safari-xcode/Lexical\\ Developer\\ Tools/dist/Lexical\\ Developer\\ Tools.pkg",
"safari:upload": "VERSION=\"$(node safari-xcode/versioning.mjs)\" && xcrun altool --upload-package ./safari-xcode/Lexical\\ Developer\\ Tools/dist/Lexical\\ Developer\\ Tools.pkg --type osx -u [email protected] --password $PASSWORD --bundle-id com.epam.lexical.developerTools --apple-id 6502753400 --bundle-version $VERSION --bundle-short-version-string $VERSION",
"build": "npm-run-all build:chrome build:firefox build:edge build:safari",
"build:chrome": "wxt build -b chrome",
"build:firefox": "wxt build -b firefox",
Expand All @@ -27,9 +30,9 @@
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@webext-pegasus/rpc": "^0.0.4",
"@webext-pegasus/store-zustand": "^0.0.4",
"@webext-pegasus/transport": "^0.0.4",
"@webext-pegasus/rpc": "^0.2.0",
"@webext-pegasus/store-zustand": "^0.2.0",
"@webext-pegasus/transport": "^0.2.0",
"framer-motion": "^11.1.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
8 changes: 8 additions & 0 deletions packages/lexical-devtools/safari-xcode/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
xcuserdata/
*.xcworkspace
build/
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
Lexical\ Developer\ Tools/VersioningConfig.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Config.xcconfig
// Lexical Developer Tools
//
// Created by Vladlen Fedosov on 5/21/24.
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

VERSION=0.0.0

// This file is generated during npm run safari:archive
#include? "VersioningConfig.xcconfig"
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.Safari.web-extension</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).SafariWebExtensionHandler</string>
</dict>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// SafariWebExtensionHandler.swift
// Lexical Developer Tools Extension
//
// Created by Vladlen Fedosov on 5/14/24.
//

import SafariServices
import os.log

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {

func beginRequest(with context: NSExtensionContext) {
let request = context.inputItems.first as? NSExtensionItem

let profile: UUID?
if #available(iOS 17.0, macOS 14.0, *) {
profile = request?.userInfo?[SFExtensionProfileKey] as? UUID
} else {
profile = request?.userInfo?["profile"] as? UUID
}

let message: Any?
if #available(iOS 17.0, macOS 14.0, *) {
message = request?.userInfo?[SFExtensionMessageKey]
} else {
message = request?.userInfo?["message"]
}

os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@ (profile: %@)", String(describing: message), profile?.uuidString ?? "none")

let response = NSExtensionItem()
response.userInfo = [ SFExtensionMessageKey: [ "echo": message ] ]

context.completeRequest(returningItems: [ response ], completionHandler: nil)
}

}
Loading
Loading