forked from MapComplete/MapComplete
		
	Search: document 'isNormal' in layerconfig; document autofilter-disable option; disable this in favourites, split out the code
This commit is contained in:
		
							parent
							
								
									5479b81066
								
							
						
					
					
						commit
						8239820d04
					
				
					 5 changed files with 102 additions and 69 deletions
				
			
		|  | @ -1,6 +1,7 @@ | ||||||
| { | { | ||||||
|   "#":"no-translations", |   "#":"no-translations", | ||||||
|   "#dont-translate": "*", |   "#dont-translate": "*", | ||||||
|  |   "#filter": "no-auto", | ||||||
|   "pointRendering": [ |   "pointRendering": [ | ||||||
|     { |     { | ||||||
|       "location": [ |       "location": [ | ||||||
|  |  | ||||||
|  | @ -45,6 +45,7 @@ export class GenerateFavouritesLayer extends Script { | ||||||
|         this.addTagRenderings(proto) |         this.addTagRenderings(proto) | ||||||
|         this.addTitle(proto) |         this.addTitle(proto) | ||||||
|         proto.titleIcons = this.generateTitleIcons() |         proto.titleIcons = this.generateTitleIcons() | ||||||
|  |         delete proto.filter | ||||||
|         const targetContent = JSON.stringify(proto, null, "  ") |         const targetContent = JSON.stringify(proto, null, "  ") | ||||||
|         const path = "./assets/layers/favourite/favourite.json" |         const path = "./assets/layers/favourite/favourite.json" | ||||||
|         if (existsSync(path)) { |         if (existsSync(path)) { | ||||||
|  |  | ||||||
|  | @ -30,8 +30,72 @@ import LineRenderingConfigJson from "../Json/LineRenderingConfigJson" | ||||||
| import { ConversionContext } from "./ConversionContext" | import { ConversionContext } from "./ConversionContext" | ||||||
| import { ExpandRewrite } from "./ExpandRewrite" | import { ExpandRewrite } from "./ExpandRewrite" | ||||||
| import { TagUtils } from "../../../Logic/Tags/TagUtils" | import { TagUtils } from "../../../Logic/Tags/TagUtils" | ||||||
| import FilterConfig, { FilterConfigOption } from "../FilterConfig" |  | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class AddFiltersFromTagRenderings extends DesugaringStep<LayerConfigJson> { | ||||||
|  |     constructor() { | ||||||
|  |         super("Inspects all the tagRenderings. If some tagRenderings have the `filter` attribute set, introduce those filters. This step might introduce shorthand filter names, thus 'ExpandFilter' should be run afterwards. Can be disabled with \"#filter\":\"no-auto\"", ["filter"], "AddFiltersFromTagRenderings") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     convert(json: LayerConfigJson, context: ConversionContext): LayerConfigJson { | ||||||
|  |         const noAutoFilters = json["#filter"] === "no-auto" | ||||||
|  |         if(noAutoFilters){ | ||||||
|  |             return json | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(json.filter?.["sameAs"]){ | ||||||
|  |             return json | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const filters: (FilterConfigJson | string)[] = [...<any>json.filter ?? []] | ||||||
|  | 
 | ||||||
|  |         function filterExists(filterName: string): boolean { | ||||||
|  |             return filters.some((existing) => { | ||||||
|  |                 const id: string = existing["id"] ?? existing | ||||||
|  |                 return ( | ||||||
|  |                     filterName === id || | ||||||
|  |                     (filterName.startsWith("filters.") && filterName.endsWith("." + id)) | ||||||
|  |                 ) | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         for (let i = 0; i < json.tagRenderings?.length; i++) { | ||||||
|  |             const tagRendering = <TagRenderingConfigJson>json.tagRenderings[i] | ||||||
|  |             if (!tagRendering?.filter) { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             if (tagRendering.filter === true) { | ||||||
|  |                 if (filterExists(tagRendering["id"])) { | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|  |                 filters.push(ExpandFilter.buildFilterFromTagRendering(tagRendering, context.enters("tagRenderings", i, "filter"))) | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             for (const filterName of tagRendering.filter ?? []) { | ||||||
|  |                 if (typeof filterName !== "string") { | ||||||
|  |                     context.enters("tagRenderings", i, "filter").err("Not a string: " + filterName) | ||||||
|  |                 } | ||||||
|  |                 if (filterExists(filterName)) { | ||||||
|  |                     // This filter has already been added
 | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|  |                 if (!filterName) { | ||||||
|  |                     context.err("Got undefined as filter expansion in " + tagRendering["id"]) | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|  |                 filters.push(filterName) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(filters.length === 0){ | ||||||
|  |             return json | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return { ...json, filter: filters } | ||||||
|  |     } | ||||||
|  | } | ||||||
| class ExpandFilter extends DesugaringStep<LayerConfigJson> { | class ExpandFilter extends DesugaringStep<LayerConfigJson> { | ||||||
|     private static readonly predefinedFilters = ExpandFilter.load_filters() |     private static readonly predefinedFilters = ExpandFilter.load_filters() | ||||||
|     private _state: DesugaringContext |     private _state: DesugaringContext | ||||||
|  | @ -39,9 +103,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> { | ||||||
|     constructor(state: DesugaringContext) { |     constructor(state: DesugaringContext) { | ||||||
|         super( |         super( | ||||||
|             ["Expands filters: replaces a shorthand by the value found in 'filters.json'.", |             ["Expands filters: replaces a shorthand by the value found in 'filters.json'.", | ||||||
|                 "If the string is formatted 'layername.filtername, it will be looked up into that layer instead.", |                 "If the string is formatted 'layername.filtername, it will be looked up into that layer instead."].join(" "), | ||||||
|                 "If a tagRendering sets 'filter', this filter will also be included - unless \"#filter\":\"no-auto\" is set", |  | ||||||
|                 ""].join(" "), |  | ||||||
|             ["filter"], |             ["filter"], | ||||||
|             "ExpandFilter", |             "ExpandFilter", | ||||||
|         ) |         ) | ||||||
|  | @ -56,7 +118,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> { | ||||||
|         return filters |         return filters | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static buildFilterFromTagRendering(tr: TagRenderingConfigJson, context: ConversionContext): FilterConfigJson { |     public static buildFilterFromTagRendering(tr: TagRenderingConfigJson, context: ConversionContext): FilterConfigJson { | ||||||
|         if (!(tr.mappings?.length >= 1)) { |         if (!(tr.mappings?.length >= 1)) { | ||||||
|             context.err( |             context.err( | ||||||
|                 "Found a matching tagRendering to base a filter on, but this tagRendering does not contain any mappings", |                 "Found a matching tagRendering to base a filter on, but this tagRendering does not contain any mappings", | ||||||
|  | @ -97,53 +159,10 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> { | ||||||
|             return json // Nothing to change here
 |             return json // Nothing to change here
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const noAutoFilters = json["#filter"] === "no-auto" |  | ||||||
| 
 | 
 | ||||||
|         const newFilters: FilterConfigJson[] = [] |         const newFilters: FilterConfigJson[] = [] | ||||||
|         const filters = <(FilterConfigJson | string)[]>json.filter |         const filters = <(FilterConfigJson | string)[]>json.filter | ||||||
| 
 | 
 | ||||||
|         function filterExists(filterName: string): boolean { |  | ||||||
|             return filters.some((existing) => { |  | ||||||
|                 const id: string = existing["id"] ?? existing |  | ||||||
|                 return ( |  | ||||||
|                     filterName === id || |  | ||||||
|                     (filterName.startsWith("filters.") && filterName.endsWith("." + id)) |  | ||||||
|                 ) |  | ||||||
|             }) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!noAutoFilters){ |  | ||||||
|             /** |  | ||||||
|              * Checks all tagRendering. If a tagrendering has 'filter' set, add this filter to the layer config |  | ||||||
|              */ |  | ||||||
|             for (let i = 0; i < json.tagRenderings?.length; i++) { |  | ||||||
|                 const tagRendering = <TagRenderingConfigJson>json.tagRenderings[i] |  | ||||||
|                 if (!tagRendering?.filter) { |  | ||||||
|                     continue |  | ||||||
|                 } |  | ||||||
|                 if (tagRendering.filter === true) { |  | ||||||
|                     if (filterExists(tagRendering["id"])) { |  | ||||||
|                         continue |  | ||||||
|                     } |  | ||||||
|                     filters.push(ExpandFilter.buildFilterFromTagRendering(tagRendering, context.enters("tagRenderings", i, "filter"))) |  | ||||||
|                     continue |  | ||||||
|                 } |  | ||||||
|                 for (const filterName of tagRendering.filter ?? []) { |  | ||||||
|                     if (typeof filterName !== "string") { |  | ||||||
|                         context.enters("tagRenderings", i, "filter").err("Not a string: " + filterName) |  | ||||||
|                     } |  | ||||||
|                     if (filterExists(filterName)) { |  | ||||||
|                         // This filter has already been added
 |  | ||||||
|                         continue |  | ||||||
|                     } |  | ||||||
|                     if (!filterName) { |  | ||||||
|                         context.err("Got undefined as filter expansion in " + tagRendering["id"]) |  | ||||||
|                         continue |  | ||||||
|                     } |  | ||||||
|                     filters.push(filterName) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         /** |         /** | ||||||
|          * Create filters based on builtin filters or create them based on the tagRendering |          * Create filters based on builtin filters or create them based on the tagRendering | ||||||
|  | @ -168,28 +187,28 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (filter.indexOf(".") > 0) { |             if (filter.indexOf(".") > 0) { | ||||||
|                 if (this._state.sharedLayers.size > 0) { |                 if (!(this._state.sharedLayers?.size > 0)) { | ||||||
|                     const split = filter.split(".") |  | ||||||
|                     if (split.length > 2) { |  | ||||||
|                         context.err( |  | ||||||
|                             "invalid filter name: " + filter + ", expected `layername.filterid`", |  | ||||||
|                         ) |  | ||||||
|                     } |  | ||||||
|                     const layer = this._state.sharedLayers.get(split[0]) |  | ||||||
|                     if (layer === undefined) { |  | ||||||
|                         context.err("Layer '" + split[0] + "' not found") |  | ||||||
|                     } |  | ||||||
|                     const expectedId = split[1] |  | ||||||
|                     const expandedFilter = (<(FilterConfigJson | string)[]>layer.filter).find( |  | ||||||
|                         (f) => typeof f !== "string" && f.id === expectedId, |  | ||||||
|                     ) |  | ||||||
|                     if (expandedFilter === undefined) { |  | ||||||
|                         context.err("Did not find filter with name " + filter) |  | ||||||
|                     } else { |  | ||||||
|                         newFilters.push(<FilterConfigJson>expandedFilter) |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     // This is a bootstrapping-run, we can safely ignore this
 |                     // This is a bootstrapping-run, we can safely ignore this
 | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|  |                 const split = filter.split(".") | ||||||
|  |                 if (split.length > 2) { | ||||||
|  |                     context.err( | ||||||
|  |                         "invalid filter name: " + filter + ", expected `layername.filterid`", | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 const layer = this._state.sharedLayers.get(split[0]) | ||||||
|  |                 if (layer === undefined) { | ||||||
|  |                     context.err("Layer '" + split[0] + "' not found") | ||||||
|  |                 } | ||||||
|  |                 const expectedId = split[1] | ||||||
|  |                 const expandedFilter = (<(FilterConfigJson | string)[]>layer.filter).find( | ||||||
|  |                     (f) => typeof f !== "string" && f.id === expectedId, | ||||||
|  |                 ) | ||||||
|  |                 if (expandedFilter === undefined) { | ||||||
|  |                     context.err("Did not find filter with name " + filter) | ||||||
|  |                 } else { | ||||||
|  |                     newFilters.push(<FilterConfigJson>expandedFilter) | ||||||
|                 } |                 } | ||||||
|                 continue |                 continue | ||||||
|             } |             } | ||||||
|  | @ -1424,6 +1443,7 @@ export class PrepareLayer extends Fuse<LayerConfigJson> { | ||||||
|                 (layer) => |                 (layer) => | ||||||
|                     new Concat(new ExpandTagRendering(state, layer, { noHardcodedStrings: true })), |                     new Concat(new ExpandTagRendering(state, layer, { noHardcodedStrings: true })), | ||||||
|             ), |             ), | ||||||
|  |             new AddFiltersFromTagRenderings(), | ||||||
|             new ExpandFilter(state), |             new ExpandFilter(state), | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -447,6 +447,10 @@ export interface LayerConfigJson { | ||||||
|      * group: filters |      * group: filters | ||||||
|      */ |      */ | ||||||
|     filter?: (FilterConfigJson | string)[] | { sameAs: string } |     filter?: (FilterConfigJson | string)[] | { sameAs: string } | ||||||
|  |     /** | ||||||
|  |      * Set this to disable the feature that tagRenderings can introduce filters | ||||||
|  |      */ | ||||||
|  |     "#filter"?: "no-auto" | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * This block defines under what circumstances the delete dialog is shown for objects of this layer. |      * This block defines under what circumstances the delete dialog is shown for objects of this layer. | ||||||
|  |  | ||||||
|  | @ -642,6 +642,10 @@ export default class LayerConfig extends WithContextLoader { | ||||||
|         return mostShadowed ?? matchingPresets[0] |         return mostShadowed ?? matchingPresets[0] | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Indicates if this is a normal layer, meaning that it can be toggled by the user in normal circumstances | ||||||
|  |      * Thus: name is set, not a note import layer, not synced with another filter, ... | ||||||
|  |      */ | ||||||
|     public isNormal(){ |     public isNormal(){ | ||||||
|         if(this.id.startsWith("note_import")){ |         if(this.id.startsWith("note_import")){ | ||||||
|             return false |             return false | ||||||
|  | @ -653,6 +657,9 @@ export default class LayerConfig extends WithContextLoader { | ||||||
|         if(this.filterIsSameAs !== undefined){ |         if(this.filterIsSameAs !== undefined){ | ||||||
|             return false |             return false | ||||||
|         } |         } | ||||||
|  |         if(!this.name ){ | ||||||
|  |             return false | ||||||
|  |         } | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue