forked from MapComplete/MapComplete
		
	Move some assets to the 'tagRenderings'-directory as they are only needed there, add 'smoking' question, add 'nightclubs' to 'pub_cafe'-layer
This commit is contained in:
		
							parent
							
								
									2a6a09da76
								
							
						
					
					
						commit
						e13c7ae677
					
				
					 18 changed files with 472 additions and 132 deletions
				
			
		|  | @ -17,7 +17,7 @@ import {QuestionableTagRenderingConfigJson} from "../Json/QuestionableTagRenderi | |||
| 
 | ||||
| 
 | ||||
| class ValidateLanguageCompleteness extends DesugaringStep<any> { | ||||
|      | ||||
| 
 | ||||
|     private readonly _languages: string[]; | ||||
| 
 | ||||
|     constructor(...languages: string[]) { | ||||
|  | @ -98,8 +98,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                     continue | ||||
|                 } | ||||
|                 if (image.match(/[a-z]*/)) { | ||||
|                      | ||||
|                     if(Svg.All[image + ".svg"] !== undefined){ | ||||
| 
 | ||||
|                     if (Svg.All[image + ".svg"] !== undefined) { | ||||
|                         // This is a builtin img, e.g. 'checkmark' or 'crosshair'
 | ||||
|                         continue;// =>
 | ||||
|                     } | ||||
|  | @ -121,18 +121,18 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                                 ` Width = ${width} height = ${height}`; | ||||
|                             (json.hideFromOverview ? warnings : errors).push(e) | ||||
|                         } | ||||
|                          | ||||
| 
 | ||||
|                         const w = parseInt(width); | ||||
|                         const h = parseInt(height) | ||||
|                         if(w < 370 || h < 370){ | ||||
|                             const e : string = [ | ||||
|                         if (w < 370 || h < 370) { | ||||
|                             const e: string = [ | ||||
|                                 `the icon for theme ${json.id} is too small. Please rescale the icon at ${json.icon}`, | ||||
|                                 `Even though an SVG is 'infinitely scaleable', the icon should be dimensioned bigger. One of the build steps of the theme does convert the image to a PNG (to serve as PWA-icon) and having a small dimension will cause blurry images.`, | ||||
|                                 ` Width = ${width} height = ${height}; we recommend a size of at least 500px * 500px and to use a square aspect ratio.`, | ||||
|                                 ].join("\n"); | ||||
|                             ].join("\n"); | ||||
|                             (json.hideFromOverview ? warnings : errors).push(e) | ||||
|                         } | ||||
|                          | ||||
| 
 | ||||
|                     }) | ||||
|                 } catch (e) { | ||||
|                     console.error("Could not read " + json.icon + " due to " + e) | ||||
|  | @ -186,7 +186,7 @@ export class ValidateThemeAndLayers extends Fuse<LayoutConfigJson> { | |||
|     constructor(knownImagePaths: Set<string>, path: string, isBuiltin: boolean, sharedTagRenderings: Map<string, any>) { | ||||
|         super("Validates a theme and the contained layers", | ||||
|             new ValidateTheme(knownImagePaths, path, isBuiltin, sharedTagRenderings), | ||||
|             new On("layers", new Each(new ValidateLayer(undefined, false))) | ||||
|             new On("layers", new Each(new ValidateLayer(undefined, false, knownImagePaths))) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | @ -222,22 +222,22 @@ class OverrideShadowingCheck extends DesugaringStep<LayoutConfigJson> { | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| class MiscThemeChecks extends DesugaringStep<LayoutConfigJson>{ | ||||
| class MiscThemeChecks extends DesugaringStep<LayoutConfigJson> { | ||||
|     constructor() { | ||||
|         super("Miscelleanous checks on the theme", [],"MiscThemesChecks"); | ||||
|         super("Miscelleanous checks on the theme", [], "MiscThemesChecks"); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } { | ||||
|         const warnings = [] | ||||
|         const errors = [] | ||||
|         if(json.id !== "personal" && (json.layers === undefined || json.layers.length === 0)){ | ||||
|             errors.push("The theme "+json.id+" has no 'layers' defined ("+context+")") | ||||
|         if (json.id !== "personal" && (json.layers === undefined || json.layers.length === 0)) { | ||||
|             errors.push("The theme " + json.id + " has no 'layers' defined (" + context + ")") | ||||
|         } | ||||
|         if(json.socialImage === ""){ | ||||
|             warnings.push("Social image for theme "+json.id+" is the emtpy string") | ||||
|         if (json.socialImage === "") { | ||||
|             warnings.push("Social image for theme " + json.id + " is the emtpy string") | ||||
|         } | ||||
|         return { | ||||
|             result :json, | ||||
|             result: json, | ||||
|             warnings, | ||||
|             errors | ||||
|         }; | ||||
|  | @ -258,28 +258,29 @@ export class PrevalidateTheme extends Fuse<LayoutConfigJson> { | |||
| 
 | ||||
| export class DetectShadowedMappings extends DesugaringStep<QuestionableTagRenderingConfigJson> { | ||||
|     private readonly _calculatedTagNames: string[]; | ||||
| 
 | ||||
|     constructor(layerConfig?: LayerConfigJson) { | ||||
|         super("Checks that the mappings don't shadow each other", [], "DetectShadowedMappings"); | ||||
|         this._calculatedTagNames = DetectShadowedMappings.extractCalculatedTagNames(layerConfig); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      *  | ||||
|      * | ||||
|      * DetectShadowedMappings.extractCalculatedTagNames({calculatedTags: ["_abc:=js()"]}) // => ["_abc"]
 | ||||
|      * DetectShadowedMappings.extractCalculatedTagNames({calculatedTags: ["_abc=js()"]}) // => ["_abc"]
 | ||||
|      */ | ||||
|     private static extractCalculatedTagNames(layerConfig?: LayerConfigJson | {calculatedTags : string []}){ | ||||
|     private static extractCalculatedTagNames(layerConfig?: LayerConfigJson | { calculatedTags: string [] }) { | ||||
|         return layerConfig?.calculatedTags?.map(ct => { | ||||
|             if(ct.indexOf(':=') >= 0){ | ||||
|             if (ct.indexOf(':=') >= 0) { | ||||
|                 return ct.split(':=')[0] | ||||
|             } | ||||
|             return ct.split("=")[0] | ||||
|         }) ?? [] | ||||
|          | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      *  | ||||
|      * | ||||
|      * // should detect a simple shadowed mapping
 | ||||
|      * const tr = {mappings: [ | ||||
|      *            { | ||||
|  | @ -319,20 +320,20 @@ export class DetectShadowedMappings extends DesugaringStep<QuestionableTagRender | |||
|         } | ||||
|         const defaultProperties = {} | ||||
|         for (const calculatedTagName of this._calculatedTagNames) { | ||||
|             defaultProperties[calculatedTagName] = "some_calculated_tag_value_for_"+calculatedTagName | ||||
|             defaultProperties[calculatedTagName] = "some_calculated_tag_value_for_" + calculatedTagName | ||||
|         } | ||||
|         const parsedConditions = json.mappings.map((m,i) => { | ||||
|         const parsedConditions = json.mappings.map((m, i) => { | ||||
|             const ctx = `${context}.mappings[${i}]` | ||||
|             const ifTags = TagUtils.Tag(m.if, ctx); | ||||
|             if(m.hideInAnswer !== undefined && m.hideInAnswer !== false && m.hideInAnswer !== true){ | ||||
|                 let conditionTags = TagUtils.Tag( m.hideInAnswer) | ||||
|             if (m.hideInAnswer !== undefined && m.hideInAnswer !== false && m.hideInAnswer !== true) { | ||||
|                 let conditionTags = TagUtils.Tag(m.hideInAnswer) | ||||
|                 // Merge the condition too!
 | ||||
|                 return new And([conditionTags, ifTags]) | ||||
|             } | ||||
|             return ifTags | ||||
|         }) | ||||
|         for (let i = 0; i < json.mappings.length; i++) { | ||||
|             if(!parsedConditions[i].isUsableAsAnswer()){ | ||||
|             if (!parsedConditions[i].isUsableAsAnswer()) { | ||||
|                 // There is no straightforward way to convert this mapping.if into a properties-object, so we simply skip this one
 | ||||
|                 // Yes, it might be shadowed, but running this check is to difficult right now
 | ||||
|                 continue | ||||
|  | @ -372,8 +373,10 @@ export class DetectShadowedMappings extends DesugaringStep<QuestionableTagRender | |||
| } | ||||
| 
 | ||||
| export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJson> { | ||||
|     constructor() { | ||||
|     private knownImagePaths: Set<string>; | ||||
|     constructor(knownImagePaths: Set<string>) { | ||||
|         super("Checks that 'then'clauses in mappings don't have images, but use 'icon' instead", [], "DetectMappingsWithImages"); | ||||
|         this.knownImagePaths = knownImagePaths; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -407,21 +410,29 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ | |||
|         for (let i = 0; i < json.mappings.length; i++) { | ||||
| 
 | ||||
|             const mapping = json.mappings[i] | ||||
|             const ignore = mapping["#"]?.indexOf(ignoreToken) >=0 | ||||
|             const ignore = mapping["#"]?.indexOf(ignoreToken) >= 0 | ||||
|             const images = Utils.Dedup(Translations.T(mapping.then)?.ExtractImages() ?? []) | ||||
|             const ctx = `${context}.mappings[${i}]` | ||||
|             if (images.length > 0) { | ||||
|                 if(!ignore){ | ||||
|                 if (!ignore) { | ||||
|                     errors.push(`${ctx}: A mapping has an image in the 'then'-clause. Remove the image there and use \`"icon": <your-image>\` instead. The images found are ${images.join(", ")}. (This check can be turned of by adding "#": "${ignoreToken}" in the mapping, but this is discouraged`) | ||||
|                 }else{ | ||||
|                 } else { | ||||
|                     information.push(`${ctx}: Ignored image ${images.join(", ")} in 'then'-clause of a mapping as this check has been disabled`) | ||||
| 
 | ||||
|                     for (const image of images) { | ||||
|                         if (this.knownImagePaths !== undefined && !this.knownImagePaths.has(image)) { | ||||
|                             const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}` | ||||
|                             errors.push(`Image with path ${image} not found or not attributed; it is used in ${json.id}${ctx}`) | ||||
|                         } | ||||
|                     } | ||||
|                      | ||||
|                 } | ||||
|             }else if (ignore){ | ||||
|             } else if (ignore) { | ||||
|                 warnings.push(`${ctx}: unused '${ignoreToken}' - please remove this`) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|          return { | ||||
|         return { | ||||
|             errors, | ||||
|             warnings, | ||||
|             information, | ||||
|  | @ -431,10 +442,10 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ | |||
| } | ||||
| 
 | ||||
| export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> { | ||||
|     constructor(layerConfig: LayerConfigJson) { | ||||
|     constructor(layerConfig?: LayerConfigJson, knownImagePaths?: Set<string>) { | ||||
|         super("Various validation on tagRenderingConfigs", | ||||
|             new DetectShadowedMappings( layerConfig), | ||||
|             new DetectMappingsWithImages()     | ||||
|             new DetectShadowedMappings(layerConfig), | ||||
|             new DetectMappingsWithImages(knownImagePaths) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | @ -446,11 +457,13 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> { | |||
|      */ | ||||
|     private readonly _path?: string; | ||||
|     private readonly _isBuiltin: boolean; | ||||
|     private knownImagePaths: Set<string>; | ||||
| 
 | ||||
|     constructor(path: string, isBuiltin: boolean) { | ||||
|     constructor(path: string, isBuiltin: boolean, knownImagePaths: Set<string>) { | ||||
|         super("Doesn't change anything, but emits warnings and errors", [], "ValidateLayer"); | ||||
|         this._path = path; | ||||
|         this._isBuiltin = isBuiltin; | ||||
|         this.knownImagePaths = knownImagePaths | ||||
|     } | ||||
| 
 | ||||
|     convert(json: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings?: string[], information?: string[] } { | ||||
|  | @ -475,13 +488,13 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> { | |||
| 
 | ||||
|         { | ||||
|             // duplicate ids in tagrenderings check
 | ||||
|           const duplicates = Utils.Dedup(Utils.Dupiclates( Utils.NoNull((json.tagRenderings ?? []).map(tr => tr["id"])))) | ||||
|               .filter(dupl => dupl !== "questions") | ||||
|             if(duplicates.length > 0){ | ||||
|                 errors.push("At "+context+": some tagrenderings have a duplicate id: "+duplicates.join(", ")) | ||||
|             const duplicates = Utils.Dedup(Utils.Dupiclates(Utils.NoNull((json.tagRenderings ?? []).map(tr => tr["id"])))) | ||||
|                 .filter(dupl => dupl !== "questions") | ||||
|             if (duplicates.length > 0) { | ||||
|                 errors.push("At " + context + ": some tagrenderings have a duplicate id: " + duplicates.join(", ")) | ||||
|             } | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         try { | ||||
|             { | ||||
|                 // Some checks for legacy elements
 | ||||
|  | @ -538,10 +551,10 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> { | |||
|                 } | ||||
|             } | ||||
|             if (json.tagRenderings !== undefined) { | ||||
|                const r = new On("tagRenderings", new Each(new ValidateTagRenderings(json))).convert(json, context) | ||||
|                 warnings.push(...(r.warnings??[])) | ||||
|                 errors.push(...(r.errors??[])) | ||||
|                 information.push(...(r.information??[])) | ||||
|                 const r = new On("tagRenderings", new Each(new ValidateTagRenderings(json, this.knownImagePaths))).convert(json, context) | ||||
|                 warnings.push(...(r.warnings ?? [])) | ||||
|                 errors.push(...(r.errors ?? [])) | ||||
|                 information.push(...(r.information ?? [])) | ||||
|             } | ||||
| 
 | ||||
|             if (json.presets !== undefined) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue