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 ;
constructor ( isOfficial : boolean ) {
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-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-09 22:37:21 +01:00
const paths = metapaths [ "default" ] ? ? metapaths
const trpaths = tagrenderingmetapaths [ "default" ] ? ? tagrenderingmetapaths
const allFoundImages = [ ]
2022-02-11 19:56:31 +01:00
const errors = [ ]
2022-02-14 22:21:01 +01:00
const warnings = [ ]
2022-02-09 22:37:21 +01:00
for ( const metapath of paths ) {
if ( metapath . typeHint === undefined ) {
continue
}
if ( metapath . typeHint !== "image" && metapath . typeHint !== "icon" ) {
continue
}
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
for ( const foundImage of found ) {
if ( typeof foundImage === "string" ) {
allFoundImages . push ( foundImage )
} else {
// This is a tagRendering where every rendered value might be an icon!
for ( const trpath of trpaths ) {
if ( trpath . typeHint !== "rendered" ) {
continue
}
2022-02-11 19:56:31 +01:00
const fromPath = Utils . CollectPath ( trpath . path , foundImage )
for ( const img of fromPath ) {
if ( typeof img !== "string" ) {
2022-02-14 23:42:32 +01:00
( this . _isOfficial ? errors : warnings ) . push ( context + ": found an image path that is not a path at " + context + "." + metapath . path . join ( "." ) + ": " + JSON . stringify ( img ) )
2022-02-11 19:56:31 +01:00
}
}
allFoundImages . push ( . . . fromPath . filter ( i = > typeof i === "string" ) )
2022-02-09 22:37:21 +01:00
}
}
}
} else {
allFoundImages . push ( . . . found )
}
}
2022-02-11 19:56:31 +01:00
const splitParts = [ ] . concat ( . . . Utils . NoNull ( allFoundImages ) . map ( img = > img . split ( ";" ) ) )
2022-02-09 22:37:21 +01:00
. map ( img = > img . split ( ":" ) [ 0 ] )
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" )
Utils . WalkPath ( metapath . path , json , leaf = > {
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
} ;
}
}