Skip to content

Commit

Permalink
Merge pull request #3 from hlfcoding/v0.2.0
Browse files Browse the repository at this point in the history
v0.2.0-0

- Extensive documentation updates.
- Minor breaking API changes.
- Switch to UMD for all release JS products.
- Minor SCSS refactoring.
  • Loading branch information
hlfcoding committed May 13, 2015
2 parents 06e966b + 1e10dc4 commit 96f6890
Show file tree
Hide file tree
Showing 29 changed files with 1,581 additions and 1,427 deletions.
3 changes: 3 additions & 0 deletions Gruntfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ module.exports = (grunt) ->
css:
files: '{src,tests}/**/*.scss'
tasks: ['copy:dist', 'sass', 'autoprefixer']
docs:
files: aspects.docs.groc.all.src
tasks: ['docs']
js:
files: '{src,tests}/**/*.coffee'
tasks: ['coffee']
Expand Down
87 changes: 47 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,67 @@
# HLF jQuery Library [![Build Status](https://travis-ci.org/hlfcoding/hlf-jquery.svg?branch=master)](https://travis-ci.org/hlfcoding/hlf-jquery) ![Bower Version](https://img.shields.io/bower/v/hlf-jquery.svg)

jQuery extensions and plugins for quality UI. All modules have scoped debug
flags, jQuery namespaces, and no-conflict support with jQuery. All modules have
AMD-compatible versions, so you can pick and choose what to use. The only other
hard dependency is UnderscoreJS. RequireJS is suggested. Other dependencies
(see Bower file) are for tests and demos.
jQuery extensions and plugins for quality UI and implemented following best
practices. The [annotated source code][] is also available and include
documented examples.

The [annotated source code][] is also available.
All modules have scoped debug flags, jQuery namespaces, and no-conflict support
with jQuery. They are exported using [UMD]() and work with AMD, Browserify, or
plain. Only other dependency is UnderscoreJS. Other Bower dependencies are for
tests and demos.

## Extensions
## Plugins

All extensions should have test pages.
All plugins should have test pages with documented source. Please use them as
usage examples. Plugins should also have sample styles, and some have required
styles. When possible, styles are made customizeable as SCSS mixins.

### Core
### [HLF Tip][]

Main features:
Main features summary:

- Generate jQuery plugin methods from plugin definitions.
- Helpers to create mixins that can be used for plugin API.
- Provide no-conflict support.
- Based on hover 'intent' and prevents redundant toggling or DOM thrashing.
- Re-use the same tip for a group of triggers to keep DOM light.
- Aware of available space surrounding the triggering element.
- Has an extended, 'snapping' version that only follows the mouse on one axis.
The tip snaps to the trigger's edge on the other axis.

### Event
Short examples:

Main features:
```js
$('.avatars').find('img[alt]').tip(); // Tips will follow cursor.
$('nav.bar').find('a[title]').snapTip({
snap: { toXAxis: true } // Tips will only follow along x axis.
});
$('article').find('a[title]').snapTip() // Tip will not follow.
```

