From abde015288584b0f4eaa2dd1cb12418c2cba9d49 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 10 Dec 2020 15:15:37 -0500 Subject: [PATCH] Allow validation severity to be overridden with url params --- API.md | 8 ++++- modules/core/validator.js | 66 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/API.md b/API.md index 097942a41..8b990cb90 100644 --- a/API.md +++ b/API.md @@ -55,6 +55,12 @@ of iD (e.g. `https://ideditor-release.netlify.app`), the following parameters ar * __`rtl=true`__ - Force iD into right-to-left mode (useful for testing). * __`source`__ - Prefills the changeset source. Pass a url encoded string.
_Example:_ `source=Bing%3BMapillary` +* __`validationDisable`__ - The issues identified by these types/subtypes will be disabled (i.e. Issues will not be shown at all). Each parameter value should contain a urlencoded, comma-separated list of type/subtype match rules. An asterisk `*` may be used as a wildcard.
+ _Example:_ `validationDisable=crossing_ways/highway*,crossing_ways/tunnel*` +* __`validationWarning`__ - The issues identified by these types/subtypes will be treated as warnings (i.e. Issues will be surfaced to the user but not block changeset upload). Each parameter value should contain a urlencoded, comma-separated list of type/subtype match rules. An asterisk `*` may be used as a wildcard.
+ _Example:_ `validationWarning=crossing_ways/highway*,crossing_ways/tunnel*` +* __`validationError`__ - The issues identified by these types/subtypes will be treated as errors (i.e. Issues will be surfaced to the user but will block changeset upload). Each parameter value should contain a urlencoded, comma-separated list of type/subtype match rules. An asterisk `*` may be used as a wildcard.
+ _Example:_ `validationError=crossing_ways/highway*,crossing_ways/tunnel*` * __`walkthrough=true`__ - Start the walkthrough automatically ##### iD on openstreetmap.org (Rails Port) @@ -377,4 +383,4 @@ A "name" field must be included: "label": "Name", "placeholder": "Common name (if any)" } -``` +``` \ No newline at end of file diff --git a/modules/core/validator.js b/modules/core/validator.js index e546ae606..0a7446872 100644 --- a/modules/core/validator.js +++ b/modules/core/validator.js @@ -21,6 +21,41 @@ export function coreValidator(context) { var _validatedGraph = null; var _deferred = new Set(); + // Allow validation severity to be overridden by url queryparams... + // Each param should contain a urlencoded comma separated list of + // `type/subtype` rules. `*` may be used as a wildcard.. + // Examples: + // `validationError=disconnected_way/*` + // `validationError=disconnected_way/highway` + // `validationError=crossing_ways/bridge*` + // `validationError=crossing_ways/bridge*,crossing_ways/tunnel*` + + var _errorOverrides = parseHashParam(context.initialHashParams.validationError); + var _warningOverrides = parseHashParam(context.initialHashParams.validationWarning); + var _disableOverrides = parseHashParam(context.initialHashParams.validationDisable); + + function parseHashParam(param) { + var result = []; + var rules = (param || '').split(','); + rules.forEach(function(rule) { + rule = rule.trim(); + var parts = rule.split('/', 2); // "type/subtype" + var type = parts[0]; + var subtype = parts[1] || '*'; + if (!type || !subtype) return; + + result.push({ type: makeRegExp(type), subtype: makeRegExp(subtype) }); + }); + return result; + } + + function makeRegExp(str) { + var escaped = str + .replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&') // escape all reserved chars except for the '*' + .replace(/\*/g, '.*'); // treat a '*' like '.*' + return new RegExp('^' + escaped + '$'); + } + // // initialize the validator rulesets // @@ -296,7 +331,7 @@ export function coreValidator(context) { return; } - var detected = fn(entity, graph); + var detected = fn(entity, graph).filter(applySeverityOverrides); entityIssues = entityIssues.concat(detected); } @@ -306,6 +341,35 @@ export function coreValidator(context) { return entityIssues; } + + // If there are any override rules that match the issue type/subtype, + // adjust severity (or disable it) and keep/discard as quickly as possible. + function applySeverityOverrides(issue) { + var type = issue.type; + var subtype = issue.subtype || ''; + var i; + + for (i = 0; i < _errorOverrides.length; i++) { + if (_errorOverrides[i].type.test(type) && _errorOverrides[i].subtype.test(subtype)) { + issue.severity = 'error'; + return true; + } + } + for (i = 0; i < _warningOverrides.length; i++) { + if (_warningOverrides[i].type.test(type) && _warningOverrides[i].subtype.test(subtype)) { + issue.severity = 'warning'; + return true; + } + } + for (i = 0; i < _disableOverrides.length; i++) { + if (_disableOverrides[i].type.test(type) && _disableOverrides[i].subtype.test(subtype)) { + return false; + } + } + return true; + } + + function entityIDsToValidate(entityIDs, graph) { var processedIDs = new Set(); return entityIDs.reduce(function(acc, entityID) {