Skip to content

Simplify external plugin development with a plugin factory #6

Open
@aarondfrancis

Description

@aarondfrancis

I've found that when creating multiple external plugins, the process can get a bit tedious.

I've created an internal PluginFactory that makes it a lot easier. Not sure if this is useful enough to be used somewhere.

plugin-factory.js

import Handsontable from 'handsontable';

export default function (settingsKey) {
    /**
     * @param hotInstance
     * @constructor
     */
    let plugin = function (hotInstance) {
        // Call the BasePlugin constructor.
        Handsontable.plugins.BasePlugin.call(this, hotInstance);

        this.optionalCall('setup')

        this._superClass = Handsontable.plugins.BasePlugin;
    }

    // Inherit the BasePlugin prototype.
    plugin.prototype = Object.create(Handsontable.plugins.BasePlugin.prototype, {
        constructor: {
            writable: true,
            configurable: true,
            value: plugin
        },
    });

    plugin.prototype.optionalCall = function (name) {
        if (this[name] && typeof this[name] === 'function') {
            this[name]();
        }
    }

    /**
     * Checks if the plugin is enabled in the settings.
     */
    plugin.prototype.isEnabled = function () {
        return !!this.hot.getSettings()[settingsKey];
    }

    /**
     * The enablePlugin method is triggered on the beforeInit hook. It should contain your initial plugin setup, along with
     * the hook connections.
     * Note, that this method is run only if the statement in the isEnabled method is true.
     */
    plugin.prototype.enablePlugin = function () {
        this.optionalCall('enable');

        // The super class' method assigns the this.enabled property to true, which can be later used to check if plugin is already enabled.
        this._superClass.prototype.enablePlugin.call(this);
    };

    /**
     * The disablePlugin method is used to disable the plugin. Reset all of your classes properties to their default values here.
     */
    plugin.prototype.disablePlugin = function () {
        this.optionalCall('disable');

        // The super class' method takes care of clearing the hook connections and assigning the 'false' value to the 'this.enabled' property.
        this._superClass.prototype.disablePlugin.call(this);
    };

    /**
     * The destroy method should de-assign all of your properties.
     */
    plugin.prototype.destroy = function () {
        this.optionalCall('teardown');

        // The super method takes care of de-assigning the event callbacks, plugin hooks and clearing all the plugin properties.
        this._superClass.prototype.destroy.call(this);
    };

    return plugin;
}

custom-headers.js

import PluginFactory from './plugin-factory';

let CustomHeaders = PluginFactory('customHeaders');

CustomHeaders.prototype.enable = function () {
    this.hot.getSettings().afterGetColHeader = this.afterGetColHeader.bind(this);
    this.hot.getSettings().afterGetRowHeader = this.afterGetRowHeader.bind(this);
}

CustomHeaders.prototype.afterGetColHeader = function (col, th) {
    // Modify column header
}

CustomHeaders.prototype.afterGetRowHeader = function (row, th) {
    // Modify row header
}

export default CustomHeaders;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions