mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-22 16:37:31 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
529
mobile/ios/Storage/Bookmarks/Bookmarks.swift
Normal file
529
mobile/ios/Storage/Bookmarks/Bookmarks.swift
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Shared
|
||||
import Deferred
|
||||
import SwiftyJSON
|
||||
|
||||
private let log = Logger.syncLogger
|
||||
|
||||
public protocol SearchableBookmarks: class {
|
||||
func bookmarksByURL(_ url: URL) -> Deferred<Maybe<Cursor<BookmarkItem>>>
|
||||
}
|
||||
|
||||
public protocol SyncableBookmarks: class, ResettableSyncStorage, AccountRemovalDelegate {
|
||||
// TODO
|
||||
func isUnchanged() -> Deferred<Maybe<Bool>>
|
||||
func getLocalBookmarksModifications(limit: Int) -> Deferred<Maybe<(deletions: [GUID], additions: [BookmarkMirrorItem])>>
|
||||
func getLocalDeletions() -> Deferred<Maybe<[(GUID, Timestamp)]>>
|
||||
func treesForEdges() -> Deferred<Maybe<(local: BookmarkTree, buffer: BookmarkTree)>>
|
||||
func treeForMirror() -> Deferred<Maybe<BookmarkTree>>
|
||||
func applyLocalOverrideCompletionOp(_ op: LocalOverrideCompletionOp, itemSources: ItemSources) -> Success
|
||||
func applyBufferUpdatedCompletionOp(_ op: BufferUpdatedCompletionOp) -> Success
|
||||
}
|
||||
|
||||
public let NotificationBookmarkBufferValidated = Notification.Name("NotificationBookmarkBufferValidated")
|
||||
|
||||
public protocol BookmarkBufferStorage: class {
|
||||
func isEmpty() -> Deferred<Maybe<Bool>>
|
||||
func applyRecords(_ records: [BookmarkMirrorItem]) -> Success
|
||||
func doneApplyingRecordsAfterDownload() -> Success
|
||||
|
||||
func validate() -> Success
|
||||
func getBufferedDeletions() -> Deferred<Maybe<[(GUID, Timestamp)]>>
|
||||
func applyBufferCompletionOp(_ op: BufferCompletionOp, itemSources: ItemSources) -> Success
|
||||
|
||||
// Only use for diagnostics.
|
||||
func synchronousBufferCount() -> Int?
|
||||
func getUpstreamRecordCount() -> Deferred<Int?>
|
||||
}
|
||||
|
||||
public protocol MirrorItemSource: class {
|
||||
func getMirrorItemWithGUID(_ guid: GUID) -> Deferred<Maybe<BookmarkMirrorItem>>
|
||||
func getMirrorItemsWithGUIDs<T: Collection>(_ guids: T) -> Deferred<Maybe<[GUID: BookmarkMirrorItem]>> where T.Iterator.Element == GUID
|
||||
func prefetchMirrorItemsWithGUIDs<T: Collection>(_ guids: T) -> Success where T.Iterator.Element == GUID
|
||||
}
|
||||
|
||||
public protocol BufferItemSource: class {
|
||||
func getBufferItemWithGUID(_ guid: GUID) -> Deferred<Maybe<BookmarkMirrorItem>>
|
||||
func getBufferItemsWithGUIDs<T: Collection>(_ guids: T) -> Deferred<Maybe<[GUID: BookmarkMirrorItem]>> where T.Iterator.Element == GUID
|
||||
func getBufferChildrenGUIDsForParent(_ guid: GUID) -> Deferred<Maybe<[GUID]>>
|
||||
func prefetchBufferItemsWithGUIDs<T: Collection>(_ guids: T) -> Success where T.Iterator.Element == GUID
|
||||
}
|
||||
|
||||
public protocol LocalItemSource: class {
|
||||
func getLocalItemWithGUID(_ guid: GUID) -> Deferred<Maybe<BookmarkMirrorItem>>
|
||||
func getLocalItemsWithGUIDs<T: Collection>(_ guids: T) -> Deferred<Maybe<[GUID: BookmarkMirrorItem]>> where T.Iterator.Element == GUID
|
||||
func prefetchLocalItemsWithGUIDs<T: Collection>(_ guids: T) -> Success where T.Iterator.Element == GUID
|
||||
}
|
||||
|
||||
open class ItemSources {
|
||||
open let local: LocalItemSource
|
||||
open let mirror: MirrorItemSource
|
||||
open let buffer: BufferItemSource
|
||||
|
||||
public init(local: LocalItemSource, mirror: MirrorItemSource, buffer: BufferItemSource) {
|
||||
self.local = local
|
||||
self.mirror = mirror
|
||||
self.buffer = buffer
|
||||
}
|
||||
|
||||
open func prefetchWithGUIDs<T: Collection>(_ guids: T) -> Success where T.Iterator.Element == GUID {
|
||||
return self.local.prefetchLocalItemsWithGUIDs(guids)
|
||||
>>> { self.mirror.prefetchMirrorItemsWithGUIDs(guids) }
|
||||
>>> { self.buffer.prefetchBufferItemsWithGUIDs(guids) }
|
||||
}
|
||||
}
|
||||
|
||||
public struct BookmarkRoots {
|
||||
// These match Places on desktop.
|
||||
public static let RootGUID = "root________"
|
||||
public static let MobileFolderGUID = "mobile______"
|
||||
public static let MenuFolderGUID = "menu________"
|
||||
public static let ToolbarFolderGUID = "toolbar_____"
|
||||
public static let UnfiledFolderGUID = "unfiled_____"
|
||||
|
||||
public static let FakeDesktopFolderGUID = "desktop_____" // Pseudo. Never mentioned in a real record.
|
||||
|
||||
// This is the order we use.
|
||||
public static let RootChildren: [GUID] = [
|
||||
BookmarkRoots.MenuFolderGUID,
|
||||
BookmarkRoots.ToolbarFolderGUID,
|
||||
BookmarkRoots.UnfiledFolderGUID,
|
||||
BookmarkRoots.MobileFolderGUID,
|
||||
]
|
||||
|
||||
public static let DesktopRoots: [GUID] = [
|
||||
BookmarkRoots.MenuFolderGUID,
|
||||
BookmarkRoots.ToolbarFolderGUID,
|
||||
BookmarkRoots.UnfiledFolderGUID,
|
||||
]
|
||||
|
||||
public static let Real = Set<GUID>([
|
||||
BookmarkRoots.RootGUID,
|
||||
BookmarkRoots.MobileFolderGUID,
|
||||
BookmarkRoots.MenuFolderGUID,
|
||||
BookmarkRoots.ToolbarFolderGUID,
|
||||
BookmarkRoots.UnfiledFolderGUID,
|
||||
])
|
||||
|
||||
public static let All = Set<GUID>([
|
||||
BookmarkRoots.RootGUID,
|
||||
BookmarkRoots.MobileFolderGUID,
|
||||
BookmarkRoots.MenuFolderGUID,
|
||||
BookmarkRoots.ToolbarFolderGUID,
|
||||
BookmarkRoots.UnfiledFolderGUID,
|
||||
BookmarkRoots.FakeDesktopFolderGUID,
|
||||
])
|
||||
|
||||
/**
|
||||
* Sync records are a horrible mess of Places-native GUIDs and Sync-native IDs.
|
||||
* For example:
|
||||
* {"id":"places",
|
||||
* "type":"folder",
|
||||
* "title":"",
|
||||
* "description":null,
|
||||
* "children":["menu________","toolbar_____",
|
||||
* "tags________","unfiled_____",
|
||||
* "jKnyPDrBQSDg","T6XK5oJMU8ih"],
|
||||
* "parentid":"2hYxKgBwvkEH"}"
|
||||
*
|
||||
* We thus normalize on the extended Places IDs (with underscores) for
|
||||
* local storage, and translate to the Sync IDs when creating an outbound
|
||||
* record.
|
||||
* We translate the record's ID and also its parent. Evidence suggests that
|
||||
* we don't need to translate children IDs.
|
||||
*
|
||||
* TODO: We don't create outbound records yet, so that's why there's no
|
||||
* translation in that direction yet!
|
||||
*/
|
||||
public static func translateIncomingRootGUID(_ guid: GUID) -> GUID {
|
||||
return [
|
||||
"places": RootGUID,
|
||||
"root": RootGUID,
|
||||
"mobile": MobileFolderGUID,
|
||||
"menu": MenuFolderGUID,
|
||||
"toolbar": ToolbarFolderGUID,
|
||||
"unfiled": UnfiledFolderGUID
|
||||
][guid] ?? guid
|
||||
}
|
||||
|
||||
public static func translateOutgoingRootGUID(_ guid: GUID) -> GUID {
|
||||
return [
|
||||
RootGUID: "places",
|
||||
MobileFolderGUID: "mobile",
|
||||
MenuFolderGUID: "menu",
|
||||
ToolbarFolderGUID: "toolbar",
|
||||
UnfiledFolderGUID: "unfiled"
|
||||
][guid] ?? guid
|
||||
}
|
||||
|
||||
/*
|
||||
public static let TagsFolderGUID = "tags________"
|
||||
public static let PinnedFolderGUID = "pinned______"
|
||||
*/
|
||||
|
||||
static let RootID = 0
|
||||
static let MobileID = 1
|
||||
static let MenuID = 2
|
||||
static let ToolbarID = 3
|
||||
static let UnfiledID = 4
|
||||
}
|
||||
|
||||
/**
|
||||
* This partly matches Places's nsINavBookmarksService, just for sanity.
|
||||
*
|
||||
* It is further extended to support the types that exist in Sync, so we can use
|
||||
* this to store mirrored rows.
|
||||
*
|
||||
* These are only used at the DB layer.
|
||||
*/
|
||||
public enum BookmarkNodeType: Int {
|
||||
case bookmark = 1
|
||||
case folder = 2
|
||||
case separator = 3
|
||||
case dynamicContainer = 4
|
||||
|
||||
case livemark = 5
|
||||
case query = 6
|
||||
|
||||
// No microsummary: those turn into bookmarks.
|
||||
}
|
||||
|
||||
public func == (lhs: BookmarkMirrorItem, rhs: BookmarkMirrorItem) -> Bool {
|
||||
if lhs.type != rhs.type ||
|
||||
lhs.guid != rhs.guid ||
|
||||
lhs.dateAdded != rhs.dateAdded ||
|
||||
lhs.serverModified != rhs.serverModified ||
|
||||
lhs.isDeleted != rhs.isDeleted ||
|
||||
lhs.hasDupe != rhs.hasDupe ||
|
||||
lhs.pos != rhs.pos ||
|
||||
lhs.faviconID != rhs.faviconID ||
|
||||
lhs.localModified != rhs.localModified ||
|
||||
lhs.parentID != rhs.parentID ||
|
||||
lhs.parentName != rhs.parentName ||
|
||||
lhs.feedURI != rhs.feedURI ||
|
||||
lhs.siteURI != rhs.siteURI ||
|
||||
lhs.title != rhs.title ||
|
||||
lhs.description != rhs.description ||
|
||||
lhs.bookmarkURI != rhs.bookmarkURI ||
|
||||
lhs.tags != rhs.tags ||
|
||||
lhs.keyword != rhs.keyword ||
|
||||
lhs.folderName != rhs.folderName ||
|
||||
lhs.queryID != rhs.queryID {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsChildren = lhs.children, let rhsChildren = rhs.children {
|
||||
return lhsChildren == rhsChildren
|
||||
}
|
||||
return lhs.children == nil && rhs.children == nil
|
||||
}
|
||||
|
||||
public struct BookmarkMirrorItem: Equatable {
|
||||
public let guid: GUID
|
||||
public let type: BookmarkNodeType
|
||||
public let dateAdded: Timestamp?
|
||||
public var serverModified: Timestamp
|
||||
public let isDeleted: Bool
|
||||
public let hasDupe: Bool
|
||||
public let parentID: GUID?
|
||||
public let parentName: String?
|
||||
|
||||
// Livemarks.
|
||||
public let feedURI: String?
|
||||
public let siteURI: String?
|
||||
|
||||
// Separators.
|
||||
let pos: Int?
|
||||
|
||||
// Folders, livemarks, bookmarks and queries.
|
||||
public let title: String?
|
||||
let description: String?
|
||||
|
||||
// Bookmarks and queries.
|
||||
let bookmarkURI: String?
|
||||
let tags: String?
|
||||
let keyword: String?
|
||||
|
||||
// Queries.
|
||||
let folderName: String?
|
||||
let queryID: String?
|
||||
|
||||
// Folders.
|
||||
public let children: [GUID]?
|
||||
|
||||
// Internal stuff.
|
||||
let faviconID: Int?
|
||||
public let localModified: Timestamp?
|
||||
let syncStatus: SyncStatus?
|
||||
|
||||
public func copyWithDateAdded(_ dateAdded: Timestamp) -> BookmarkMirrorItem {
|
||||
return BookmarkMirrorItem(
|
||||
guid: self.guid,
|
||||
type: self.type,
|
||||
dateAdded: dateAdded,
|
||||
serverModified: self.serverModified,
|
||||
isDeleted: self.isDeleted,
|
||||
hasDupe: self.hasDupe,
|
||||
parentID: self.parentID,
|
||||
parentName: self.parentName,
|
||||
feedURI: self.feedURI,
|
||||
siteURI: self.siteURI,
|
||||
pos: self.pos,
|
||||
title: self.title,
|
||||
description: self.description,
|
||||
bookmarkURI: self.bookmarkURI,
|
||||
tags: self.tags,
|
||||
keyword: self.keyword,
|
||||
folderName: self.folderName,
|
||||
queryID: self.queryID,
|
||||
children: self.children,
|
||||
faviconID: self.faviconID,
|
||||
localModified: self.localModified,
|
||||
syncStatus: self.syncStatus)
|
||||
}
|
||||
|
||||
public func copyWithParentID(_ parentID: GUID, parentName: String?) -> BookmarkMirrorItem {
|
||||
return BookmarkMirrorItem(
|
||||
guid: self.guid,
|
||||
type: self.type,
|
||||
dateAdded: self.dateAdded,
|
||||
serverModified: self.serverModified,
|
||||
isDeleted: self.isDeleted,
|
||||
hasDupe: self.hasDupe,
|
||||
parentID: parentID,
|
||||
parentName: parentName,
|
||||
feedURI: self.feedURI,
|
||||
siteURI: self.siteURI,
|
||||
pos: self.pos,
|
||||
title: self.title,
|
||||
description: self.description,
|
||||
bookmarkURI: self.bookmarkURI,
|
||||
tags: self.tags,
|
||||
keyword: self.keyword,
|
||||
folderName: self.folderName,
|
||||
queryID: self.queryID,
|
||||
children: self.children,
|
||||
faviconID: self.faviconID,
|
||||
localModified: self.localModified,
|
||||
syncStatus: self.syncStatus)
|
||||
}
|
||||
|
||||
// Ignores internal metadata and GUID; a pure value comparison.
|
||||
// Does compare child GUIDs!
|
||||
public func sameAs(_ rhs: BookmarkMirrorItem) -> Bool {
|
||||
if self.type != rhs.type ||
|
||||
self.dateAdded != rhs.dateAdded ||
|
||||
self.isDeleted != rhs.isDeleted ||
|
||||
self.pos != rhs.pos ||
|
||||
self.parentID != rhs.parentID ||
|
||||
self.parentName != rhs.parentName ||
|
||||
self.feedURI != rhs.feedURI ||
|
||||
self.siteURI != rhs.siteURI ||
|
||||
self.title != rhs.title ||
|
||||
(self.description ?? "") != (rhs.description ?? "") ||
|
||||
self.bookmarkURI != rhs.bookmarkURI ||
|
||||
self.tags != rhs.tags ||
|
||||
self.keyword != rhs.keyword ||
|
||||
self.folderName != rhs.folderName ||
|
||||
self.queryID != rhs.queryID {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsChildren = self.children, let rhsChildren = rhs.children {
|
||||
return lhsChildren == rhsChildren
|
||||
}
|
||||
return self.children == nil && rhs.children == nil
|
||||
}
|
||||
|
||||
public func asJSON() -> JSON {
|
||||
return self.asJSONWithChildren(self.children)
|
||||
}
|
||||
|
||||
public func asJSONWithChildren(_ children: [GUID]?) -> JSON {
|
||||
var out: [String: Any] = [:]
|
||||
|
||||
out["id"] = BookmarkRoots.translateOutgoingRootGUID(self.guid)
|
||||
|
||||
func take(_ key: String, _ val: String?) {
|
||||
guard let val = val else {
|
||||
return
|
||||
}
|
||||
out[key] = val
|
||||
}
|
||||
|
||||
if self.isDeleted {
|
||||
out["deleted"] = true
|
||||
return JSON(out)
|
||||
}
|
||||
|
||||
out["dateAdded"] = self.dateAdded
|
||||
out["hasDupe"] = self.hasDupe
|
||||
|
||||
// TODO: this should never be nil!
|
||||
if let parentID = self.parentID {
|
||||
out["parentid"] = BookmarkRoots.translateOutgoingRootGUID(parentID)
|
||||
take("parentName", titleForSpecialGUID(parentID) ?? self.parentName ?? "")
|
||||
}
|
||||
|
||||
func takeBookmarkFields() {
|
||||
take("title", self.title)
|
||||
take("bmkUri", self.bookmarkURI)
|
||||
take("description", self.description)
|
||||
if let tags = self.tags {
|
||||
let tagsJSON = JSON(parseJSON: tags)
|
||||
if let tagsArray = tagsJSON.array, tagsArray.every({ $0.type == SwiftyJSON.Type.string }) {
|
||||
out["tags"] = tagsArray
|
||||
} else {
|
||||
out["tags"] = []
|
||||
}
|
||||
} else {
|
||||
out["tags"] = []
|
||||
}
|
||||
take("keyword", self.keyword)
|
||||
}
|
||||
|
||||
func takeFolderFields() {
|
||||
take("title", titleForSpecialGUID(self.guid) ?? self.title)
|
||||
take("description", self.description)
|
||||
if let children = children {
|
||||
if BookmarkRoots.RootGUID == self.guid {
|
||||
// Only the root contains roots, and so only its children
|
||||
// need to be translated.
|
||||
out["children"] = children.map(BookmarkRoots.translateOutgoingRootGUID)
|
||||
} else {
|
||||
out["children"] = children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch self.type {
|
||||
|
||||
case .query:
|
||||
out["type"] = "query"
|
||||
take("folderName", self.folderName)
|
||||
take("queryId", self.queryID)
|
||||
takeBookmarkFields()
|
||||
|
||||
case .bookmark:
|
||||
out["type"] = "bookmark"
|
||||
takeBookmarkFields()
|
||||
|
||||
case .livemark:
|
||||
out["type"] = "livemark"
|
||||
take("siteUri", self.siteURI)
|
||||
take("feedUri", self.feedURI)
|
||||
takeFolderFields()
|
||||
|
||||
case .folder:
|
||||
out["type"] = "folder"
|
||||
takeFolderFields()
|
||||
|
||||
case .separator:
|
||||
out["type"] = "separator"
|
||||
if let pos = self.pos {
|
||||
out["pos"] = pos
|
||||
}
|
||||
|
||||
case .dynamicContainer:
|
||||
// Sigh.
|
||||
preconditionFailure("DynamicContainer not supported.")
|
||||
}
|
||||
|
||||
return JSON(out)
|
||||
}
|
||||
|
||||
// The places root is a folder but has no parentName.
|
||||
public static func folder(_ guid: GUID, dateAdded: Timestamp?, modified: Timestamp, hasDupe: Bool, parentID: GUID, parentName: String?, title: String, description: String?, children: [GUID]) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
let parent = BookmarkRoots.translateIncomingRootGUID(parentID)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: .folder, dateAdded: dateAdded, serverModified: modified,
|
||||
isDeleted: false, hasDupe: hasDupe, parentID: parent, parentName: parentName,
|
||||
feedURI: nil, siteURI: nil,
|
||||
pos: nil,
|
||||
title: title, description: description,
|
||||
bookmarkURI: nil, tags: nil, keyword: nil,
|
||||
folderName: nil, queryID: nil,
|
||||
children: children,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
|
||||
public static func livemark(_ guid: GUID, dateAdded: Timestamp?, modified: Timestamp, hasDupe: Bool, parentID: GUID, parentName: String?, title: String?, description: String?, feedURI: String, siteURI: String) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
let parent = BookmarkRoots.translateIncomingRootGUID(parentID)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: .livemark, dateAdded: dateAdded, serverModified: modified,
|
||||
isDeleted: false, hasDupe: hasDupe, parentID: parent, parentName: parentName,
|
||||
feedURI: feedURI, siteURI: siteURI,
|
||||
pos: nil,
|
||||
title: title, description: description,
|
||||
bookmarkURI: nil, tags: nil, keyword: nil,
|
||||
folderName: nil, queryID: nil,
|
||||
children: nil,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
|
||||
public static func separator(_ guid: GUID, dateAdded: Timestamp?, modified: Timestamp, hasDupe: Bool, parentID: GUID, parentName: String?, pos: Int) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
let parent = BookmarkRoots.translateIncomingRootGUID(parentID)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: .separator, dateAdded: dateAdded, serverModified: modified,
|
||||
isDeleted: false, hasDupe: hasDupe, parentID: parent, parentName: parentName,
|
||||
feedURI: nil, siteURI: nil,
|
||||
pos: pos,
|
||||
title: nil, description: nil,
|
||||
bookmarkURI: nil, tags: nil, keyword: nil,
|
||||
folderName: nil, queryID: nil,
|
||||
children: nil,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
|
||||
public static func bookmark(_ guid: GUID, dateAdded: Timestamp?, modified: Timestamp, hasDupe: Bool, parentID: GUID, parentName: String?, title: String, description: String?, URI: String, tags: String, keyword: String?) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
let parent = BookmarkRoots.translateIncomingRootGUID(parentID)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: .bookmark, dateAdded: dateAdded, serverModified: modified,
|
||||
isDeleted: false, hasDupe: hasDupe, parentID: parent, parentName: parentName,
|
||||
feedURI: nil, siteURI: nil,
|
||||
pos: nil,
|
||||
title: title, description: description,
|
||||
bookmarkURI: URI, tags: tags, keyword: keyword,
|
||||
folderName: nil, queryID: nil,
|
||||
children: nil,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
|
||||
public static func query(_ guid: GUID, dateAdded: Timestamp?, modified: Timestamp, hasDupe: Bool, parentID: GUID, parentName: String?, title: String, description: String?, URI: String, tags: String, keyword: String?, folderName: String?, queryID: String?) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
let parent = BookmarkRoots.translateIncomingRootGUID(parentID)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: .query, dateAdded: dateAdded, serverModified: modified,
|
||||
isDeleted: false, hasDupe: hasDupe, parentID: parent, parentName: parentName,
|
||||
feedURI: nil, siteURI: nil,
|
||||
pos: nil,
|
||||
title: title, description: description,
|
||||
bookmarkURI: URI, tags: tags, keyword: keyword,
|
||||
folderName: folderName, queryID: queryID,
|
||||
children: nil,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
|
||||
public static func deleted(_ type: BookmarkNodeType, guid: GUID, modified: Timestamp) -> BookmarkMirrorItem {
|
||||
let id = BookmarkRoots.translateIncomingRootGUID(guid)
|
||||
|
||||
return BookmarkMirrorItem(guid: id, type: type, dateAdded: nil, serverModified: modified,
|
||||
isDeleted: true, hasDupe: false, parentID: nil, parentName: nil,
|
||||
feedURI: nil, siteURI: nil,
|
||||
pos: nil,
|
||||
title: nil, description: nil,
|
||||
bookmarkURI: nil, tags: nil, keyword: nil,
|
||||
folderName: nil, queryID: nil,
|
||||
children: nil,
|
||||
faviconID: nil, localModified: nil, syncStatus: nil)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue