Skip to content

Commit

Permalink
initial plugin system
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleoflqj committed Jul 30, 2024
1 parent e12b76b commit 42b3c5d
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 83 deletions.
176 changes: 94 additions & 82 deletions assets/po/zh_CN.po

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/config/config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ private func jsonToOption(_ json: JSON, _ type: String) throws -> any Option {
if let appIM = json["AppIM"].string, appIM == "True" {
return try ListOption<AppIMOption>.decode(json: json)
}
if let plugin = json["Plugin"].string, plugin == "True" {
return try ListOption<PluginOption>.decode(json: json)
}
return try ListOption<StringOption>.decode(json: json)
} else if type == "List|Key" {
return try ListOption<KeyOption>.decode(json: json)
Expand Down
2 changes: 2 additions & 0 deletions src/config/optionmodels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ class UserThemeOption: StringOption {}

class CssOption: StringOption {}

class PluginOption: StringOption {}

private func bundleIdentifier(_ appPath: String) -> String {
guard let bundle = Bundle(path: appPath) else {
return ""
Expand Down
7 changes: 7 additions & 0 deletions src/config/optionviews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ struct ExternalOptionView: OptionView {
case "UserDataDir":
mkdirP(rimeLocalDir.localPath())
NSWorkspace.shared.open(rimeLocalDir)
case "PluginDir":
mkdirP(pluginDir.localPath())
NSWorkspace.shared.open(pluginDir)
case "CustomPhrase":
showCustomPhrase = true
case "DictManager":
Expand Down Expand Up @@ -547,6 +550,8 @@ func buildViewImpl(label: String, option: any Option) -> any OptionView {
return CssOptionView(label: label, model: option)
} else if let option = option as? AppIMOption {
return AppIMOptionView(label: label, model: option)
} else if let option = option as? PluginOption {
return PluginOptionView(label: label, model: option)
} else if let option = option as? KeyOption {
return KeyOptionView(label: label, model: option)
} else if let option = option as? StringOption {
Expand All @@ -565,6 +570,8 @@ func buildViewImpl(label: String, option: any Option) -> any OptionView {
return ListOptionView<FontOption>(label: label, model: option)
} else if let option = option as? ListOption<AppIMOption> {
return ListOptionView<AppIMOption>(label: label, model: option)
} else if let option = option as? ListOption<PluginOption> {
return ListOptionView<PluginOption>(label: label, model: option)
} else if let option = option as? ListOption<KeyOption> {
return ListOptionView<KeyOption>(label: label, model: option)
} else if let option = option as? ListOption<StringOption> {
Expand Down
34 changes: 34 additions & 0 deletions src/config/pluginoptionview.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Logging
import SwiftUI

struct PluginOptionView: OptionView {
let label: String
let overrideLabel: String? = nil
@ObservedObject var model: PluginOption
@State private var availablePlugins = [String]()

var body: some View {
Picker("", selection: $model.value) {
ForEach(availablePlugins, id: \.self) { plugin in
Text(plugin)
}
}.onAppear {
for fileName in getFileNamesWithExtension(pluginDir.localPath()) {
let url = pluginDir.appendingPathComponent(fileName)
if !url.isDirectory {
continue
}
let packageJsonURL = url.appendingPathComponent("package.json")
if let json = readJSON(packageJsonURL) {
if json["license"].stringValue.hasPrefix("GPL-3.0") {
availablePlugins.append(fileName)
} else {
FCITX_WARN("Rejecting plugin \(fileName) which is not GPLv3")
}
} else {
FCITX_WARN("Invalid package.json for plugin \(fileName)")
}
}
}
}
}
1 change: 1 addition & 0 deletions src/config/util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ let cacheDir = libraryDir.appendingPathComponent("cache")
let configDir = homeDir.appendingPathComponent(".config/fcitx5")
let localDir = homeDir.appendingPathComponent(".local/share/fcitx5")
let wwwDir = localDir.appendingPathComponent("www")
let pluginDir = wwwDir.appendingPathComponent("plugin")
let imLocalDir = localDir.appendingPathComponent("inputmethod")
let pinyinLocalDir = localDir.appendingPathComponent("pinyin")
let tableLocalDir = localDir.appendingPathComponent("table")
Expand Down
4 changes: 4 additions & 0 deletions webpanel/webpanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,13 @@ void WebPanel::updateConfig() {
window_->set_style(style.c_str());
if (auto web = dynamic_cast<candidate_window::WebviewCandidateWindow *>(
window_.get())) {
web->unload_plugins();
using namespace candidate_window;
uint64_t apis = (config_.advanced->unsafeAPI->curl.value() ? kCurl : 0);
web->set_api(apis);
if (*config_.advanced->pluginNotice) {
web->load_plugins({*config_.advanced->plugins});
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions webpanel/webpanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ struct CssAnnotation {
}
};

struct PluginAnnotation {
bool skipDescription() { return false; }
bool skipSave() { return false; }
void dumpDescription(RawConfig &config) {
config.setValueByPath("Plugin", "True");
}
};

FCITX_CONFIGURATION(
BasicConfig,
Option<bool> followCursor{this, "FollowCursor", _("Follow cursor"), false};
Expand Down Expand Up @@ -287,6 +295,12 @@ FCITX_CONFIGURATION(
OptionWithAnnotation<std::string, CssAnnotation> userCss{
this, "UserCss", _("User CSS"), {}};
Option<KeyList> copyHtml{this, "CopyHtml", _("Copy HTML"), {}};
ExternalOption pluginDir{this, "PluginDir", _("Plugin dir"), ""};
Option<bool> pluginNotice{this, "PluginNotice",
_("I know there may be risks for using plugins"),
false};
OptionWithAnnotation<std::vector<std::string>, PluginAnnotation> plugins{
this, "Plugins", _("Plugins"), {}};
Option<UnsafeAPI> unsafeAPI{this, "UnsafeAPI",
_("Dangerous API for JavaScript plugins")};);

Expand Down

0 comments on commit 42b3c5d

Please sign in to comment.