- Hover-intent provides rate-limited versions of mouseenter and mouseleave
events through a customizable delay.
See [Tip's visual tests][] for more examples.

## Plugins

All plugins should have test pages and sample styles. Some plugins may have
required styles. When possible, styles are made customizeable as SCSS mixins.
## Extensions

### HLF Tip
All extensions should be covered by QUnit tests.

A [visual test for Tip][] is available.
### [HLF Core][]

Main features:

- Uses custom hover intent events that allow for custom delays.
- Re-use the same tip for a group of triggers.
- Has a snapping extension that allows snapping to the trigger or tracking in
either direction.
- Generate jQuery plugin methods from plugin definitions.
- Helpers to create mixins that can be used for plugin API.
- Provide no-conflict support.

Additional features:
See [Core's unit tests][] for examples.

- Sample styling that draws tip stems with CSS borders.
- Detailed API.
### HLF Event

Example:
Main features:

```javascript
$('.article-1').find('a[title]').tip(); // Tips will follow cursor.
$('.article-2').find('a[title]').snapTip(); // Tips will remain affixed.
```
- Hover-intent provides rate-limited versions of mouseenter and mouseleave
events through a customizable delay.

See visual tests for more examples.
## Plugins Coming Soon

### HLF Editable

A [(WIP) visual test for Editable][] is available.

Main features:

- Uses mixins for encapsulate editing behaviors, so plugin instances can be
Expand Down Expand Up @@ -90,6 +91,7 @@ Start off with `npm install`.
[
"dist/*",
"docs/*",
"release/*",
"tests/*.css",
"tests/*.js"
]
Expand Down Expand Up @@ -122,6 +124,11 @@ The MIT License (MIT)
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

[UMD]: https://github.com/umdjs/umd
[annotated source code]: http://hlfcoding.github.io/hlf-jquery/docs/index.html
[visual test for Tip]: http://hlfcoding.github.io/hlf-jquery/tests/tip.visual.html
[(WIP) visual test for Editable]: http://hlfcoding.github.io/hlf-jquery/tests/editable.visual.html
[HLF Tip]: http://hlfcoding.github.io/hlf-jquery/docs/src/js/jquery.hlf.tip.html
[Tip's visual tests]: http://hlfcoding.github.io/hlf-jquery/tests/tip.visual.html
[HLF Core]: http://hlfcoding.github.io/hlf-jquery/docs/src/js/jquery.extension.hlf.core.html
[Core's unit tests]: http://localhost/hlf-jquery/tests/core.unit.html
[HLF Editable]: http://hlfcoding.github.io/hlf-jquery/docs/src/js/jquery.hlf.editable.html
[Editable's visual tests]: http://hlfcoding.github.io/hlf-jquery/tests/editable.visual.html
2 changes: 2 additions & 0 deletions build/docs.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
grunt = require 'grunt'

# For working docs generation, disable automatic trailing whitespace trimming.

module.exports =

clean: [
Expand Down
186 changes: 92 additions & 94 deletions release/jquery.extension.hlf.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,28 @@
/*
HLF Core jQuery Extension
=========================
Released under the MIT License
Written with jQuery 1.7.2
*/

(function() {
var slice = [].slice,
hasProp = {}.hasOwnProperty,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

(function(extension) {
if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
return define(['jquery', 'underscore'], extension);
(function(root, factory) {
if (typeof define === 'function' && (define.amd != null)) {
return define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {
return module.exports = factory(require('jquery', require('underscore')));
} else {
return extension(jQuery, _);
return factory(jQuery, _, jQuery.hlf);
}
})(function($, _) {
var _createPluginAPIAdditions, _createPluginInstance, _noConflicts, hlf, safeSet;
})(this, function($, _) {
var _createPluginAPIAdditions, _createPluginInstance, _noConflicts, _safeSet, hlf;
hlf = {
debug: true,
toString: _.memoize(function(context) {
return 'hlf';
})
};
_noConflicts = [];
_.extend(hlf, {
}),
noConflict: function() {
var fn;
return ((function() {
Expand All @@ -38,83 +35,10 @@ Written with jQuery 1.7.2
}
return results;
})()).length;
},
debugLog: hlf.debug === false ? $.noop : (console.log.bind ? console.log.bind(console) : console.log)
});
_createPluginInstance = function($el, options, $context, namespace, apiClass, apiMixins, mixinFilter, createOptions) {
var $root, data, deep, finalOptions, instance, otherMixins;
data = $el.data(namespace.toString('data'));
finalOptions = options;
if ($.isPlainObject(data)) {
finalOptions = $.extend((deep = true), {}, options, data);
$root = $el;
} else if (createOptions.asSharedInstance) {
$root = $context;
} else {
$root = $el;
}
if (apiClass != null) {
instance = new apiClass($el, finalOptions, $context);
if (createOptions.baseMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.baseMixins)));
}
if (createOptions.apiMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.apiMixins)));
}
} else if (apiMixins != null) {
instance = {
$el: $el,
options: finalOptions
};
if (createOptions.baseMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.baseMixins)));
}
hlf.applyMixin(instance, namespace, apiMixins.base);
otherMixins = _.chain(apiMixins).filter(mixinFilter, instance).values().without(apiMixins.base).value();
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(otherMixins)));
}
if (createOptions.compactOptions === true) {
$.extend((deep = true), instance, finalOptions);
delete instance.options;
} else {
if (finalOptions.selectors != null) {
instance.selectors = finalOptions.selectors;
}
if (finalOptions.classNames != null) {
instance.classNames = finalOptions.classNames;
}
}
if (createOptions.autoSelect === true && _.isFunction(instance.select)) {
instance.select();
}
if (instance.cls !== $.noop) {
$root.addClass(instance.cls());
}
if (_.isFunction(instance.init)) {
instance.init();
} else if (apiClass == null) {
hlf.debugLog('ERROR: No `init` method on instance.', instance);
}
return $root.data(instance.attr(), instance);
};
_createPluginAPIAdditions = function(name, namespace) {
return {
evt: _.memoize(function(name) {
return "" + name + (namespace.toString('event'));
}),
attr: _.memoize(function(name) {
name = name != null ? "-" + name : '';
return namespace.toString('data') + name;
}),
cls: namespace.toString('class') === namespace.toString() ? $.noop : _.memoize(function(name) {
name = name != null ? "-" + name : '';
return namespace.toString('class') + name;
}),
debugLog: namespace.debug === false ? $.noop : function() {
return hlf.debugLog.apply(hlf, [namespace.toString('log')].concat(slice.call(arguments)));
}
};
};
hlf.debugLog = hlf.debug === false ? $.noop : (console.log.bind ? console.log.bind(console) : console.log);
_noConflicts = [];
_.extend(hlf, {
createPlugin: function(createOptions) {
var _noConflict, _plugin, apiAdditions, apiClass, apiMixins, deep, mixinFilter, name, namespace, plugin, safeName;
Expand Down Expand Up @@ -201,6 +125,80 @@ Written with jQuery 1.7.2
}
});
_.bindAll(hlf, 'createPlugin');
_createPluginInstance = function($el, options, $context, namespace, apiClass, apiMixins, mixinFilter, createOptions) {
var $root, data, deep, finalOptions, instance, otherMixins;
data = $el.data(namespace.toString('data'));
finalOptions = options;
if ($.isPlainObject(data)) {
finalOptions = $.extend((deep = true), {}, options, data);
$root = $el;
} else if (createOptions.asSharedInstance) {
$root = $context;
} else {
$root = $el;
}
if (apiClass != null) {
instance = new apiClass($el, finalOptions, $context);
if (createOptions.baseMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.baseMixins)));
}
if (createOptions.apiMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.apiMixins)));
}
} else if (apiMixins != null) {
instance = {
$el: $el,
options: finalOptions
};
if (createOptions.baseMixins != null) {
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(createOptions.baseMixins)));
}
hlf.applyMixin(instance, namespace, apiMixins.base);
otherMixins = _.chain(apiMixins).filter(mixinFilter, instance).values().without(apiMixins.base).value();
hlf.applyMixins.apply(hlf, [instance, namespace].concat(slice.call(otherMixins)));
}
if (createOptions.compactOptions === true) {
$.extend((deep = true), instance, finalOptions);
delete instance.options;
} else {
if (finalOptions.selectors != null) {
instance.selectors = finalOptions.selectors;
}
if (finalOptions.classNames != null) {
instance.classNames = finalOptions.classNames;
}
}
if (createOptions.autoSelect === true && _.isFunction(instance.select)) {
instance.select();
}
if (instance.cls !== $.noop) {
$root.addClass(instance.cls());
}
if (_.isFunction(instance.init)) {
instance.init();
} else if (apiClass == null) {
hlf.debugLog('ERROR: No `init` method on instance.', instance);
}
return $root.data(instance.attr(), instance);
};
_createPluginAPIAdditions = function(name, namespace) {
return {
evt: _.memoize(function(name) {
return "" + name + (namespace.toString('event'));
}),
attr: _.memoize(function(name) {
name = name != null ? "-" + name : '';
return namespace.toString('data') + name;
}),
cls: namespace.toString('class') === namespace.toString() ? $.noop : _.memoize(function(name) {
name = name != null ? "-" + name : '';
return namespace.toString('class') + name;
}),
debugLog: namespace.debug === false ? $.noop : function() {
return hlf.debugLog.apply(hlf, [namespace.toString('log')].concat(slice.call(arguments)));
}
};
};
_.extend(hlf, {
applyMixin: function(context, dependencies, mixin) {
var handlerNames, i, len, method, mixinToApply, name, onceMethods, prop;
Expand Down Expand Up @@ -345,7 +343,7 @@ Written with jQuery 1.7.2
}
}
});
safeSet = function(key, toContext, fromContext) {
_safeSet = function(key, toContext, fromContext) {
var _oldValue;
if (toContext == null) {
toContext = $;
Expand All @@ -359,12 +357,12 @@ Written with jQuery 1.7.2
return toContext[key] = _oldValue;
});
};
safeSet('applyMixin');
safeSet('applyMixins');
safeSet('createMixin');
safeSet('createPlugin');
safeSet('mixinOnceNames');
safeSet('mixins');
_safeSet('applyMixin');
_safeSet('applyMixins');
_safeSet('createMixin');
_safeSet('createPlugin');
_safeSet('mixinOnceNames');
_safeSet('mixins');
$.hlf = hlf;
return $.hlf;
});
Expand Down
Loading

0 comments on commit 96f6890

Please sign in to comment.