| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  | import {Conversion, DesugaringStep} from "./Conversion"; | 
					
						
							|  |  |  | import {LayoutConfigJson} from "../Json/LayoutConfigJson"; | 
					
						
							|  |  |  | import {Utils} from "../../../Utils"; | 
					
						
							|  |  |  | import * as metapaths from "../../../assets/layoutconfigmeta.json"; | 
					
						
							|  |  |  | import * as tagrenderingmetapaths from "../../../assets/tagrenderingconfigmeta.json"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | 
					
						
							| 
									
										
										
										
											2022-02-14 22:21:01 +01:00
										 |  |  |     private _isOfficial: boolean; | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |     private _sharedTagRenderings: Map<string, any>; | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private static readonly layoutMetaPaths = (metapaths["default"] ?? metapaths).filter(mp => mp.typeHint !== undefined && (mp.typeHint === "image" || mp.typeHint === "icon")) | 
					
						
							| 
									
										
										
										
											2022-02-19 02:50:54 +01:00
										 |  |  |     private static readonly tagRenderingMetaPaths = (tagrenderingmetapaths["default"] ?? tagrenderingmetapaths).filter(trpath => trpath.typeHint === "rendered") | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |     constructor(isOfficial: boolean, sharedTagRenderings: Map<string, any>) { | 
					
						
							| 
									
										
										
										
											2022-02-14 02:26:03 +01:00
										 |  |  |         super("Extract all images from a layoutConfig using the meta paths",[],"ExctractImages"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:21:01 +01:00
										 |  |  |         this._isOfficial = isOfficial; | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |         this._sharedTagRenderings = sharedTagRenderings; | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 22:21:01 +01:00
										 |  |  |     convert(json: LayoutConfigJson, context: string): { result: string[], errors: string[], warnings: string[] } { | 
					
						
							| 
									
										
										
										
											2022-02-19 17:39:16 +01:00
										 |  |  |         const allFoundImages : string[] = [] | 
					
						
							| 
									
										
										
										
											2022-02-11 19:56:31 +01:00
										 |  |  |         const errors = [] | 
					
						
							| 
									
										
										
										
											2022-02-14 22:21:01 +01:00
										 |  |  |         const warnings = [] | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  |         for (const metapath of ExtractImages.layoutMetaPaths) { | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |             const mightBeTr = Array.isArray(metapath.type) && metapath.type.some(t => t["$ref"] == "#/definitions/TagRenderingConfigJson") | 
					
						
							|  |  |  |             const found = Utils.CollectPath(metapath.path, json) | 
					
						
							|  |  |  |             if (mightBeTr) { | 
					
						
							|  |  |  |                 // We might have tagRenderingConfigs containing icons here
 | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  |                 for (const el of found) { | 
					
						
							|  |  |  |                     const path = el.path | 
					
						
							|  |  |  |                     const foundImage = el.leaf; | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |                     if (typeof foundImage === "string") { | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |                          | 
					
						
							|  |  |  |                         if(foundImage == ""){ | 
					
						
							| 
									
										
										
										
											2022-02-19 17:39:16 +01:00
										 |  |  |                             warnings.push(context+"."+path.join(".")+" Found an empty image") | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |                         } | 
					
						
							|  |  |  |                          | 
					
						
							|  |  |  |                         if(this._sharedTagRenderings?.has(foundImage)){ | 
					
						
							|  |  |  |                             // This is not an image, but a shared tag rendering
 | 
					
						
							|  |  |  |                             continue | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                          | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |                         allFoundImages.push(foundImage) | 
					
						
							| 
									
										
										
										
											2022-02-17 23:54:14 +01:00
										 |  |  |                     } else{ | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |                         // This is a tagRendering where every rendered value might be an icon!
 | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  |                         for (const trpath of ExtractImages.tagRenderingMetaPaths) { | 
					
						
							| 
									
										
										
										
											2022-02-11 19:56:31 +01:00
										 |  |  |                             const fromPath = Utils.CollectPath(trpath.path, foundImage) | 
					
						
							|  |  |  |                             for (const img of fromPath) { | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  |                                 if (typeof img.leaf !== "string") { | 
					
						
							| 
									
										
										
										
											2022-02-19 02:50:54 +01:00
										 |  |  |                                     (this._isOfficial ?   errors: warnings).push(context+"."+img.path.join(".")+": found an image path that is not a string: " + JSON.stringify(img.leaf)) | 
					
						
							| 
									
										
										
										
											2022-02-11 19:56:31 +01:00
										 |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2022-02-19 02:45:15 +01:00
										 |  |  |                             allFoundImages.push(...fromPath.map(i => i.leaf).filter(i => typeof i=== "string")) | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |                             for (const pathAndImg of fromPath) { | 
					
						
							|  |  |  |                                 if(pathAndImg.leaf === "" || pathAndImg.leaf["path"] == ""){ | 
					
						
							| 
									
										
										
										
											2022-02-19 17:39:16 +01:00
										 |  |  |                                     warnings.push(context+[...path,...pathAndImg.path].join(".")+": Found an empty image at ") | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2022-02-19 17:39:16 +01:00
										 |  |  |                 for (const foundElement of found) { | 
					
						
							|  |  |  |                     if(foundElement.leaf === ""){ | 
					
						
							|  |  |  |                         warnings.push(context+"."+foundElement.path.join(".")+" Found an empty image") | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     allFoundImages.push(foundElement.leaf) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                  | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-17 23:54:14 +01:00
										 |  |  |         const splitParts = [].concat(...Utils.NoNull(allFoundImages) | 
					
						
							|  |  |  |             .map(img => img["path"] ?? img) | 
					
						
							|  |  |  |             .map(img => img.split(";"))) | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |             .map(img => img.split(":")[0]) | 
					
						
							| 
									
										
										
										
											2022-02-19 17:39:16 +01:00
										 |  |  |             .filter(img => img !== "") | 
					
						
							| 
									
										
										
										
											2022-02-14 22:21:01 +01:00
										 |  |  |         return {result: Utils.Dedup(splitParts), errors, warnings}; | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FixImages extends DesugaringStep<LayoutConfigJson> { | 
					
						
							|  |  |  |     private readonly _knownImages: Set<string>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(knownImages: Set<string>) { | 
					
						
							| 
									
										
										
										
											2022-02-14 02:26:03 +01:00
										 |  |  |         super("Walks over the entire theme and replaces images to the relative URL. Only works if the ID of the theme is an URL",[],"fixImages"); | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |         this._knownImages = knownImages; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-10 23:16:14 +01:00
										 |  |  |     convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson } { | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |         let url: URL; | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             url = new URL(json.id) | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							|  |  |  |             // Not a URL, we don't rewrite
 | 
					
						
							|  |  |  |             return {result: json} | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const absolute = url.protocol + "//" + url.host | 
					
						
							|  |  |  |         let relative = url.protocol + "//" + url.host + url.pathname | 
					
						
							|  |  |  |         relative = relative.substring(0, relative.lastIndexOf("/")) | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function replaceString(leaf: string) { | 
					
						
							|  |  |  |             if (self._knownImages.has(leaf)) { | 
					
						
							|  |  |  |                 return leaf; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (leaf.startsWith("./")) { | 
					
						
							|  |  |  |                 return relative + leaf.substring(1) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (leaf.startsWith("/")) { | 
					
						
							|  |  |  |                 return absolute + leaf | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return leaf; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         json = Utils.Clone(json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let paths = metapaths["default"] ?? metapaths | 
					
						
							|  |  |  |         let trpaths = tagrenderingmetapaths["default"] ?? tagrenderingmetapaths | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const metapath of paths) { | 
					
						
							|  |  |  |             if (metapath.typeHint !== "image" && metapath.typeHint !== "icon") { | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const mightBeTr = Array.isArray(metapath.type) && metapath.type.some(t => t["$ref"] == "#/definitions/TagRenderingConfigJson") | 
					
						
							| 
									
										
										
										
											2022-02-18 23:10:27 +01:00
										 |  |  |             Utils.WalkPath(metapath.path, json, (leaf, path) => { | 
					
						
							| 
									
										
										
										
											2022-02-09 22:37:21 +01:00
										 |  |  |                 if (typeof leaf === "string") { | 
					
						
							|  |  |  |                     return replaceString(leaf) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (mightBeTr) { | 
					
						
							|  |  |  |                     // We might have reached a tagRenderingConfig containing icons
 | 
					
						
							|  |  |  |                     // lets walk every rendered value and fix the images in there
 | 
					
						
							|  |  |  |                     for (const trpath of trpaths) { | 
					
						
							|  |  |  |                         if (trpath.typeHint !== "rendered") { | 
					
						
							|  |  |  |                             continue | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         Utils.WalkPath(trpath.path, leaf, (rendered => { | 
					
						
							|  |  |  |                             return replaceString(rendered) | 
					
						
							|  |  |  |                         })) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return leaf; | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             result: json | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |