ServiceMenu // Filter some services if readings are unavailable.
This commit is contained in:
parent
9411686d03
commit
0107e7cd78
|
@ -69,6 +69,8 @@ public extension AppDelegate {
|
|||
|
||||
SpeechSputnik.shared.refreshStatus() // 根據現狀條件決定是否初期化語音引擎。
|
||||
|
||||
CandidateTextService.enableFinalSanityCheck()
|
||||
|
||||
// 一旦發現與使用者半衰模組的觀察行為有關的崩潰標記被開啟:
|
||||
// 如果有開啟 Debug 模式的話,就將既有的半衰記憶資料檔案更名+打上當時的時間戳。
|
||||
// 如果沒有開啟 Debug 模式的話,則將半衰記憶資料直接清空。
|
||||
|
|
|
@ -12,6 +12,28 @@ import Shared
|
|||
import Tekkon
|
||||
|
||||
public extension CandidateTextService {
|
||||
// MARK: - Final Sanity Check Implementation.
|
||||
|
||||
static func enableFinalSanityCheck() {
|
||||
finalSanityCheck = finalSanityCheckImplemented
|
||||
}
|
||||
|
||||
private static func finalSanityCheckImplemented(_ target: CandidateTextService) -> Bool {
|
||||
switch target.value {
|
||||
case .url: return true
|
||||
case let .selector(strSelector):
|
||||
guard target.candidateText != "%s" else { return true } // 防止誤傷到編輯器。
|
||||
switch strSelector {
|
||||
case "copyUnicodeMetadata:": return true
|
||||
case _ where strSelector.hasPrefix("copyRuby"),
|
||||
_ where strSelector.hasPrefix("copyBraille"),
|
||||
_ where strSelector.hasPrefix("copyInline"):
|
||||
return !target.reading.joined().isEmpty // 以便應對 [""] 的情況。
|
||||
default: return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Selector Methods, CandidatePairServicable, and the Coordinator.
|
||||
|
||||
var responseFromSelector: String? {
|
||||
|
|
|
@ -24,6 +24,21 @@ class CandidateServiceCoordinatorTests: XCTestCase {
|
|||
#"Braille 2018: %s"# + "\t" + #"@SEL:copyBraille2018:"#,
|
||||
]
|
||||
|
||||
func testSelector_FinalSanityCheck() throws {
|
||||
var stacked = Self.testDataMap.parseIntoCandidateTextServiceStack(
|
||||
candidate: "胡桃", reading: [] // 故意使用空 Reading
|
||||
)
|
||||
let count1 = stacked.count
|
||||
print("Current Count before Sanity Check ON: \(stacked.count)")
|
||||
CandidateTextService.enableFinalSanityCheck()
|
||||
stacked = Self.testDataMap.parseIntoCandidateTextServiceStack(
|
||||
candidate: "胡桃", reading: [] // 故意使用空 Reading
|
||||
)
|
||||
let count2 = stacked.count
|
||||
print("Current Count after Sanity Check ON: \(stacked.count)")
|
||||
XCTAssertGreaterThan(count1, count2)
|
||||
}
|
||||
|
||||
func testSelector_UnicodeMetadata() throws {
|
||||
let stacked = Self.testDataMap.parseIntoCandidateTextServiceStack(
|
||||
candidate: "胡桃", reading: ["ㄏㄨˊ", "ㄊㄠˊ"]
|
||||
|
|
|
@ -26,6 +26,8 @@ public struct CandidateTextService: Codable {
|
|||
public let value: ServiceValue
|
||||
public let candidateText: String
|
||||
|
||||
public static var finalSanityCheck: ((CandidateTextService) -> Bool)?
|
||||
|
||||
public init?(key: String, definedValue: String, param: String = #"%s"#, reading: [String] = []) {
|
||||
guard !key.isEmpty, !definedValue.isEmpty, definedValue.first != "#" else { return nil }
|
||||
candidateText = param
|
||||
|
@ -62,6 +64,8 @@ public struct CandidateTextService: Codable {
|
|||
}
|
||||
guard let finalServiceValue = finalServiceValue else { return nil }
|
||||
value = finalServiceValue
|
||||
let finalSanityCheckResult = Self.finalSanityCheck?(self) ?? true
|
||||
if !finalSanityCheckResult { return nil }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue