formstone
Version:
Library of modular front end components.
285 lines (225 loc) • 7.28 kB
JavaScript
/* global define */
(function(factory) {
if (typeof define === "function" && define.amd) {
define([
"jquery",
"./core",
"./mediaquery"
], factory);
} else {
factory(jQuery, Formstone);
}
}(function($, Formstone) {
"use strict";
/**
* @method private
* @name construct
* @description Builds instance.
* @param data [object] "Instance data"
*/
function construct(data) {
data.enabled = false;
data.active = false;
data.classes = $.extend(true, {}, Classes, data.classes);
data.target = this.data(Namespace + "-target");
data.$target = $(data.target).addClass(data.classes.raw.target);
data.mq = "(max-width:" + (data.maxWidth === Infinity ? "100000px" : data.maxWidth) + ")";
// live query for linked to avoid missing new elements
var linked = this.data(Namespace + "-linked");
data.linked = linked ? '[data-' + Namespace + '-linked="' + linked + '"]' : false;
// live query for the group to avoid missing new elements
var group = this.data(Namespace + "-group");
data.group = group ? '[data-' + Namespace + '-group="' + group + '"]' : false;
data.$swaps = $().add(this).add(data.$target);
this.on(Events.click + data.dotGuid, data, onClick);
}
/**
* @method private
* @name postConstruct
* @description Run post build.
* @param data [object] "Instance data"
*/
function postConstruct(data) {
if (!data.collapse && data.group && !$(data.group).filter("[data-" + Namespace + "-active]").length) {
$(data.group).eq(0).attr("data-" + Namespace + "-active", "true");
}
// Should be activate when enabled
data.onEnable = this.data(Namespace + "-active") || false;
// Media Query support
$.fsMediaquery("bind", data.rawGuid, data.mq, {
enter: function() {
enable.call(data.$el, data, true);
},
leave: function() {
disable.call(data.$el, data, true);
}
});
}
/**
* @method private
* @name destruct
* @description Tears down instance.
* @param data [object] "Instance data"
*/
function destruct(data) {
$.fsMediaquery("unbind", data.rawGuid);
data.$swaps.removeClass([data.classes.raw.enabled, data.classes.raw.active].join(" "))
.off(Events.namespace);
}
/**
* @method
* @name activate
* @description Activate instance.
* @example $(".target").swap("activate");
*/
function activate(data, fromLinked) {
if (data.enabled && !data.active) {
if (data.group && !fromLinked) {
// Deactivates grouped instances
$(data.group).not(data.$el).not(data.linked)[Plugin.namespaceClean]("deactivate", true);
}
// index in group
var index = (data.group) ? $(data.group).index(data.$el) : null;
data.$swaps.addClass(data.classes.raw.active);
if (!fromLinked) {
if (data.linked) {
// Linked handles
$(data.linked).not(data.$el)[Plugin.namespaceClean]("activate", true);
}
}
this.trigger(Events.activate, [index]);
data.active = true;
}
}
/**
* @method
* @name deactivate
* @description Deactivates instance.
* @example $(".target").swap("deactivate");
*/
function deactivate(data, fromLinked) {
if (data.enabled && data.active) {
data.$swaps.removeClass(data.classes.raw.active);
if (!fromLinked) {
if (data.linked) {
// Linked handles
$(data.linked).not(data.$el)[Plugin.namespaceClean]("deactivate", true);
}
}
this.trigger(Events.deactivate);
data.active = false;
}
}
/**
* @method
* @name enable
* @description Enables instance.
* @example $(".target").swap("enable");
*/
function enable(data, fromLinked) {
if (!data.enabled) {
data.enabled = true;
data.$swaps.addClass(data.classes.raw.enabled);
if (!fromLinked) {
// Linked handles
$(data.linked).not(data.$el)[Plugin.namespaceClean]("enable");
}
this.trigger(Events.enable);
if (data.onEnable) {
data.active = false;
activate.call(this, data);
} else {
data.active = true;
deactivate.call(this, data);
}
}
}
/**
* @method
* @name disable
* @description Disables instance.
* @example $(".target").swap("disable");
*/
function disable(data, fromLinked) {
if (data.enabled) {
data.enabled = false;
data.$swaps.removeClass([data.classes.raw.enabled, data.classes.raw.active].join(" "));
if (!fromLinked) {
// Linked handles
$(data.linked).not(data.$el)[Plugin.namespaceClean]("disable");
}
this.trigger(Events.disable);
}
}
/**
* @method private
* @name onClick
* @description Handles click nav click.
* @param e [object] "Event data"
*/
function onClick(e) {
Functions.killEvent(e);
var data = e.data;
if (data.active && data.collapse) {
deactivate.call(data.$el, data);
} else {
activate.call(data.$el, data);
}
}
/**
* @plugin
* @name Swap
* @description A jQuery plugin for toggling states.
* @type widget
* @main swap.js
* @dependency jQuery
* @dependency core.js
* @dependency mediaquery.js
*/
var Plugin = Formstone.Plugin("swap", {
widget: true,
/**
* @options
* @param collapse [boolean] <true> "Allow swap to collapse it's target"
* @param maxWidth [string] <Infinity> "Width at which to auto-disable plugin"
*/
defaults: {
collapse: true,
maxWidth: Infinity
},
classes: [
"target",
"enabled",
"active"
],
/**
* @events
* @event activate.swap "Swap activated"
* @event deactivate.swap "Swap deactivated"
* @event enable.swap "Swap enabled"
* @event disable.swap "Swap diabled"
*/
events: {
activate: "activate",
deactivate: "deactivate",
enable: "enable",
disable: "disable"
},
methods: {
_construct: construct,
_postConstruct: postConstruct,
_destruct: destruct,
// Public Methods
activate: activate,
deactivate: deactivate,
enable: enable,
disable: disable
}
}),
// Localize References
Namespace = Plugin.namespace,
Classes = Plugin.classes,
Events = Plugin.events,
Functions = Plugin.functions;
})
);