mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
implement 'current article' property of the application
Also, fix the unique-id based accessors (the four byte code for id was wrong in the sdef) Add valueIn<Key>WithUniqueID accessors Add a few protocols and protocol implementations for the AppDelegate and MainWindowControllor so as to expose needed functionality for scriptability
This commit is contained in:
@@ -54,12 +54,29 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
||||
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInFeedsWithUniqueID:)
|
||||
func valueInFeeds(withUniqueID id:String) -> ScriptableFeed? {
|
||||
let feeds = account.children.compactMap { $0 as? Feed }
|
||||
guard let feed = feeds.first(where:{$0.feedID == id}) else { return nil }
|
||||
return ScriptableFeed(feed, container:self)
|
||||
}
|
||||
|
||||
|
||||
@objc(folders)
|
||||
var folders:NSArray {
|
||||
let folders = account.children.compactMap { $0 as? Folder }
|
||||
return folders.map { ScriptableFolder($0, container:self) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInFoldersWithUniqueID:)
|
||||
func valueInFolders(withUniqueID id:NSNumber) -> ScriptableFolder? {
|
||||
let folderId = id.intValue
|
||||
let folders = account.children.compactMap { $0 as? Folder }
|
||||
guard let folder = folders.first(where:{$0.folderID == folderId}) else { return nil }
|
||||
return ScriptableFolder(folder, container:self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: --- Scriptable properties ---
|
||||
|
||||
@objc(contents)
|
||||
|
||||
28
Evergreen/Scriptability/AppDelegate+Scriptability.swift
Normal file
28
Evergreen/Scriptability/AppDelegate+Scriptability.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// AppDelegate+Scriptability.swift
|
||||
// Evergreen
|
||||
//
|
||||
// Created by Olof Hellman on 2/7/18.
|
||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
Note: strictly, the AppDelegate doesn't appear as part of the scripting model,
|
||||
so this file is rather unlike the other Object+Scriptability.swift files.
|
||||
However, the AppDelegate object is the de facto scripting accessor for some
|
||||
application elements and properties. For, example, the main window is accessed
|
||||
via the AppDelegate's MainWindowController, and the main window itself has
|
||||
selected feeds, selected articles and a current article. This file supplies the glue to access
|
||||
these scriptable objects, while being completely separate from the core AppDelegate code,
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Data
|
||||
|
||||
protocol ScriptingAppDelegate {
|
||||
var scriptingCurrentArticle: Article? {get}
|
||||
var scriptingSelectedArticles: [Article] {get}
|
||||
var scriptingMainWindowController:ScriptingMainWindowController? {get}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,11 +85,19 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||
return self.feed.OPMLString(indentLevel:0)
|
||||
}
|
||||
|
||||
// MARK: --- scriptable elements ---
|
||||
|
||||
@objc(authors)
|
||||
var authors:NSArray {
|
||||
let feedAuthors = feed.authors ?? []
|
||||
return feedAuthors.map { ScriptableAuthor($0, container:self) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInAuthorsWithUniqueID:)
|
||||
func valueInAuthors(withUniqueID id:String) -> ScriptableAuthor? {
|
||||
guard let author = feed.authors?.first(where:{$0.authorID == id}) else { return nil }
|
||||
return ScriptableAuthor(author, container:self)
|
||||
}
|
||||
|
||||
@objc(articles)
|
||||
var articles:NSArray {
|
||||
@@ -100,5 +108,12 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
|
||||
})
|
||||
return sortedArticles.map { ScriptableArticle($0, container:self) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInArticlesWithUniqueID:)
|
||||
func valueInArticles(withUniqueID id:String) -> ScriptableArticle? {
|
||||
let articles = feed.fetchArticles()
|
||||
guard let article = articles.first(where:{$0.uniqueID == id}) else { return nil }
|
||||
return ScriptableArticle(article, container:self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// MainWindowController+Scriptability.swift
|
||||
// Evergreen
|
||||
//
|
||||
// Created by Olof Hellman on 2/7/18.
|
||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Data
|
||||
|
||||
protocol ScriptingMainWindowController {
|
||||
var scriptingCurrentArticle: Article? { get }
|
||||
var scriptingSelectedArticles: [Article] { get }
|
||||
}
|
||||
|
||||
@@ -20,27 +20,74 @@ extension NSApplication : ScriptingObjectContainer {
|
||||
return "application"
|
||||
}
|
||||
|
||||
@objc(currentArticle)
|
||||
func currentArticle() -> ScriptableArticle? {
|
||||
var scriptableArticle: ScriptableArticle?
|
||||
if let currentArticle = appDelegate.scriptingCurrentArticle {
|
||||
if let feed = currentArticle.feed {
|
||||
let scriptableFeed = ScriptableFeed(feed, container:self)
|
||||
scriptableArticle = ScriptableArticle(currentArticle, container:scriptableFeed)
|
||||
}
|
||||
}
|
||||
return scriptableArticle
|
||||
}
|
||||
|
||||
@objc(selectedArticles)
|
||||
func selectedArticles() -> NSArray {
|
||||
let articles = appDelegate.scriptingSelectedArticles
|
||||
let scriptableArticles:[ScriptableArticle] = articles.compactMap { article in
|
||||
if let feed = article.feed {
|
||||
let scriptableFeed = ScriptableFeed(feed, container:self)
|
||||
return ScriptableArticle(article, container:scriptableFeed)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return scriptableArticles as NSArray
|
||||
}
|
||||
|
||||
// MARK: --- scriptable elements ---
|
||||
|
||||
@objc(accounts)
|
||||
func accounts() -> NSArray {
|
||||
let accounts = AccountManager.shared.accounts
|
||||
return accounts.map { ScriptableAccount($0) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInAccountsWithUniqueID:)
|
||||
func valueInAccounts(withUniqueID id:String) -> ScriptableAccount? {
|
||||
let accounts = AccountManager.shared.accounts
|
||||
guard let account = accounts.first(where:{$0.accountID == id}) else { return nil }
|
||||
return ScriptableAccount(account)
|
||||
}
|
||||
|
||||
/*
|
||||
accessing feeds from the application object skips the 'account' containment hierarchy
|
||||
this allows a script like 'articles of feed "The Shape of Everything"' as a shorthand
|
||||
for 'articles of feed "The Shape of Everything" of account "On My Mac"'
|
||||
*/
|
||||
@objc(feeds)
|
||||
func feeds() -> NSArray {
|
||||
*/
|
||||
|
||||
func allFeeds() -> [Feed] {
|
||||
let accounts = AccountManager.shared.accounts
|
||||
let emptyFeeds:[Feed] = []
|
||||
let feeds = accounts.reduce(emptyFeeds) { (result, nthAccount) -> [Feed] in
|
||||
return accounts.reduce(emptyFeeds) { (result, nthAccount) -> [Feed] in
|
||||
let accountFeeds = nthAccount.children.compactMap { $0 as? Feed }
|
||||
return result + accountFeeds
|
||||
}
|
||||
}
|
||||
|
||||
@objc(feeds)
|
||||
func feeds() -> NSArray {
|
||||
let feeds = self.allFeeds()
|
||||
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
|
||||
}
|
||||
|
||||
@objc(valueInFeedsWithUniqueID:)
|
||||
func valueInFeeds(withUniqueID id:String) -> ScriptableFeed? {
|
||||
let feeds = self.allFeeds()
|
||||
guard let feed = feeds.first(where:{$0.feedID == id}) else { return nil }
|
||||
return ScriptableFeed(feed, container:self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user