forked from MapComplete/MapComplete
		
	Merge branches
This commit is contained in:
		
						commit
						bae90d50bc
					
				
					 304 changed files with 49983 additions and 31589 deletions
				
			
		|  | @ -258,11 +258,11 @@ export class ExpandRewrite<T> extends Conversion<T | RewritableConfigJson<T>, T[ | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let renderings = Array.isArray(rewrite.renderings) | ||||
|         const renderings = Array.isArray(rewrite.renderings) | ||||
|             ? rewrite.renderings | ||||
|             : [rewrite.renderings] | ||||
|         for (let i = 0; i < keysToRewrite.into.length; i++) { | ||||
|             let ts: T[] = <T[]>Utils.Clone(renderings) | ||||
|             const ts: T[] = <T[]>Utils.Clone(renderings) | ||||
|             for (const tx of ts) { | ||||
|                 let t = <T>tx | ||||
|                 const sourceKeysToIgnore: string[] = [] | ||||
|  |  | |||
|  | @ -161,7 +161,9 @@ class ExpandTagRendering extends Conversion< | |||
|     private readonly _options: { | ||||
|         /* If true, will copy the 'osmSource'-tags into the condition */ | ||||
|         applyCondition?: true | boolean | ||||
|         noHardcodedStrings?: false | boolean | ||||
|         noHardcodedStrings?: false | boolean, | ||||
|         addToContext?: false | boolean | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     constructor( | ||||
|  | @ -169,11 +171,13 @@ class ExpandTagRendering extends Conversion< | |||
|         self: LayerConfigJson, | ||||
|         options?: { | ||||
|             applyCondition?: true | boolean | ||||
|             noHardcodedStrings?: false | boolean | ||||
|             noHardcodedStrings?: false | boolean, | ||||
|             // If set, a question will be added to the 'sharedTagRenderings'. Should only be used for 'questions.json'
 | ||||
|             addToContext?: false | boolean | ||||
|         } | ||||
|     ) { | ||||
|         super( | ||||
|             "Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question", | ||||
|             "Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins", | ||||
|             [], | ||||
|             "ExpandTagRendering" | ||||
|         ) | ||||
|  | @ -204,8 +208,17 @@ class ExpandTagRendering extends Conversion< | |||
|             if (typeof tr === "string" || tr["builtin"] !== undefined) { | ||||
|                 const stable = this.convert(tr, ctx.inOperation("recursive_resolve")) | ||||
|                 result.push(...stable) | ||||
|                 if(this._options?.addToContext){ | ||||
|                     for (const tr of stable) { | ||||
|                         this._state.tagRenderings?.set(tr.id, tr) | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 result.push(tr) | ||||
|                 if(this._options?.addToContext){ | ||||
|                     this._state.tagRenderings?.set(tr["id"], <QuestionableTagRenderingConfigJson> tr) | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -220,7 +233,7 @@ class ExpandTagRendering extends Conversion< | |||
|         } | ||||
|         const result: TagRenderingConfigJson[] = [] | ||||
|         for (const tagRenderingConfigJson of direct) { | ||||
|             let nm: string | string[] | undefined = tagRenderingConfigJson["builtin"] | ||||
|             const nm: string | string[] | undefined = tagRenderingConfigJson["builtin"] | ||||
|             if (nm !== undefined) { | ||||
|                 let indirect: TagRenderingConfigJson[] | ||||
|                 if (typeof nm === "string") { | ||||
|  | @ -1261,12 +1274,14 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> { | |||
| } | ||||
| 
 | ||||
| export class PrepareLayer extends Fuse<LayerConfigJson> { | ||||
|     constructor(state: DesugaringContext) { | ||||
|     constructor(state: DesugaringContext, options?: {addTagRenderingsToContext?: false | boolean}) { | ||||
|         super( | ||||
|             "Fully prepares and expands a layer for the LayerConfig.", | ||||
|             new On("tagRenderings", new Each(new RewriteSpecial())), | ||||
|             new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), | ||||
|             new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))), | ||||
|             new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer, { | ||||
|                 addToContext: options?.addTagRenderingsToContext ?? false | ||||
|             }))), | ||||
|             new On("tagRenderings", new Each(new DetectInline())), | ||||
|             new AddQuestionBox(), | ||||
|             new AddEditingElements(state), | ||||
|  |  | |||
|  | @ -562,6 +562,65 @@ export class DetectNonErasedKeysInMappings extends DesugaringStep<QuestionableTa | |||
|     } | ||||
| } | ||||
| 
 | ||||
| export class DetectMappingsShadowedByCondition extends DesugaringStep<TagRenderingConfigJson> { | ||||
|     private readonly _forceError: boolean | ||||
| 
 | ||||
|     constructor(forceError: boolean = false) { | ||||
|         super("Checks that, if the tagrendering has a condition, that a mapping is not contradictory to it, i.e. that there are no dead mappings", [], "DetectMappingsShadowedByCondition") | ||||
|         this._forceError = forceError | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * const validator = new DetectMappingsShadowedByCondition(true) | ||||
|      * const ctx = ConversionContext.construct([],["test"]) | ||||
|      * validator.convert({ | ||||
|      *     condition: "count>0", | ||||
|      *     mappings:[ | ||||
|      *         { | ||||
|      *             if: "count=0", | ||||
|      *             then:{ | ||||
|      *                 en: "No count" | ||||
|      *             } | ||||
|      *         } | ||||
|      *     ] | ||||
|      * }, ctx) | ||||
|      * ctx.hasErrors() // => true
 | ||||
|      */ | ||||
|     convert(json: TagRenderingConfigJson, context: ConversionContext): TagRenderingConfigJson { | ||||
|         if(!json.condition && !json.metacondition){ | ||||
|             return json | ||||
|         } | ||||
|         if(!json.mappings || json.mappings?.length ==0){ | ||||
|             return json | ||||
|         } | ||||
|         let conditionJson = json.condition ?? json.metacondition | ||||
|         if(json.condition !== undefined && json.metacondition !== undefined){ | ||||
|             conditionJson = {and: [json.condition, json.metacondition]} | ||||
|         } | ||||
|         const condition = TagUtils.Tag(conditionJson, context.path.join(".")) | ||||
| 
 | ||||
|         for (let i = 0; i < json.mappings.length; i++){ | ||||
|             const mapping = json.mappings[i] | ||||
|             const tagIf = TagUtils.Tag(mapping.if, context.path.join(".")) | ||||
|             const optimized = new And([tagIf, condition]).optimize() | ||||
|             if(optimized === false){ | ||||
|                 const msg = ("Detected a conflicting mapping and condition. The mapping requires tags " + tagIf.asHumanString() + ", yet this can never happen because the set condition requires " + condition.asHumanString()) | ||||
|                 const ctx = context.enters("mappings", i) | ||||
|                 if (this._forceError) { | ||||
|                     ctx.err(msg) | ||||
|                 } else { | ||||
|                     ctx.warn(msg) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return undefined | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> { | ||||
|     private readonly _calculatedTagNames: string[] | ||||
| 
 | ||||
|  | @ -1088,6 +1147,8 @@ export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> { | |||
|             "Various validation on tagRenderingConfigs", | ||||
|             new MiscTagRenderingChecks(), | ||||
|             new DetectShadowedMappings(layerConfig), | ||||
| 
 | ||||
|             new DetectMappingsShadowedByCondition(), | ||||
|             new DetectConflictingAddExtraTags(), | ||||
|             // TODO enable   new DetectNonErasedKeysInMappings(),
 | ||||
|             new DetectMappingsWithImages(doesImageExist), | ||||
|  |  | |||
|  | @ -554,4 +554,15 @@ export interface LayerConfigJson { | |||
|      * group: hidden | ||||
|      */ | ||||
|     fullNodeDatabase?: boolean | ||||
| 
 | ||||
|     /** | ||||
|      * question: Should a theme using this layer leak some location info when making changes? | ||||
|      * | ||||
|      * When a changeset is made, a 'distance to object'-class is written to the changeset. | ||||
|      * For some particular themes and layers, this might leak too much information, and we want to obfuscate this | ||||
|      * | ||||
|      * ifunset: Write 'change_within_x_m' as usual and if GPS is enabled | ||||
|      * iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey | ||||
|      */ | ||||
|     enableMorePrivacy?: boolean | ||||
| } | ||||
|  |  | |||
|  | @ -439,4 +439,16 @@ export interface LayoutConfigJson { | |||
|      * group: hidden | ||||
|      */ | ||||
|     enableNodeDatabase?: boolean | ||||
| 
 | ||||
|     /** | ||||
|      * question: Should this theme leak some location info when making changes? | ||||
|      * | ||||
|      * When a changeset is made, a 'distance to object'-class is written to the changeset. | ||||
|      * For some particular themes and layers, this might leak too much information, and we want to obfuscate this | ||||
|      * | ||||
|      * ifunset: Write 'change_within_x_m' as usual and if GPS is enabled | ||||
|      * iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey | ||||
|      */ | ||||
|     enableMorePrivacy: boolean | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -229,6 +229,7 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs | |||
|          * A (translated) text that is shown (as gray text) within the textfield | ||||
|          * type: translation | ||||
|          * group: expert | ||||
|          * ifunset: No specific placeholder is set, show the type of the textfield | ||||
|          */ | ||||
|         placeholder?: Translatable | ||||
| 
 | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ export interface TagRenderingConfigJson { | |||
|      * | ||||
|      * question: When should this item be shown? | ||||
|      * type: tag | ||||
|      * ifunset: No specific condition set; always show this tagRendering or ask the question if unkown | ||||
|      * ifunset: No specific condition set; always show this tagRendering or show this question if unknown | ||||
|      * | ||||
|      * Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`. | ||||
|      * | ||||
|  | @ -132,9 +132,10 @@ export interface TagRenderingConfigJson { | |||
| 
 | ||||
|     /** question: When should this item be shown (including special conditions)? | ||||
|      * type: tag | ||||
|      * ifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown | ||||
|      * | ||||
|      * If set, this tag will be evaluated agains the _usersettings/application state_ table. | ||||
|      * Enable 'show debug info' in user settings to see available options. | ||||
|      * If set, this tag will be evaluated against the _usersettings/application state_ table. | ||||
|      * Enable 'show debug info' in user settings to see available options (at the settings-tab). | ||||
|      * Note that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_ | ||||
|      */ | ||||
|     metacondition?: TagConfigJson | ||||
|  |  | |||
|  | @ -67,6 +67,7 @@ export default class LayerConfig extends WithContextLoader { | |||
| 
 | ||||
|     public readonly _needsFullNodeDatabase: boolean | ||||
|     public readonly popupInFloatover: boolean | string | ||||
|     public readonly enableMorePrivacy: boolean | ||||
| 
 | ||||
|     constructor(json: LayerConfigJson, context?: string, official: boolean = true) { | ||||
|         context = context + "." + json.id | ||||
|  | @ -149,6 +150,7 @@ export default class LayerConfig extends WithContextLoader { | |||
|         this.shownByDefault = json.shownByDefault ?? true | ||||
|         this.doCount = json.isCounted ?? this.shownByDefault ?? true | ||||
|         this.forceLoad = json.forceLoad ?? false | ||||
|         this.enableMorePrivacy = json.enableMorePrivacy ?? false | ||||
|         if (json.presets === null) json.presets = undefined | ||||
|         if (json.presets !== undefined && json.presets?.map === undefined) { | ||||
|             throw "Presets should be a list of items (at " + context + ")" | ||||
|  |  | |||
|  | @ -63,6 +63,8 @@ export default class LayoutConfig implements LayoutInformation { | |||
|     public readonly enableExportButton: boolean | ||||
|     public readonly enablePdfDownload: boolean | ||||
|     public readonly enableTerrain: boolean | ||||
|     public readonly enableMorePrivacy: boolean | ||||
| 
 | ||||
| 
 | ||||
|     public readonly customCss?: string | ||||
| 
 | ||||
|  | @ -204,6 +206,7 @@ export default class LayoutConfig implements LayoutInformation { | |||
|         this.overpassTimeout = json.overpassTimeout ?? 30 | ||||
|         this.overpassMaxZoom = json.overpassMaxZoom ?? 16 | ||||
|         this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1 | ||||
|         this.enableMorePrivacy = json.enableMorePrivacy || json.layers.some(l => (<LayerConfigJson> l).enableMorePrivacy) | ||||
| 
 | ||||
|         this.layersDict = new Map<string, LayerConfig>() | ||||
|         for (const layer of this.layers) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue