handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
743 lines (714 loc) • 27 kB
JavaScript
"use strict";
exports.__esModule = true;
require("core-js/modules/es.error.cause.js");
require("core-js/modules/es.array.push.js");
var _base = require("../base");
var _object = require("../../helpers/object");
var _number = require("../../helpers/number");
var _array = require("../../helpers/array");
var C = _interopRequireWildcard(require("../../i18n/constants"));
var _contextMenuItem = require("./contextMenuItem");
var _utils = require("./utils");
var _selection = require("../../selection");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const PLUGIN_KEY = exports.PLUGIN_KEY = 'customBorders';
const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 90;
/* eslint-disable jsdoc/require-description-complete-sentence */
/**
* @plugin CustomBorders
* @class CustomBorders
*
* @description
* This plugin enables an option to apply custom borders through the context menu (configurable with context menu key
* `borders`).
*
* To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form
* of an array.
*
* See [`customBorders` configuration option](@/api/options.md#customBorders) or go to
* [Custom cell borders demo](@/guides/cell-features/formatting-cells/formatting-cells.md#custom-cell-borders) for more examples.
*
* @example
* ```js
* customBorders: [
* {
* range: {
* from: {
* row: 1,
* col: 1
* },
* to: {
* row: 3,
* col: 4
* },
* },
* start: {},
* end: {},
* top: {},
* bottom: {},
* },
* ],
*
* // or
* customBorders: [
* { row: 2,
* col: 2,
* start: {
* width: 2,
* color: 'red',
* },
* end: {
* width: 1,
* color: 'green',
* },
* top: '',
* bottom: '',
* }
* ],
* ```
*/
var _CustomBorders_brand = /*#__PURE__*/new WeakSet();
class CustomBorders extends _base.BasePlugin {
constructor() {
super(...arguments);
/**
* Add border options to context menu.
*
* @param {object} defaultOptions Context menu items.
*/
_classPrivateMethodInitSpec(this, _CustomBorders_brand);
/**
* Saved borders.
*
* @private
* @type {Array}
*/
_defineProperty(this, "savedBorders", []);
}
static get PLUGIN_KEY() {
return PLUGIN_KEY;
}
static get PLUGIN_PRIORITY() {
return PLUGIN_PRIORITY;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` then the {@link CustomBorders#enablePlugin} method is called.
*
* @returns {boolean}
*/
isEnabled() {
return !!this.hot.getSettings()[PLUGIN_KEY];
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
enablePlugin() {
if (this.enabled) {
return;
}
this.addHook('afterContextMenuDefaultOptions', options => _assertClassBrand(_CustomBorders_brand, this, _onAfterContextMenuDefaultOptions).call(this, options));
this.addHook('init', () => _assertClassBrand(_CustomBorders_brand, this, _onAfterInit).call(this));
super.enablePlugin();
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
disablePlugin() {
this.hideBorders();
super.disablePlugin();
}
/**
* Updates the plugin's state.
*
* This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
* - [`customBorders`](@/api/options.md#customborders)
*/
updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.changeBorderSettings();
super.updatePlugin();
}
/**
* Set custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.setBorders([[1, 1, 2, 2], [6, 2, 0, 2]], {start: {width: 2, color: 'blue'}});
*
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* // Selecting a cell range.
* hot.selectCell(0, 0, 2, 2);
* // Returning selected cells' range with the getSelectedRange method.
* customBordersPlugin.setBorders(hot.getSelectedRange(), {start: {hide: false, width: 2, color: 'blue'}});
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
* @param {object} borderObject Object with `top`, `right`, `bottom` and `start` properties.
*/
setBorders(selectionRanges, borderObject) {
let borderKeys = ['top', 'bottom', 'start', 'end'];
let normBorder = null;
if (borderObject) {
this.checkSettingsCohesion([borderObject]);
borderKeys = Object.keys(borderObject);
normBorder = (0, _utils.normalizeBorder)(borderObject);
}
const selectionType = (0, _selection.detectSelectionType)(selectionRanges);
const selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType, {
createCellCoords: this.hot._createCellCoords.bind(this.hot),
createCellRange: this.hot._createCellRange.bind(this.hot)
});
(0, _array.arrayEach)(selectionRanges, selection => {
selectionSchemaNormalizer(selection).forAll((row, col) => {
(0, _array.arrayEach)(borderKeys, borderKey => {
this.prepareBorderFromCustomAdded(row, col, normBorder, (0, _utils.toInlinePropName)(borderKey));
});
});
});
/*
The line below triggers a re-render of Handsontable. This will be a "fastDraw"
render, because that is the default for the TableView class.
The re-render is needed for borders on cells that did not have a border before.
The way this call works is that it calls Table.refreshSelections, which calls
Selection.getBorder, which creates a new instance of Border.
Seems wise to keep this single-direction flow of creating new Borders
*/
this.hot.view.render();
}
/**
* Get custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.getBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* customBordersPlugin.getBorders(hot.getSelectedRange());
* // Using without param - return all customBorders.
* customBordersPlugin.getBorders();
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
* @returns {object[]} Returns array of border objects.
*/
getBorders(selectionRanges) {
if (!Array.isArray(selectionRanges)) {
return this.savedBorders;
}
const selectionType = (0, _selection.detectSelectionType)(selectionRanges);
const selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType, {
createCellCoords: this.hot._createCellCoords.bind(this.hot),
createCellRange: this.hot._createCellRange.bind(this.hot)
});
const selectedBorders = [];
(0, _array.arrayEach)(selectionRanges, selection => {
selectionSchemaNormalizer(selection).forAll((row, col) => {
(0, _array.arrayEach)(this.savedBorders, border => {
if (border.row === row && border.col === col) {
selectedBorders.push((0, _utils.denormalizeBorder)(border));
}
});
});
});
return selectedBorders;
}
/**
* Clear custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.clearBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* customBordersPlugin.clearBorders(hot.getSelectedRange());
* // Using without param - clear all customBorders.
* customBordersPlugin.clearBorders();
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
*/
clearBorders(selectionRanges) {
if (selectionRanges) {
this.setBorders(selectionRanges);
} else {
(0, _array.arrayEach)(this.savedBorders, border => {
this.clearBordersFromSelectionSettings(border.id);
this.clearNullCellRange();
this.hot.removeCellMeta(border.row, border.col, 'borders');
});
this.savedBorders.length = 0;
}
}
/**
* Insert WalkontableSelection instance into Walkontable settings.
*
* @private
* @param {object} border Object with `row` and `col`, `start`, `end`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {string} [place] Coordinate where add/remove border - `top`, `bottom`, `start`, `end`.
*/
insertBorderIntoSettings(border, place) {
const hasSavedBorders = this.checkSavedBorders(border);
if (!hasSavedBorders) {
this.savedBorders.push(border);
}
const visualCellRange = this.hot._createCellRange(this.hot._createCellCoords(border.row, border.col));
const hasCustomSelections = this.checkCustomSelections(border, visualCellRange, place);
if (!hasCustomSelections) {
this.hot.selection.highlight.addCustomSelection({
border,
visualCellRange
});
}
}
/**
* Prepare borders from setting (single cell).
*
* @private
* @param {number} row Visual row index.
* @param {number} column Visual column index.
* @param {object} borderDescriptor Object with `row` and `col`, `start`, `end`, `top` and `bottom` properties.
* @param {string} [place] Coordinate where add/remove border - `top`, `bottom`, `start`, `end`.
*/
prepareBorderFromCustomAdded(row, column, borderDescriptor, place) {
const nrOfRows = this.hot.countRows();
const nrOfColumns = this.hot.countCols();
if (row >= nrOfRows || column >= nrOfColumns) {
return;
}
let border = (0, _utils.createEmptyBorders)(row, column);
if (borderDescriptor) {
border = (0, _utils.extendDefaultBorder)(border, borderDescriptor);
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, customSelection => {
if (border.id === customSelection.settings.id) {
Object.assign(customSelection.settings, borderDescriptor);
border.id = customSelection.settings.id;
border.top = customSelection.settings.top;
border.bottom = customSelection.settings.bottom;
border.start = customSelection.settings.start;
border.end = customSelection.settings.end;
return false; // breaks forAll
}
});
}
this.hot.setCellMeta(row, column, 'borders', (0, _utils.denormalizeBorder)(border));
this.insertBorderIntoSettings(border, place);
}
/**
* Prepare borders from setting (object).
*
* @private
* @param {object} range {CellRange} The CellRange object.
* @param {object} customBorder Object with `start`, `end`, `top` and `bottom` properties.
*/
prepareBorderFromCustomAddedRange(range, customBorder) {
const lastRowIndex = Math.min(range.to.row, this.hot.countRows() - 1);
const lastColumnIndex = Math.min(range.to.col, this.hot.countCols() - 1);
(0, _number.rangeEach)(range.from.row, lastRowIndex, rowIndex => {
(0, _number.rangeEach)(range.from.col, lastColumnIndex, colIndex => {
const border = (0, _utils.createEmptyBorders)(rowIndex, colIndex);
let add = 0;
if (rowIndex === range.from.row) {
if ((0, _object.hasOwnProperty)(customBorder, 'top')) {
add += 1;
border.top = customBorder.top;
}
}
// Please keep in mind that `range.to.row` may be beyond the table boundaries. The border won't be rendered.
if (rowIndex === range.to.row) {
if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) {
add += 1;
border.bottom = customBorder.bottom;
}
}
if (colIndex === range.from.col) {
if ((0, _object.hasOwnProperty)(customBorder, 'start')) {
add += 1;
border.start = customBorder.start;
}
}
// Please keep in mind that `range.to.col` may be beyond the table boundaries. The border won't be rendered.
if (colIndex === range.to.col) {
if ((0, _object.hasOwnProperty)(customBorder, 'end')) {
add += 1;
border.end = customBorder.end;
}
}
if (add > 0) {
this.hot.setCellMeta(rowIndex, colIndex, 'borders', (0, _utils.denormalizeBorder)(border));
this.insertBorderIntoSettings(border);
} else {
// TODO sometimes it enters here. Why?
}
});
});
}
/**
* Remove border (triggered from context menu).
*
* @private
* @param {number} row Visual row index.
* @param {number} column Visual column index.
*/
removeAllBorders(row, column) {
const borderId = (0, _utils.createId)(row, column);
this.spliceBorder(borderId);
this.clearBordersFromSelectionSettings(borderId);
this.clearNullCellRange();
this.hot.removeCellMeta(row, column, 'borders');
}
/**
* Set borders for each cell re. To border position.
*
* @private
* @param {number} row Visual row index.
* @param {number} column Visual column index.
* @param {string} place Coordinate where add/remove border - `top`, `bottom`, `start`, `end` and `noBorders`.
* @param {boolean} remove True when remove borders, and false when add borders.
*/
setBorder(row, column, place, remove) {
let bordersMeta = this.hot.getCellMeta(row, column).borders;
if (!bordersMeta || bordersMeta.border === undefined) {
bordersMeta = (0, _utils.createEmptyBorders)(row, column);
} else {
bordersMeta = (0, _utils.normalizeBorder)(bordersMeta);
}
if (remove) {
bordersMeta[place] = (0, _utils.createSingleEmptyBorder)();
const hideCount = this.countHide(bordersMeta);
if (hideCount === 4) {
this.removeAllBorders(row, column);
} else {
const customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);
if (!customSelectionsChecker) {
this.insertBorderIntoSettings(bordersMeta);
}
this.hot.setCellMeta(row, column, 'borders', (0, _utils.denormalizeBorder)(bordersMeta));
}
} else {
bordersMeta[place] = (0, _utils.createDefaultCustomBorder)();
const customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);
if (!customSelectionsChecker) {
this.insertBorderIntoSettings(bordersMeta);
}
this.hot.setCellMeta(row, column, 'borders', (0, _utils.denormalizeBorder)(bordersMeta));
}
}
/**
* Prepare borders based on cell and border position.
*
* @private
* @param {CellRange[]} selected An array of CellRange objects.
* @param {string} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
* @param {boolean} remove True when remove borders, and false when add borders.
*/
prepareBorder(selected, place, remove) {
(0, _array.arrayEach)(selected, _ref => {
let {
start,
end
} = _ref;
if (start.row === end.row && start.col === end.col) {
if (place === 'noBorders') {
this.removeAllBorders(start.row, start.col);
} else {
this.setBorder(start.row, start.col, place, remove);
}
} else {
switch (place) {
case 'noBorders':
(0, _number.rangeEach)(start.col, end.col, colIndex => {
(0, _number.rangeEach)(start.row, end.row, rowIndex => {
this.removeAllBorders(rowIndex, colIndex);
});
});
break;
case 'top':
(0, _number.rangeEach)(start.col, end.col, topCol => {
this.setBorder(start.row, topCol, place, remove);
});
break;
case 'bottom':
(0, _number.rangeEach)(start.col, end.col, bottomCol => {
this.setBorder(end.row, bottomCol, place, remove);
});
break;
case 'start':
(0, _number.rangeEach)(start.row, end.row, rowStart => {
this.setBorder(rowStart, start.col, place, remove);
});
break;
case 'end':
(0, _number.rangeEach)(start.row, end.row, rowEnd => {
this.setBorder(rowEnd, end.col, place, remove);
});
break;
default:
break;
}
}
});
}
/**
* Create borders from settings.
*
* @private
* @param {Array} customBorders Object with `row` and `col`, `start`, `end`, `top` and `bottom` properties.
*/
createCustomBorders(customBorders) {
(0, _array.arrayEach)(customBorders, customBorder => {
const normCustomBorder = (0, _utils.normalizeBorder)(customBorder);
if (customBorder.range) {
this.prepareBorderFromCustomAddedRange(customBorder.range, normCustomBorder);
} else {
this.prepareBorderFromCustomAdded(customBorder.row, customBorder.col, normCustomBorder);
}
});
}
/**
* Count hide property in border object.
*
* @private
* @param {object} border Object with `row` and `col`, `start`, `end`, `top` and `bottom`, `id` and
* `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @returns {number}
*/
countHide(border) {
const {
top,
bottom,
start,
end
} = border;
const values = [top, bottom, start, end];
return (0, _array.arrayReduce)(values, (accumulator, value) => {
let result = accumulator;
if (value && value.hide) {
result += 1;
}
return result;
}, 0);
}
/**
* Clear borders settings from custom selections.
*
* @private
* @param {string} borderId Border id name as string.
*/
clearBordersFromSelectionSettings(borderId) {
const index = (0, _array.arrayMap)(this.hot.selection.highlight.customSelections, customSelection => customSelection.settings.id).indexOf(borderId);
if (index > -1) {
this.hot.selection.highlight.customSelections[index].clear();
}
}
/**
* Clear cellRange with null value.
*
* @private
*/
clearNullCellRange() {
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, (customSelection, index) => {
if (customSelection.cellRange === null) {
this.hot.selection.highlight.customSelections[index].destroy();
this.hot.selection.highlight.customSelections.splice(index, 1);
return false; // breaks forAll
}
});
}
/**
* Hide custom borders.
*
* @private
*/
hideBorders() {
(0, _array.arrayEach)(this.savedBorders, border => {
this.clearBordersFromSelectionSettings(border.id);
this.clearNullCellRange();
});
}
/**
* Splice border from savedBorders.
*
* @private
* @param {string} borderId Border id name as string.
*/
spliceBorder(borderId) {
const index = (0, _array.arrayMap)(this.savedBorders, border => border.id).indexOf(borderId);
if (index > -1) {
this.savedBorders.splice(index, 1);
}
}
/**
* Check if an border already exists in the savedBorders array, and if true update border in savedBorders.
*
* @private
* @param {object} border Object with `row` and `col`, `start`, `end`, `top` and `bottom`, `id` and
* `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
*
* @returns {boolean}
*/
checkSavedBorders(border) {
let check = false;
const hideCount = this.countHide(border);
if (hideCount === 4) {
this.spliceBorder(border.id);
check = true;
} else {
(0, _array.arrayEach)(this.savedBorders, (savedBorder, index) => {
if (border.id === savedBorder.id) {
this.savedBorders[index] = border;
check = true;
return false; // breaks forAll
}
});
}
return check;
}
/**
* Check if an border already exists in the customSelections, and if true call toggleHiddenClass method.
*
* @private
* @param {object} border Object with `row` and `col`, `start`, `end`, `top` and `bottom`, `id` and
* `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {string} place Coordinate where add/remove border - `top`, `bottom`, `start`, `end` and `noBorders`.
* @param {boolean} remove True when remove borders, and false when add borders.
*
* @returns {boolean}
*/
checkCustomSelectionsFromContextMenu(border, place, remove) {
let check = false;
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, customSelection => {
if (border.id === customSelection.settings.id) {
const borders = this.hot.view._wt.selectionManager.getBorderInstances(customSelection);
(0, _array.arrayEach)(borders, borderObject => {
borderObject.toggleHiddenClass(place, remove); // TODO this also bad?
});
check = true;
return false; // breaks forAll
}
});
return check;
}
/**
* Check if an border already exists in the customSelections, and if true reset cellRange.
*
* @private
* @param {object} border Object with `row` and `col`, `start`, `end`, `top` and `bottom`, `id` and
* `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {CellRange} cellRange The selection range to check.
* @param {string} [place] Coordinate where add/remove border - `top`, `bottom`, `start`, `end`.
* @returns {boolean}
*/
checkCustomSelections(border, cellRange, place) {
const hideCount = this.countHide(border);
let check = false;
if (hideCount === 4) {
this.removeAllBorders(border.row, border.col);
check = true;
} else {
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, customSelection => {
if (border.id === customSelection.settings.id) {
customSelection.visualCellRange = cellRange;
customSelection.commit();
if (place) {
const borders = this.hot.view._wt.selectionManager.getBorderInstances(customSelection);
(0, _array.arrayEach)(borders, borderObject => {
borderObject.changeBorderStyle(place, border);
});
}
check = true;
return false; // breaks forAll
}
});
}
return check;
}
/**
* Change borders from settings.
*
* @private
*/
changeBorderSettings() {
const customBorders = this.hot.getSettings()[PLUGIN_KEY];
if (Array.isArray(customBorders)) {
const bordersClone = (0, _object.deepClone)(customBorders);
this.checkSettingsCohesion(bordersClone);
if (!bordersClone.length) {
this.savedBorders = bordersClone;
}
this.createCustomBorders(bordersClone);
} else if (customBorders !== undefined) {
this.createCustomBorders(this.savedBorders);
}
}
/**
* Checks the settings cohesion. The properties such like "left"/"right" are supported only
* in the LTR mode and the "left"/"right" options can not be used together with "start"/"end" properties.
*
* @private
* @param {object[]} customBorders The user defined custom border objects array.
*/
checkSettingsCohesion(customBorders) {
const hasLeftOrRight = (0, _utils.hasLeftRightTypeOptions)(customBorders);
const hasStartOrEnd = (0, _utils.hasStartEndTypeOptions)(customBorders);
if (hasLeftOrRight && hasStartOrEnd) {
throw new Error('The "left"/"right" and "start"/"end" options should not be used together. ' + 'Please use only the option "start"/"end".');
}
if (this.hot.isRtl() && hasLeftOrRight) {
throw new Error('The "left"/"right" properties are not supported for RTL. Please use option "start"/"end".');
}
}
/**
* Destroys the plugin instance.
*/
destroy() {
super.destroy();
}
}
exports.CustomBorders = CustomBorders;
function _onAfterContextMenuDefaultOptions(defaultOptions) {
if (!this.hot.getSettings()[PLUGIN_KEY]) {
return;
}
defaultOptions.items.push({
name: '---------'
}, {
key: 'borders',
name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS);
},
disabled() {
const range = this.getSelectedRangeActive();
if (!range) {
return true;
}
if (range.isSingleHeader()) {
return true;
}
return this.selection.isSelectedByCorner();
},
submenu: {
items: [(0, _contextMenuItem.top)(this), (0, _contextMenuItem.right)(this), (0, _contextMenuItem.bottom)(this), (0, _contextMenuItem.left)(this), (0, _contextMenuItem.noBorders)(this)]
}
});
}
/**
* `afterInit` hook callback.
*/
function _onAfterInit() {
this.changeBorderSettings();
}