2
\$\begingroup\$

I have this plugin that I have finally finished the big pieces of, there's one or two minor details that are not yet implemented do to lack of a decision yet but everything else is there.

I wrote it and can follow fine but I feel it reads very haphazardly. Could someone with fresh eyes help me make this into a more production level plugin? For clarity, I'm not asking for it be rewritten, just if you see something that could be made better, a nudge in that direction would be super helpful.

;(function($, undefined) {
  var defaults = {
    onInit   : function () {},
    onDestroy: function () {},
    onClick  : function () {},
    onHover  : function(id, state) { this.setTransient(id, 'blue'); },
    noHover  : function(id, state) { this.reset(id); }
  }

  var pubAPI = {
    set : function(id, style) {
      this.state[id].style = style;
      this.reset(id);
    },
    reset : function(id) {
      applyStyle.call(this, id);
    },
    setTransient : function (id, style) {
      applyStyle.call(this, id, style);
    },
    resetState : function (id) {
      this.state[id].style = this.state[id].dFault;
      this.reset(id);
    },
    destroy : function () {
      this.settings.onDestroy();
      unbindEvents();
    },
    getInstance : function () {
      return this;
    }
  }

  var Clicklight = function(options) {
    this.settings = $.extend({}, defaults, options);
    this.state    = {};
  }

  var init = function(elem, inst) {
    var id = idCheck(elem);

    if (id) {
      if (!inst.state[id]) {
        var color = $(elem).css('color');
        inst.state[id] = {
          group    : [],
          dFault   : color,
          style    : color
        }
      }
      inst.state[id].group.push($(elem));

      bindEvent($(elem), inst, id);
      inst.settings.onInit();

      return inst;
    } else {
      console.log('ERROR: No \'data-cl-uid\' found on', elem, '-this element was not included');
      return undefined; // data attr can't hold undefined, forces error later on                                       
    }
  }

  var idCheck = function(elem) {
    return $(elem).attr('data-cl-uid') ?
      $(elem).attr('data-cl-uid') : null;
  }

  var bindEvent = function($elem, inst, id) {
    $elem.on('click.clicklight', function () {
      inst.settings.onClick.call(inst, id, inst.state[id]);
    }).on('mouseenter.clicklight', function () {
      inst.settings.onHover.call(inst, id, inst.state[id]);
    }).on('mouseleave.clicklight', function() {
      inst.settings.noHover.call(inst, id, inst.state[id]);
    });
  }

  var unbindEvents = function($elem) {
    // fill this in
  }

  var applyStyle = function (id, style) {
    var group = this.state[id].group;
    if (!style)
      style = this.state[id].style

    for (var i = 0; i < group.length; i++)
      group[i].css('color', style);
  }

  var getInst = function($elem) {
    var inst = null;
    $elem.each(function() {
      if (!$.data(this, 'cl-instance'))
        return true
      else if (!($.data(this, 'cl-instance') instanceof Clicklight)) {
        console.log('ERROR: Invalid instance found on', this);
        return true;
      } else {
        inst = $.data(this, 'cl-instance');
        return false;
      }
    });
    return inst;
  }

  $.extend(Clicklight.prototype, pubAPI);

  $.fn.clicklight = function (option) {
    var args = arguments;

    if (typeof option === 'object' || !option) {
      var inst = null;
      return this.each(function() {
        if (!inst)
          inst = new Clicklight(option);

        if (!$.data(this, 'cl-instance'))
          $.data(this, 'cl-instance', init(this,  inst));
        else
          console.log('ERROR: Cannot create a duplicate instance for ',this);
      });
    } else if (typeof option === 'string' && option in pubAPI) {
      var inst = getInst(this);
      if (inst) {
        if (typeof inst[option] === 'function')
          return inst[option].apply(inst, Array.prototype.slice.call(args, 1));
        else
          console.log('ERROR: No method found with name', option);
      } else
        console.log('ERROR: No instance found in selection', this);
    } else
      console.log('ERROR: Invalid call of clicklight with argument', option);
    return this;
  }
})(jQuery, undefined);

For those that want to see it in action, I have it running on this test page.

\$\endgroup\$
0

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.