diff options
Diffstat (limited to 'browser/components/search/schema')
3 files changed, 447 insertions, 0 deletions
diff --git a/browser/components/search/schema/Readme.txt b/browser/components/search/schema/Readme.txt new file mode 100644 index 0000000000..14fffb5c10 --- /dev/null +++ b/browser/components/search/schema/Readme.txt @@ -0,0 +1,7 @@ +The schemas in this directory are the primary source for the schemas they represent. + +They are uploaded to the RemoteSettings server to validate new configurations. + +Any changes should be validated by the Search team. + +See the documentation for more information: https://firefox-source-docs.mozilla.org/ diff --git a/browser/components/search/schema/search-telemetry-schema.json b/browser/components/search/schema/search-telemetry-schema.json new file mode 100644 index 0000000000..b985ae0802 --- /dev/null +++ b/browser/components/search/schema/search-telemetry-schema.json @@ -0,0 +1,417 @@ +{ + "type": "object", + "required": [ + "telemetryId", + "searchPageRegexp", + "queryParamName", + "queryParamNames" + ], + "properties": { + "telemetryId": { + "type": "string", + "title": "Telemetry Id", + "description": "The telemetry identifier for the provider.", + "pattern": "^[a-z0-9-._]*$" + }, + "searchPageMatches": { + "type": "array", + "title": "Search Page Matches", + "description": "An array containing match expressions used to match on URLs.", + "items": { + "type": "string" + } + }, + "searchPageRegexp": { + "type": "string", + "title": "Search Page Regular Expression", + "description": "A regular expression which matches the search page of the provider." + }, + "queryParamName": { + "type": "string", + "title": "Search Query Parameter Name", + "description": "The name of the query parameter for the user's search string. This is deprecated, in preference to queryParamNames, but still defined for older clients (pre Firefox 121)." + }, + "queryParamNames": { + "type": "array", + "title": "Search Query Parameter Names", + "description": "An array of query parameters that may be used for the user's search string.", + "items": { + "type": "string" + } + }, + "codeParamName": { + "type": "string", + "title": "Partner Code Parameter Name", + "description": "The name of the query parameter for the partner code." + }, + "taggedCodes": { + "type": "array", + "title": "Partner Codes", + "description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as tagged.", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9-._]*$" + } + }, + "expectedOrganicCodes": { + "type": "array", + "title": "Expected Organic Codes", + "description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as organic:none which means the user has done a search through the search engine's website rather than through SAP.", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9-._]*$" + } + }, + "organicCodes": { + "type": "array", + "title": "Organic Codes", + "description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as organic:<partner code>, which means the search was performed organically rather than through a SAP.", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9-._]*$" + } + }, + "followOnParamNames": { + "type": "array", + "title": "Follow-on Search Parameter Names", + "description": "An array of query parameter names that are used when a follow-on search occurs.", + "items": { + "type": "string", + "pattern": "^[a-z0-9-._]*$" + } + }, + "followOnCookies": { + "type": "array", + "title": "Follow-on Cookies", + "description": "An array of cookie details that are used to identify follow-on searches.", + "items": { + "type": "object", + "properties": { + "extraCodeParamName": { + "type": "string", + "description": "The query parameter name in the URL that indicates this might be a follow-on search.", + "pattern": "^[a-z0-9-._]*$" + }, + "extraCodePrefixes": { + "type": "array", + "description": "Possible values for the query parameter in the URL that indicates this might be a follow-on search.", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9-._]*$" + } + }, + "host": { + "type": "string", + "description": "The hostname on which the cookie is stored.", + "pattern": "^[a-z0-9-._]*$" + }, + "name": { + "type": "string", + "description": "The name of the cookie to check.", + "pattern": "^[a-zA-Z0-9-._]*$" + }, + "codeParamName": { + "type": "string", + "description": "The name of parameter within the cookie.", + "pattern": "^[a-zA-Z0-9-._]*$" + } + } + } + }, + "extraAdServersRegexps": { + "type": "array", + "title": "Extra Ad Server Regular Expressions", + "description": "An array of regular expressions that match URLs of potential ad servers.", + "items": { + "type": "string" + } + }, + "adServerAttributes": { + "type": "array", + "title": "Ad Server Attributes", + "description": "An array of strings that potentially match data-attribute keys of anchors.", + "items": { + "type": "string" + } + }, + "components": { + "type": "array", + "title": "Components", + "description": "An array of components that could be on the SERP.", + "items": { + "required": ["type"], + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "The type of component the anchor or DOM element should belong to.", + "pattern": "^[a-z](?:_?[a-z])*$" + }, + "included": { + "type": "object", + "description": "Conditions that should be fulfilled.", + "properties": { + "parent": { + "title": "Parent", + "description": "The DOM element that should only contain elements applicable to a single component type.", + "type": "object", + "properties": { + "selector": { + "description": "If topDown is true for this component, then this will be the value used in querySelectorAll(). Otherwise, it will be the value to in closest() from the context of an anchor.", + "type": "string" + }, + "eventListeners": { + "$ref": "#/definitions/eventListeners" + }, + "skipCount": { + "$ref": "#/definitions/skipCount" + } + }, + "required": ["selector"] + }, + "children": { + "type": "array", + "title": "Children", + "description": "Child DOM elements of the parent. Optional.", + "items": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "The selector to use querySelectorAll from the context of the parent." + }, + "type": { + "type": "string", + "description": "The component type to use if this child is present.", + "pattern": "^[a-z](?:_?[a-z])*$" + }, + "countChildren": { + "type": "boolean", + "description": "Whether we should count all instances of the child element instead of anchor links found inside of the parent. Defaults to false." + }, + "eventListeners": { + "$ref": "#/definitions/eventListeners" + }, + "skipCount": { + "$ref": "#/definitions/skipCount" + } + }, + "required": ["selector"] + } + }, + "related": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "The selector to use querySelectorAll from the context of the parent. Any elements specified will have their click events registered and categorized as expanded unless explicitly overwritten in SearchSERPTelemetryChild." + } + }, + "required": ["selector"] + } + }, + "required": ["parent"] + }, + "excluded": { + "type": "object", + "description": "Conditions that should not be included.", + "properties": { + "parent": { + "type": "object", + "properties": { + "selector": { + "type": "string", + "description": "The root DOM element that shouldn't be a parent from the context of the anchor being inspected." + } + }, + "required": ["selector"] + } + } + }, + "default": { + "type": "boolean", + "description": "Whether this component should be the fallback option if a link was included in both ad-related regular expressions as well as regular expressions matching non-ad elements but couldn't be categorized. Defaults to false." + }, + "topDown": { + "type": "boolean", + "description": "Whether the component should be found first by using document.querySelectorAll on the parent selector definition. Defaults to false." + }, + "dependentRequired": { + "topDown": ["included"] + } + } + } + }, + "ignoreLinkRegexps": { + "type": "array", + "title": "Ignore links matching regular expressions", + "description": "Regular expressions matching links that should be ignored by the network observer.", + "items": { + "type": "string", + "description": "The matching regular expression." + } + }, + "nonAdsLinkRegexps": { + "type": "array", + "title": "Non-ads link matching regular expressions", + "description": "An array containing known patterns that match non-ad links from a search provider.", + "items": { + "type": "string", + "description": "The matching regular expression." + } + }, + "shoppingTab": { + "type": "object", + "title": "Shopping Tab", + "properties": { + "selector": { + "type": "string", + "description": "The elements on the page to inspect for the shopping tab. Should be anchor elements." + }, + "regexp": { + "type": "string", + "description": "The regular expression to match against a possible shopping tab. Must be provided if using this feature." + }, + "inspectRegexpInSERP": { + "type": "boolean", + "description": "Whether the regexp should be used against hrefs the selector matches against." + } + }, + "required": ["selector", "regexp"] + }, + "domainExtraction": { + "type": "object", + "title": "Domain Extraction", + "description": "An array of methods for extracting domains from a SERP result.", + "properties": { + "ads": { + "type": "array", + "description": "An array of methods for extracting domains from ads.", + "items": { + "$ref": "#/definitions/extraction" + } + }, + "nonAds": { + "type": "array", + "description": "An array of methods for extracting domains from non-ads.", + "items": { + "$ref": "#/definitions/extraction" + } + } + } + }, + "isSPA": { + "type": "boolean", + "title": "Is Single Page App", + "description": "Whether the provider exhibits tendencies of a single page app, namely changes the entire contents of the page without having to reload." + }, + "defaultPageQueryParam": { + "type": "object", + "title": "Default page query parameter", + "properties": { + "key": { + "type": "string", + "description": "The key corresponding to the query parameter that contains what type of search page is being shown." + }, + "value": { + "type": "string", + "description": "The value corresponding to the query parameter that should be matched against." + } + }, + "required": ["key", "value"] + } + }, + "definitions": { + "eventListener": { + "title": "Event Listener", + "type": "object", + "description": "Event listeners attached to a component.", + "properties": { + "eventType": { + "title": "Event Type", + "description": "The type of event to listen for. Custom events, especially those with special logic like keydownEnter, can be used if the Desktop code has been updated.", + "type": "string", + "pattern": "^[a-z][A-Za-z]*$" + }, + "target": { + "title": "Target", + "description": "The component type to report when the event is triggered. Uses the child component type (if exists), otherwise uses the parent component type.", + "type": "string", + "pattern": "^[a-z](?:_?[a-z])*$" + }, + "action": { + "title": "Action", + "description": "The action to report when the event is triggered. If the event type is 'click', defaults to clicked. Otherwise, this should be provided.", + "type": "string", + "pattern": "^[a-z](?:_?[a-z])*$" + } + }, + "required": ["eventType"] + }, + "eventListeners": { + "title": "Event Listeners", + "description": "An array of Event Listeners to apply to elements.", + "type": "array", + "items": { + "$ref": "#/definitions/eventListener" + } + }, + "extraction": { + "anyOf": [ + { + "type": "object", + "properties": { + "selectors": { + "type": "string", + "description": "The query to inspect all elements on the SERP." + }, + "method": { + "enum": ["data-attribute"], + "description": "The extraction method used for the query." + }, + "options": { + "type": "object", + "properties": { + "dataAttributeKey": { + "type": "string", + "description": "The data attribute key that will be looked up in order to retrieve its data attribute value." + } + }, + "required": ["dataAttributeKey"] + } + }, + "required": ["selectors", "method", "options"] + }, + { + "type": "object", + "properties": { + "selectors": { + "type": "string", + "description": "The query to use to inspect all elements on the SERP." + }, + "method": { + "enum": ["href"], + "description": "The extraction method to use for the query." + }, + "options": { + "type": "object", + "properties": { + "queryParamKey": { + "type": "string", + "description": "The query parameter key to inspect in the href." + } + }, + "required": ["queryParamKey"] + } + }, + "required": ["selectors", "method"] + } + ] + } + }, + "skipCount": { + "title": "Skip Count", + "description": "Whether to skip reporting of the count of these elements to ad_impressions. Defaults to false.", + "type": "boolean" + } +} diff --git a/browser/components/search/schema/search-telemetry-ui-schema.json b/browser/components/search/schema/search-telemetry-ui-schema.json new file mode 100644 index 0000000000..781da5a626 --- /dev/null +++ b/browser/components/search/schema/search-telemetry-ui-schema.json @@ -0,0 +1,23 @@ +{ + "ui:order": [ + "telemetryId", + "searchPageMatches", + "searchPageRegexp", + "queryParamNames", + "queryParamName", + "codeParamName", + "taggedCodes", + "expectedOrganicCodes", + "organicCodes", + "followOnParamNames", + "followOnCookies", + "extraAdServersRegexps", + "adServerAttributes", + "components", + "nonAdsLinkRegexps", + "shoppingTab", + "domainExtraction", + "isSPA", + "defaultPageQueryParam" + ] +} |