1
1
/*
2
2
This source file is part of the Swift.org open source project
3
3
4
- Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
4
+ Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
5
5
Licensed under Apache License v2.0 with Runtime Library Exception
6
6
7
7
See https://swift.org/LICENSE.txt for license information
@@ -172,7 +172,7 @@ public class OutOfProcessReferenceResolver: ExternalReferenceResolver, FallbackR
172
172
name = . conceptual( title: resolvedInformation. title)
173
173
}
174
174
175
- return DocumentationNode (
175
+ var node = DocumentationNode (
176
176
reference: reference,
177
177
kind: resolvedInformation. kind,
178
178
sourceLanguage: resolvedInformation. language,
@@ -182,6 +182,10 @@ public class OutOfProcessReferenceResolver: ExternalReferenceResolver, FallbackR
182
182
semantic: maybeSymbol,
183
183
platformNames: resolvedInformation. platformNames
184
184
)
185
+
186
+ addImagesAndCacheMediaReferences ( to: & node, from: resolvedInformation)
187
+
188
+ return node
185
189
}
186
190
187
191
/// Returns the web URL for the external topic.
@@ -247,7 +251,7 @@ public class OutOfProcessReferenceResolver: ExternalReferenceResolver, FallbackR
247
251
variants: resolvedInformation. variants
248
252
) ! // This entity was resolved from a symbol USR and is known to be a symbol.
249
253
250
- return DocumentationNode (
254
+ var node = DocumentationNode (
251
255
reference: reference,
252
256
kind: resolvedInformation. kind,
253
257
sourceLanguage: resolvedInformation. language,
@@ -257,6 +261,49 @@ public class OutOfProcessReferenceResolver: ExternalReferenceResolver, FallbackR
257
261
semantic: symbol,
258
262
platformNames: resolvedInformation. platformNames
259
263
)
264
+
265
+ addImagesAndCacheMediaReferences ( to: & node, from: resolvedInformation)
266
+
267
+ return node
268
+ }
269
+
270
+ private func addImagesAndCacheMediaReferences( to node: inout DocumentationNode , from resolvedInformation: ResolvedInformation ) {
271
+ // Because DocC renders external content in the local context, external media also needs to be added to the local context.
272
+ // If the external content was treated as pre-rendered then this wouldn't be necessary. (rdar://78718811)
273
+ // FIXME: https://github.com/apple/swift-docc/issues/468
274
+
275
+ // `@PageImage` directives isn't meant to be created in code like this but it's the only way to associate topic images
276
+ // with a render node.
277
+
278
+ if let topicImages = resolvedInformation. topicImages, !topicImages. isEmpty {
279
+ let metadata = node. metadata ?? Metadata ( originalMarkup: BlockDirective ( name: " Metadata " , children: [ ] ) , documentationExtension: nil , technologyRoot: nil , displayName: nil )
280
+
281
+ metadata. pageImages = topicImages. map { topicImage in
282
+ let purpose : PageImage . Purpose
283
+ switch topicImage. type {
284
+ case . card: purpose = . card
285
+ case . icon: purpose = . icon
286
+ }
287
+
288
+ return PageImage . _make (
289
+ purpose: purpose,
290
+ source: ResourceReference ( bundleIdentifier: node. reference. bundleIdentifier, path: topicImage. identifier. identifier) ,
291
+ alt: ( resolvedInformation. references? . first ( where: { $0. identifier == topicImage. identifier } ) as? ImageReference ) ? . altText
292
+ )
293
+ }
294
+
295
+ node. metadata = metadata
296
+ }
297
+
298
+ // Since the DocumentationNode doesn't have any media references, the external media references can't be returned with the node.
299
+ // Instead they are added to the cache so that they are returned from later requests.
300
+
301
+ for reference in ( resolvedInformation. references ?? [ ] ) {
302
+ guard let mediaReference = reference as? MediaReference else { continue }
303
+
304
+ assetCache [ . init( assetName: mediaReference. identifier. identifier, bundleIdentifier: node. reference. bundleIdentifier) ] = mediaReference. asset
305
+ }
306
+
260
307
}
261
308
262
309
/// Returns the web URL for the external symbol.
@@ -400,6 +447,14 @@ public class OutOfProcessReferenceResolver: ExternalReferenceResolver, FallbackR
400
447
}
401
448
}
402
449
450
+ extension OutOfProcessReferenceResolver : _ExternalAssetResolver {
451
+ public func _resolveExternalAsset( named assetName: String , bundleIdentifier: String ) -> DataAsset ? {
452
+ // We don't want to make additional requests for these external assets.
453
+ // If they were already resolved, return them from the cache.
454
+ return assetCache [ AssetReference ( assetName: assetName, bundleIdentifier: bundleIdentifier) ]
455
+ }
456
+ }
457
+
403
458
private protocol ExternalLinkResolving {
404
459
func sendAndWait< Request: Codable & CustomStringConvertible , Response: Codable > ( request: Request ? ) throws -> Response
405
460
}
@@ -689,6 +744,10 @@ extension OutOfProcessReferenceResolver {
689
744
690
745
/// A type used to transfer information about a resolved reference to DocC from from a reference resolver in another executable.
691
746
public struct ResolvedInformation : Codable {
747
+ // This type is duplicating the information from LinkDestinationSummary with some minor differences.
748
+ // Changes generally need to be made in both places. It would be good to replace this with LinkDestinationSummary.
749
+ // FIXME: https://github.com/apple/swift-docc/issues/468
750
+
692
751
/// Information about the resolved kind.
693
752
public let kind : DocumentationNode . Kind
694
753
/// Information about the resolved URL.
@@ -719,8 +778,14 @@ extension OutOfProcessReferenceResolver {
719
778
return platforms. map { platforms in Set ( platforms. compactMap { $0. name } ) }
720
779
}
721
780
781
+ /// Images that are used to represent the summarized element.
782
+ public var topicImages : [ TopicImage ] ?
783
+
784
+ /// References used in the content of the summarized element.
785
+ public var references : [ RenderReference ] ?
786
+
722
787
/// The variants of content (kind, url, title, abstract, language, declaration) for this resolver information.
723
- public let variants : [ Variant ] ?
788
+ public var variants : [ Variant ] ?
724
789
725
790
/// Creates a new resolved information value with all its values.
726
791
///
@@ -743,6 +808,8 @@ extension OutOfProcessReferenceResolver {
743
808
availableLanguages: Set < SourceLanguage > ,
744
809
platforms: [ PlatformAvailability ] ? ,
745
810
declarationFragments: DeclarationFragments ? ,
811
+ topicImages: [ TopicImage ] ? ,
812
+ references: [ RenderReference ] ? ,
746
813
variants: [ Variant ] ? = nil
747
814
) {
748
815
self . kind = kind
@@ -753,6 +820,8 @@ extension OutOfProcessReferenceResolver {
753
820
self . availableLanguages = availableLanguages
754
821
self . platforms = platforms
755
822
self . declarationFragments = declarationFragments
823
+ self . topicImages = topicImages
824
+ self . references = references
756
825
self . variants = variants
757
826
}
758
827
@@ -889,3 +958,55 @@ extension OutOfProcessReferenceResolver {
889
958
)
890
959
}
891
960
}
961
+
962
+ extension OutOfProcessReferenceResolver . ResolvedInformation {
963
+ enum CodingKeys : CodingKey {
964
+ case kind
965
+ case url
966
+ case title
967
+ case abstract
968
+ case language
969
+ case availableLanguages
970
+ case platforms
971
+ case declarationFragments
972
+ case topicImages
973
+ case references
974
+ case variants
975
+ }
976
+
977
+ public init ( from decoder: Decoder ) throws {
978
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
979
+
980
+ kind = try container. decode ( DocumentationNode . Kind. self, forKey: . kind)
981
+ url = try container. decode ( URL . self, forKey: . url)
982
+ title = try container. decode ( String . self, forKey: . title)
983
+ abstract = try container. decode ( String . self, forKey: . abstract)
984
+ language = try container. decode ( SourceLanguage . self, forKey: . language)
985
+ availableLanguages = try container. decode ( Set< SourceLanguage> . self , forKey: . availableLanguages)
986
+ platforms = try container. decodeIfPresent ( [ OutOfProcessReferenceResolver . ResolvedInformation . PlatformAvailability ] . self, forKey: . platforms)
987
+ declarationFragments = try container. decodeIfPresent ( OutOfProcessReferenceResolver . ResolvedInformation. DeclarationFragments. self, forKey: . declarationFragments)
988
+ topicImages = try container. decodeIfPresent ( [ TopicImage ] . self, forKey: . topicImages)
989
+ references = try container. decodeIfPresent ( [ CodableRenderReference ] . self, forKey: . references) . map { decodedReferences in
990
+ decodedReferences. map ( \. reference)
991
+ }
992
+ variants = try container. decodeIfPresent ( [ OutOfProcessReferenceResolver . ResolvedInformation . Variant ] . self, forKey: . variants)
993
+
994
+ }
995
+
996
+ public func encode( to encoder: Encoder ) throws {
997
+ var container = encoder. container ( keyedBy: CodingKeys . self)
998
+
999
+ try container. encode ( self . kind, forKey: . kind)
1000
+ try container. encode ( self . url, forKey: . url)
1001
+ try container. encode ( self . title, forKey: . title)
1002
+ try container. encode ( self . abstract, forKey: . abstract)
1003
+ try container. encode ( self . language, forKey: . language)
1004
+ try container. encode ( self . availableLanguages, forKey: . availableLanguages)
1005
+ try container. encodeIfPresent ( self . platforms, forKey: . platforms)
1006
+ try container. encodeIfPresent ( self . declarationFragments, forKey: . declarationFragments)
1007
+ try container. encodeIfPresent ( self . topicImages, forKey: . topicImages)
1008
+ try container. encodeIfPresent ( references? . map { CodableRenderReference ( $0) } , forKey: . references)
1009
+ try container. encodeIfPresent ( self . variants, forKey: . variants)
1010
+ }
1011
+ }
1012
+
0 commit comments