Replace hasOwnProperty with simplified hasOwn function

This commit is contained in:
toasted-nutbread 2019-11-25 14:19:18 -05:00
parent 663667306c
commit 0aed27b66d
21 changed files with 63 additions and 59 deletions

View File

@ -45,7 +45,7 @@ async function apiOptionsSet(changedOptions, optionsContext, source) {
function modifyOption(path, value, options) { function modifyOption(path, value, options) {
let pivot = options; let pivot = options;
for (const key of path.slice(0, -1)) { for (const key of path.slice(0, -1)) {
if (!pivot.hasOwnProperty(key)) { if (!hasOwn(pivot, key)) {
return false; return false;
} }
pivot = pivot[key]; pivot = pivot[key];
@ -236,7 +236,7 @@ async function apiTemplateRender(template, data, dynamic) {
async function apiCommandExec(command, params) { async function apiCommandExec(command, params) {
const handlers = apiCommandExec.handlers; const handlers = apiCommandExec.handlers;
if (handlers.hasOwnProperty(command)) { if (hasOwn(handlers, command)) {
const handler = handlers[command]; const handler = handlers[command];
handler(params); handler(params);
} }

View File

@ -107,12 +107,12 @@ const audioUrlBuilders = {
'custom': async (definition, optionsContext) => { 'custom': async (definition, optionsContext) => {
const options = await apiOptionsGet(optionsContext); const options = await apiOptionsGet(optionsContext);
const customSourceUrl = options.audio.customSourceUrl; const customSourceUrl = options.audio.customSourceUrl;
return customSourceUrl.replace(/\{([^\}]*)\}/g, (m0, m1) => (definition.hasOwnProperty(m1) ? `${definition[m1]}` : m0)); return customSourceUrl.replace(/\{([^\}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0));
} }
}; };
async function audioGetUrl(definition, mode, optionsContext, download) { async function audioGetUrl(definition, mode, optionsContext, download) {
if (audioUrlBuilders.hasOwnProperty(mode)) { if (hasOwn(audioUrlBuilders, mode)) {
const handler = audioUrlBuilders[mode]; const handler = audioUrlBuilders[mode];
try { try {
return await handler(definition, optionsContext, download); return await handler(definition, optionsContext, download);
@ -171,7 +171,7 @@ async function audioInject(definition, fields, sources, optionsContext) {
try { try {
let audioSourceDefinition = definition; let audioSourceDefinition = definition;
if (definition.hasOwnProperty('expressions')) { if (hasOwn(definition, 'expressions')) {
audioSourceDefinition = definition.expressions[0]; audioSourceDefinition = definition.expressions[0];
} }

View File

@ -73,7 +73,7 @@ class Backend {
onMessage({action, params}, sender, callback) { onMessage({action, params}, sender, callback) {
const handlers = Backend.messageHandlers; const handlers = Backend.messageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
const promise = handler(params, sender); const promise = handler(params, sender);
promise.then( promise.then(

View File

@ -84,7 +84,7 @@ ConditionsUI.Container = class Container {
createDefaultCondition(type) { createDefaultCondition(type) {
let operator = ''; let operator = '';
let value = ''; let value = '';
if (this.conditionDescriptors.hasOwnProperty(type)) { if (hasOwn(this.conditionDescriptors, type)) {
const conditionDescriptor = this.conditionDescriptors[type]; const conditionDescriptor = this.conditionDescriptors[type];
operator = conditionDescriptor.defaultOperator; operator = conditionDescriptor.defaultOperator;
({value} = this.getOperatorDefaultValue(type, operator)); ({value} = this.getOperatorDefaultValue(type, operator));
@ -96,15 +96,15 @@ ConditionsUI.Container = class Container {
} }
getOperatorDefaultValue(type, operator) { getOperatorDefaultValue(type, operator) {
if (this.conditionDescriptors.hasOwnProperty(type)) { if (hasOwn(this.conditionDescriptors, type)) {
const conditionDescriptor = this.conditionDescriptors[type]; const conditionDescriptor = this.conditionDescriptors[type];
if (conditionDescriptor.operators.hasOwnProperty(operator)) { if (hasOwn(conditionDescriptor.operators, operator)) {
const operatorDescriptor = conditionDescriptor.operators[operator]; const operatorDescriptor = conditionDescriptor.operators[operator];
if (operatorDescriptor.hasOwnProperty('defaultValue')) { if (hasOwn(operatorDescriptor, 'defaultValue')) {
return {value: operatorDescriptor.defaultValue, fromOperator: true}; return {value: operatorDescriptor.defaultValue, fromOperator: true};
} }
} }
if (conditionDescriptor.hasOwnProperty('defaultValue')) { if (hasOwn(conditionDescriptor, 'defaultValue')) {
return {value: conditionDescriptor.defaultValue, fromOperator: false}; return {value: conditionDescriptor.defaultValue, fromOperator: false};
} }
} }
@ -219,7 +219,7 @@ ConditionsUI.Condition = class Condition {
optionGroup.empty(); optionGroup.empty();
const type = this.condition.type; const type = this.condition.type;
if (conditionDescriptors.hasOwnProperty(type)) { if (hasOwn(conditionDescriptors, type)) {
const conditionDescriptor = conditionDescriptors[type]; const conditionDescriptor = conditionDescriptors[type];
const operators = conditionDescriptor.operators; const operators = conditionDescriptor.operators;
for (const operatorName of Object.keys(operators)) { for (const operatorName of Object.keys(operators)) {
@ -240,23 +240,23 @@ ConditionsUI.Condition = class Condition {
}; };
const objects = []; const objects = [];
if (conditionDescriptors.hasOwnProperty(type)) { if (hasOwn(conditionDescriptors, type)) {
const conditionDescriptor = conditionDescriptors[type]; const conditionDescriptor = conditionDescriptors[type];
objects.push(conditionDescriptor); objects.push(conditionDescriptor);
if (conditionDescriptor.operators.hasOwnProperty(operator)) { if (hasOwn(conditionDescriptor.operators, operator)) {
const operatorDescriptor = conditionDescriptor.operators[operator]; const operatorDescriptor = conditionDescriptor.operators[operator];
objects.push(operatorDescriptor); objects.push(operatorDescriptor);
} }
} }
for (const object of objects) { for (const object of objects) {
if (object.hasOwnProperty('placeholder')) { if (hasOwn(object, 'placeholder')) {
props.placeholder = object.placeholder; props.placeholder = object.placeholder;
} }
if (object.type === 'number') { if (object.type === 'number') {
props.type = 'number'; props.type = 'number';
for (const prop of ['step', 'min', 'max']) { for (const prop of ['step', 'min', 'max']) {
if (object.hasOwnProperty(prop)) { if (hasOwn(object, prop)) {
props[prop] = object[prop]; props[prop] = object[prop];
} }
} }

View File

@ -18,14 +18,14 @@
function conditionsValidateOptionValue(object, value) { function conditionsValidateOptionValue(object, value) {
if (object.hasOwnProperty('validate') && !object.validate(value)) { if (hasOwn(object, 'validate') && !object.validate(value)) {
throw new Error('Invalid value for condition'); throw new Error('Invalid value for condition');
} }
if (object.hasOwnProperty('transform')) { if (hasOwn(object, 'transform')) {
value = object.transform(value); value = object.transform(value);
if (object.hasOwnProperty('validateTransformed') && !object.validateTransformed(value)) { if (hasOwn(object, 'validateTransformed') && !object.validateTransformed(value)) {
throw new Error('Invalid value for condition'); throw new Error('Invalid value for condition');
} }
} }
@ -34,12 +34,12 @@ function conditionsValidateOptionValue(object, value) {
} }
function conditionsNormalizeOptionValue(descriptors, type, operator, optionValue) { function conditionsNormalizeOptionValue(descriptors, type, operator, optionValue) {
if (!descriptors.hasOwnProperty(type)) { if (!hasOwn(descriptors, type)) {
throw new Error('Invalid type'); throw new Error('Invalid type');
} }
const conditionDescriptor = descriptors[type]; const conditionDescriptor = descriptors[type];
if (!conditionDescriptor.operators.hasOwnProperty(operator)) { if (!hasOwn(conditionDescriptor.operators, operator)) {
throw new Error('Invalid operator'); throw new Error('Invalid operator');
} }
@ -48,28 +48,28 @@ function conditionsNormalizeOptionValue(descriptors, type, operator, optionValue
let transformedValue = conditionsValidateOptionValue(conditionDescriptor, optionValue); let transformedValue = conditionsValidateOptionValue(conditionDescriptor, optionValue);
transformedValue = conditionsValidateOptionValue(operatorDescriptor, transformedValue); transformedValue = conditionsValidateOptionValue(operatorDescriptor, transformedValue);
if (operatorDescriptor.hasOwnProperty('transformReverse')) { if (hasOwn(operatorDescriptor, 'transformReverse')) {
transformedValue = operatorDescriptor.transformReverse(transformedValue); transformedValue = operatorDescriptor.transformReverse(transformedValue);
} }
return transformedValue; return transformedValue;
} }
function conditionsTestValueThrowing(descriptors, type, operator, optionValue, value) { function conditionsTestValueThrowing(descriptors, type, operator, optionValue, value) {
if (!descriptors.hasOwnProperty(type)) { if (!hasOwn(descriptors, type)) {
throw new Error('Invalid type'); throw new Error('Invalid type');
} }
const conditionDescriptor = descriptors[type]; const conditionDescriptor = descriptors[type];
if (!conditionDescriptor.operators.hasOwnProperty(operator)) { if (!hasOwn(conditionDescriptor.operators, operator)) {
throw new Error('Invalid operator'); throw new Error('Invalid operator');
} }
const operatorDescriptor = conditionDescriptor.operators[operator]; const operatorDescriptor = conditionDescriptor.operators[operator];
if (operatorDescriptor.hasOwnProperty('transform')) { if (hasOwn(operatorDescriptor, 'transform')) {
if (operatorDescriptor.hasOwnProperty('transformCache')) { if (hasOwn(operatorDescriptor, 'transformCache')) {
const key = `${optionValue}`; const key = `${optionValue}`;
const transformCache = operatorDescriptor.transformCache; const transformCache = operatorDescriptor.transformCache;
if (transformCache.hasOwnProperty(key)) { if (hasOwn(transformCache, key)) {
optionValue = transformCache[key]; optionValue = transformCache[key];
} else { } else {
optionValue = operatorDescriptor.transform(optionValue); optionValue = operatorDescriptor.transform(optionValue);
@ -93,23 +93,23 @@ function conditionsTestValue(descriptors, type, operator, optionValue, value) {
function conditionsClearCaches(descriptors) { function conditionsClearCaches(descriptors) {
for (const type in descriptors) { for (const type in descriptors) {
if (!descriptors.hasOwnProperty(type)) { if (!hasOwn(descriptors, type)) {
continue; continue;
} }
const conditionDescriptor = descriptors[type]; const conditionDescriptor = descriptors[type];
if (conditionDescriptor.hasOwnProperty('transformCache')) { if (hasOwn(conditionDescriptor, 'transformCache')) {
conditionDescriptor.transformCache = {}; conditionDescriptor.transformCache = {};
} }
const operatorDescriptors = conditionDescriptor.operators; const operatorDescriptors = conditionDescriptor.operators;
for (const operator in operatorDescriptors) { for (const operator in operatorDescriptors) {
if (!operatorDescriptors.hasOwnProperty(operator)) { if (!hasOwn(operatorDescriptors, operator)) {
continue; continue;
} }
const operatorDescriptor = operatorDescriptors[operator]; const operatorDescriptor = operatorDescriptors[operator];
if (operatorDescriptor.hasOwnProperty('transformCache')) { if (hasOwn(operatorDescriptor, 'transformCache')) {
operatorDescriptor.transformCache = {}; operatorDescriptor.transformCache = {};
} }
} }

View File

@ -137,7 +137,7 @@ class Database {
const visited = {}; const visited = {};
const results = []; const results = [];
const processRow = (row, index) => { const processRow = (row, index) => {
if (titles.includes(row.dictionary) && !visited.hasOwnProperty(row.id)) { if (titles.includes(row.dictionary) && !hasOwn(visited, row.id)) {
visited[row.id] = true; visited[row.id] = true;
results.push(Database.createTerm(row, index)); results.push(Database.createTerm(row, index));
} }

View File

@ -81,7 +81,7 @@ function dictTermsUndupe(definitions) {
const definitionGroups = {}; const definitionGroups = {};
for (const definition of definitions) { for (const definition of definitions) {
const definitionExisting = definitionGroups[definition.id]; const definitionExisting = definitionGroups[definition.id];
if (!definitionGroups.hasOwnProperty(definition.id) || definition.expression.length > definitionExisting.expression.length) { if (!hasOwn(definitionGroups, definition.id) || definition.expression.length > definitionExisting.expression.length) {
definitionGroups[definition.id] = definition; definitionGroups[definition.id] = definition;
} }
} }
@ -131,7 +131,7 @@ function dictTermsGroup(definitions, dictionaries) {
} }
const keyString = key.toString(); const keyString = key.toString();
if (groups.hasOwnProperty(keyString)) { if (hasOwn(groups, keyString)) {
groups[keyString].push(definition); groups[keyString].push(definition);
} else { } else {
groups[keyString] = [definition]; groups[keyString] = [definition];

View File

@ -60,7 +60,7 @@ class Mecab {
} }
onNativeMessage({sequence, data}) { onNativeMessage({sequence, data}) {
if (this.listeners.hasOwnProperty(sequence)) { if (hasOwn(this.listeners, sequence)) {
const {callback, timer} = this.listeners[sequence]; const {callback, timer} = this.listeners[sequence];
clearTimeout(timer); clearTimeout(timer);
callback(data); callback(data);

View File

@ -336,7 +336,7 @@ function profileOptionsSetDefaults(options) {
const combine = (target, source) => { const combine = (target, source) => {
for (const key in source) { for (const key in source) {
if (!target.hasOwnProperty(key)) { if (!hasOwn(target, key)) {
target[key] = source[key]; target[key] = source[key];
} }
} }

View File

@ -234,7 +234,7 @@ class DisplaySearch extends Display {
onRuntimeMessage({action, params}, sender, callback) { onRuntimeMessage({action, params}, sender, callback) {
const handlers = DisplaySearch.runtimeMessageHandlers; const handlers = DisplaySearch.runtimeMessageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
const result = handler(this, params); const result = handler(this, params);
callback(result); callback(result);

View File

@ -81,7 +81,7 @@ class SettingsDictionaryListUI {
let changed = false; let changed = false;
let optionsDictionary; let optionsDictionary;
const optionsDictionaries = this.optionsDictionaries; const optionsDictionaries = this.optionsDictionaries;
if (optionsDictionaries.hasOwnProperty(title)) { if (hasOwn(optionsDictionaries, title)) {
optionsDictionary = optionsDictionaries[title]; optionsDictionary = optionsDictionaries[title];
} else { } else {
optionsDictionary = SettingsDictionaryListUI.createDictionaryOptions(); optionsDictionary = SettingsDictionaryListUI.createDictionaryOptions();
@ -466,7 +466,7 @@ function dictionaryErrorsShow(errors) {
for (let e of errors) { for (let e of errors) {
console.error(e); console.error(e);
e = dictionaryErrorToString(e); e = dictionaryErrorToString(e);
uniqueErrors[e] = uniqueErrors.hasOwnProperty(e) ? uniqueErrors[e] + 1 : 1; uniqueErrors[e] = hasOwn(uniqueErrors, e) ? uniqueErrors[e] + 1 : 1;
} }
for (const e in uniqueErrors) { for (const e in uniqueErrors) {

View File

@ -106,7 +106,7 @@ class SettingsPopupPreview {
onMessage(e) { onMessage(e) {
const {action, params} = e.data; const {action, params} = e.data;
const handlers = SettingsPopupPreview.messageHandlers; const handlers = SettingsPopupPreview.messageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
handler(this, params); handler(this, params);
} }

View File

@ -297,7 +297,7 @@ class Translator {
for (const deinflection of deinflections) { for (const deinflection of deinflections) {
const term = deinflection.term; const term = deinflection.term;
let deinflectionArray; let deinflectionArray;
if (uniqueDeinflectionsMap.hasOwnProperty(term)) { if (hasOwn(uniqueDeinflectionsMap, term)) {
deinflectionArray = uniqueDeinflectionsMap[term]; deinflectionArray = uniqueDeinflectionsMap[term];
} else { } else {
deinflectionArray = []; deinflectionArray = [];
@ -355,7 +355,7 @@ class Translator {
const kanjiUnique = {}; const kanjiUnique = {};
const kanjiList = []; const kanjiList = [];
for (const c of text) { for (const c of text) {
if (!kanjiUnique.hasOwnProperty(c)) { if (!hasOwn(kanjiUnique, c)) {
kanjiList.push(c); kanjiList.push(c);
kanjiUnique[c] = true; kanjiUnique[c] = true;
} }
@ -417,7 +417,7 @@ class Translator {
const expression = term.expression; const expression = term.expression;
term.frequencies = []; term.frequencies = [];
if (termsUniqueMap.hasOwnProperty(expression)) { if (hasOwn(termsUniqueMap, expression)) {
termsUniqueMap[expression].push(term); termsUniqueMap[expression].push(term);
} else { } else {
const termList = [term]; const termList = [term];
@ -464,7 +464,7 @@ class Translator {
const category = meta.category; const category = meta.category;
const group = ( const group = (
stats.hasOwnProperty(category) ? hasOwn(stats, category) ?
stats[category] : stats[category] :
(stats[category] = []) (stats[category] = [])
); );
@ -484,7 +484,7 @@ class Translator {
async getTagMetaList(names, title) { async getTagMetaList(names, title) {
const tagMetaList = []; const tagMetaList = [];
const cache = ( const cache = (
this.tagCache.hasOwnProperty(title) ? hasOwn(this.tagCache, title) ?
this.tagCache[title] : this.tagCache[title] :
(this.tagCache[title] = {}) (this.tagCache[title] = {})
); );
@ -492,7 +492,7 @@ class Translator {
for (const name of names) { for (const name of names) {
const base = Translator.getNameBase(name); const base = Translator.getNameBase(name);
if (cache.hasOwnProperty(base)) { if (hasOwn(cache, base)) {
tagMetaList.push(cache[base]); tagMetaList.push(cache[base]);
} else { } else {
const tagMeta = await this.database.findTagForTitle(base, title); const tagMeta = await this.database.findTagForTitle(base, title);

View File

@ -49,7 +49,7 @@ class DisplayFloat extends Display {
onMessage(e) { onMessage(e) {
const {action, params} = e.data; const {action, params} = e.data;
const handlers = DisplayFloat.messageHandlers; const handlers = DisplayFloat.messageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
handler(this, params); handler(this, params);
} }
@ -58,7 +58,7 @@ class DisplayFloat extends Display {
onKeyDown(e) { onKeyDown(e) {
const key = Display.getKeyFromEvent(e); const key = Display.getKeyFromEvent(e);
const handlers = DisplayFloat.onKeyDownHandlers; const handlers = DisplayFloat.onKeyDownHandlers;
if (handlers.hasOwnProperty(key)) { if (hasOwn(handlers, key)) {
const handler = handlers[key]; const handler = handlers[key];
if (handler(this, e)) { if (handler(this, e)) {
e.preventDefault(); e.preventDefault();

View File

@ -34,7 +34,7 @@ class FrontendApiReceiver {
onMessage(port, {id, action, params, target, senderId}) { onMessage(port, {id, action, params, target, senderId}) {
if ( if (
target !== this.source || target !== this.source ||
!this.handlers.hasOwnProperty(action) !hasOwn(this.handlers, action)
) { ) {
return; return;
} }

View File

@ -78,7 +78,7 @@ class FrontendApiSender {
} }
onAck(id) { onAck(id) {
if (!this.callbacks.hasOwnProperty(id)) { if (!hasOwn(this.callbacks, id)) {
console.warn(`ID ${id} not found for ack`); console.warn(`ID ${id} not found for ack`);
return; return;
} }
@ -95,7 +95,7 @@ class FrontendApiSender {
} }
onResult(id, data) { onResult(id, data) {
if (!this.callbacks.hasOwnProperty(id)) { if (!hasOwn(this.callbacks, id)) {
console.warn(`ID ${id} not found`); console.warn(`ID ${id} not found`);
return; return;
} }
@ -118,7 +118,7 @@ class FrontendApiSender {
} }
onError(id, reason) { onError(id, reason) {
if (!this.callbacks.hasOwnProperty(id)) { return; } if (!hasOwn(this.callbacks, id)) { return; }
const info = this.callbacks[id]; const info = this.callbacks[id];
delete this.callbacks[id]; delete this.callbacks[id];
info.timer = null; info.timer = null;

View File

@ -237,7 +237,7 @@ class Frontend {
onWindowMessage(e) { onWindowMessage(e) {
const action = e.data; const action = e.data;
const handlers = Frontend.windowMessageHandlers; const handlers = Frontend.windowMessageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
handler(this); handler(this);
} }
@ -245,7 +245,7 @@ class Frontend {
onRuntimeMessage({action, params}, sender, callback) { onRuntimeMessage({action, params}, sender, callback) {
const handlers = Frontend.runtimeMessageHandlers; const handlers = Frontend.runtimeMessageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
const result = handler(this, params); const result = handler(this, params);
callback(result); callback(result);

View File

@ -50,7 +50,7 @@ class PopupProxyHost {
} }
createPopup(parentId, depth) { createPopup(parentId, depth) {
const parent = (typeof parentId === 'string' && this.popups.hasOwnProperty(parentId) ? this.popups[parentId] : null); const parent = (typeof parentId === 'string' && hasOwn(this.popups, parentId) ? this.popups[parentId] : null);
const id = `${this.nextId}`; const id = `${this.nextId}`;
if (parent !== null) { if (parent !== null) {
depth = parent.depth + 1; depth = parent.depth + 1;
@ -70,7 +70,7 @@ class PopupProxyHost {
} }
getPopup(id) { getPopup(id) {
if (!this.popups.hasOwnProperty(id)) { if (!hasOwn(this.popups, id)) {
throw new Error('Invalid popup ID'); throw new Error('Invalid popup ID');
} }

View File

@ -113,7 +113,7 @@ function audioGetFromUrl(url, willDownload) {
async function audioGetFromSources(expression, sources, optionsContext, willDownload, cache=null) { async function audioGetFromSources(expression, sources, optionsContext, willDownload, cache=null) {
const key = `${expression.expression}:${expression.reading}`; const key = `${expression.expression}:${expression.reading}`;
if (cache !== null && cache.hasOwnProperty(expression)) { if (cache !== null && hasOwn(cache, expression)) {
return cache[key]; return cache[key];
} }

View File

@ -94,6 +94,10 @@ function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value); return typeof value === 'object' && value !== null && !Array.isArray(value);
} }
function hasOwn(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
}
// toIterable is required on Edge for cross-window origin objects. // toIterable is required on Edge for cross-window origin objects.
function toIterable(value) { function toIterable(value) {
if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') { if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') {

View File

@ -194,7 +194,7 @@ class Display {
onKeyDown(e) { onKeyDown(e) {
const key = Display.getKeyFromEvent(e); const key = Display.getKeyFromEvent(e);
const handlers = Display.onKeyDownHandlers; const handlers = Display.onKeyDownHandlers;
if (handlers.hasOwnProperty(key)) { if (hasOwn(handlers, key)) {
const handler = handlers[key]; const handler = handlers[key];
if (handler(this, e)) { if (handler(this, e)) {
e.preventDefault(); e.preventDefault();
@ -216,7 +216,7 @@ class Display {
onRuntimeMessage({action, params}, sender, callback) { onRuntimeMessage({action, params}, sender, callback) {
const handlers = Display.runtimeMessageHandlers; const handlers = Display.runtimeMessageHandlers;
if (handlers.hasOwnProperty(action)) { if (hasOwn(handlers, action)) {
const handler = handlers[action]; const handler = handlers[action];
const result = handler(this, params); const result = handler(this, params);
callback(result); callback(result);