diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..56d9941 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[Makefile] +charset = utf-8 +indent_style = tabs +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore index 496fe9b..638ec35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.DS_Store -node_modules \ No newline at end of file +node_modules +npm-debug.log diff --git a/.travis.yml b/.travis.yml index 14efc10..c7c689e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,2 @@ node_js: - - "0.10" -before_install: - - npm install -g grunt-cli - - "export PHANTOMJS_BIN=`which phantomjs`" -install: - - "npm install" -script: - - grunt test \ No newline at end of file + - "0.10" \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 3540d0f..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,80 +0,0 @@ -module.exports = function(grunt) { - 'use strict'; - - grunt.initConfig({ - jshint: { - files: ['gruntfile.js', 'app/*.js'], - options: { - eqeqeq: true, - eqnull: true, - latedef: true, - undef: true, - globalstrict: true, - force: true, - globals: { - jQuery: true, - console: true, - module: true, - document: true, - Ember: true, - $: true, - App: true - } - } - }, - - concat: { - test_libs: { - src: ['test/libs/jquery-2.1.1.js'], - dest: 'test/lib.js' - }, - }, - - uglify: { - build: { - src: ['app/focus-element-overlay.js'], - dest: 'app/focus-element-overlay.min.js' - } - }, - - qunit: { - all: { - options: { - urls: [ - 'http://localhost:9092/index.html' - ], - force: true - } - } - }, - - watch: { - tests: { - files: ['test/**/*.js'], - tasks: ['qunit'], - options: { - debounceDelay: 100 - } - } - }, - connect: { - test: { - options: { - port: 9092, - base: ['.', 'test'] - } - } - } - }); - - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-contrib-qunit'); - - grunt.registerTask('release', ['jshint', 'uglify']); - grunt.registerTask('test', ['concat:test_libs', 'connect:test', 'qunit']); - grunt.registerTask('default', ['test', 'watch']); -}; \ No newline at end of file diff --git a/LICENCE b/LICENCE index d08d630..a60b4cb 100644 --- a/LICENCE +++ b/LICENCE @@ -1,6 +1,7 @@ The MIT License (MIT) -Copyright (c) 2014 Hector Leon Zarco Garcia +Copyright (c) 2015 Hector Leon Zarco Garcia +Copyright (c) 2015 Tomas Aparicio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f582b54 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +VERSION = 0.1.0 +UGLIFYJS = ./node_modules/.bin/uglifyjs +MOCHA_PHANTOM = ./node_modules/.bin/mocha-phantomjs +HTTP_SERVER = ./node_modules/.bin/http-server +BANNER = "/*! focusable - v$(VERSION) - MIT License - https://github.com/zzarcon/focusable */" + +default: all +all: test +browser: uglify +test: browser mocha + +uglify: + $(UGLIFYJS) focusable.js --mangle --preamble $(BANNER) --source-map focusable.min.js.map --source-map-url http://cdn.rawgit.com/zzarcon/focusable/$(VERSION)/focusable.min.js.map > focusable.min.js + +mocha: + #$(MOCHA_PHANTOM) --reporter spec --ui bdd test/runner.html + +demo: browser + $(HTTP_SERVER) -p 8000 . + +loc: + wc -l focusable.js + +gzip: + gzip -c focusable.js | wc -c diff --git a/README.md b/README.md index 28f51fb..e25164a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ -Focusable [![Build Status](https://travis-ci.org/zzarcon/focusable.svg?branch=master)](https://travis-ci.org/zzarcon/focusable) -============= -An awesome and lightweight library for performing spotlight in your DOM elements, setting an animated overlay to the rest of the page. -You can find a [live demo here](http://zzarcon.github.io/focusable/). +# Focusable [![Build Status](https://travis-ci.org/zzarcon/focusable.svg?branch=master)](https://travis-ci.org/zzarcon/focusable) [![Version](https://img.shields.io/bower/v/focusable.svg)](https://github.com/zzarcon/focusable/releases) [![Gitter chat](https://badges.gitter.im/zzarcon/focusable.png)](https://gitter.im/zzarcon/focusable) [![Stories in Ready](https://badge.waffle.io/zzarcon/focusable.png?label=ready&title=Ready)](https://waffle.io/zzarcon/focusable) -### Showcase +A lightweight and dependency-free micro library to easily spotlight DOM elements + +You can find a live demo [here](http://zzarcon.github.io/focusable/) + +## Showcase ![](https://raw.github.com/zzarcon/focus-element-overlay/master/showcase/list.gif) @@ -11,33 +12,68 @@ You can find a [live demo here](http://zzarcon.github.io/focusable/). ![](https://raw.github.com/zzarcon/focus-element-overlay/master/showcase/elements.gif) -### API -###### Set spotlight (jQuery style) -```javascript -$('#my-element').setFocus(options); +## Installation + +Install via [Bower](http://bower.io) +```bash +bower install focusable +``` + +Install via [Component](http://component.github.io) +```bash +component install zzarcon/focusable +``` + +Install via [npm](http://npmjs.org) +```bash +npm install focuable +``` + +Or loading the script remotely +```html + ``` -###### Set spotlight (through library) + +## Browser Support + +![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png) +--- | --- | --- | --- | --- | ++5 | +3.5 | +9 | +10 | +5 | + +## API + +###### Set spotlight using jQuery/Zepto selector + ```javascript -Focusable.setFocus($('#my-element'), options); +Focusable($('#my-element'), options) ``` -###### Refresh current focused element + +###### Set spotlight + ```javascript -Focusable.refresh(); +Focusable(document.querySelector('#my-element'), options) ``` + ###### Hide spotlight + ```javascript -Focusable.hide(); +Focusable.hideAll() ``` -###### Get focused element + +###### Get focused DOM elements + ```javascript -Focusable.getActiveElement(); +Focusable.getActiveElements() ``` + ###### Get options + ```javascript -Focusable.getOptions(); +Focusable.getOptions() ``` -###### Options +##### Options + Property | Value | Default | Description ------------ | ------------- | ------------- | ------------- fadeDuration | Number | 700 | Duration of the overlay transition (milliseconds). @@ -45,22 +81,47 @@ hideOnClick | Boolean | false | Hides the overlay when the user click into it. hideOnESC | Boolean | false | Hides the overlay when the user press Esc. findOnResize | Boolean | false | Refind the element in the DOM in case that the element don't still exists. -###### Runing tests -* `npm install` -* `grunt` -* See the result of testsuite in [http://localhost:9092](http://localhost:9092) +## Development + +Clone this repository and switch into it +```bash +git clone https://github.com/zzarcon/focusable && cd focusable +``` + +Install development dependencies +```bash +npm install +``` + +Run tests +```bash +make test +``` -###### Dependencies -- jQuery +Run the example demo and open [localhost:8000](http://localhost:8000) +``` +make demo +``` -###### Contributing +## Contributing 0. Check [open issues](https://github.com/zzarcon/focusable/issues) + 1. [Fork it](https://github.com/zzarcon/focusable/fork) + 2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) + +3. Commit your changes (`git commit -am 'feat(name): description'`) + 4. Push to the branch (`git push origin my-new-feature`) -5. Create a new Pull Request -###### Author -You can follow me on Twitter - https://twitter.com/zzarcon +5. Create a new [Pull Request](https://github.com/zzarcon/focusable/compare/) + +## Authors + +- [Hector Zarcon](https://github.com/zzarcon) +- [Tomas Aparicio](https://github.com/h2non) + +## License + +MIT (c) 2015 - Hector Zarco and contributors diff --git a/app/focus-element-overlay.js b/app/focus-element-overlay.js deleted file mode 100644 index e20ac62..0000000 --- a/app/focus-element-overlay.js +++ /dev/null @@ -1,208 +0,0 @@ -/*! - * Focus element overlay (Focusable) v0.1 - * https://github.com/zzarcon/focusable - * - * Copyright (c) 2014 @zzarcon - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Date: 2014-11-18 - */ - -(function(exports) { - var $columnWrapper = null; - var $element = null; - var isVisible = false; - var columnClass = 'focusable-column'; - var columnSelector = '.' + columnClass; - var options = { - fadeDuration: 700, - hideOnClick: false, - hideOnESC: false, - findOnResize: false - }; - - $(document).ready(setup); - - function setup() { - $columnWrapper = $('body'); - createPlugin(); - addStylesheet(); - addEvents(); - } - - /** - * Defines Focusable as jQuey plugin - * @return {jQuery object} this - */ - function createPlugin() { - if (!window.jQuery || !window.$ || !window.$.fn) { - return; - } - - $.fn.focusable = function(options) { - Focusable.setFocus(this, options); - return this; - }; - } - - function addEvents() { - $columnWrapper.on('click', columnSelector, clickOnOverlay); - $(window).on("resize", resizeHandler); - $(window).on("keyup", keyupHandler); - } - - function resizeHandler() { - if (!$element) { - return; - } - //Refind the element - $element = options.findOnResize ? $($element.selector) : $element; - - refresh(); - } - - function keyupHandler(e) { - options.hideOnESC && e.keyCode === 27 && isVisible && hide(); - } - - function clickOnOverlay() { - if (!options.hideOnClick) { - return; - } - - hide(); - } - - function setFocus($el, userOptions) { - $('body').css('overflow', 'hidden'); - options = $.extend(options, userOptions); - $element = $el; - createColumns(); - $columnWrapper.find(columnSelector).fadeIn(options.fadeDuration); - }; - - function clearColumns() { - $columnWrapper.find(columnSelector).remove(); - } - - function hide() { - isVisible = false; - $element = null; - $('body').css('overflow', ''); - $columnWrapper.find(columnSelector).fadeOut(options.fadeDuration, clearColumns); - } - - function createColumns(forceVisibility) { - if (!$element) { - return; - } - - var createdColumns = 0; - isVisible = true; - clearColumns(); - - while (createdColumns < 4) { - createColumn(createdColumns); - createdColumns++; - } - - if (forceVisibility === true) { - $(columnSelector).show(); - } - } - - function createColumn(index) { - var offset = $element.offset(); - var top = 0, left = 0, width = px($element.outerWidth()), height = "100%"; - var styles = ''; - - switch (index) { - case 0: - width = px(offset.left); - break; - case 1: - left = px(offset.left); - height = px(offset.top); - break; - case 2: - left = px(offset.left); - top = px($element.outerHeight() + offset.top); - break; - case 3: - width = "100%"; - left = px(($element.outerWidth() + offset.left)); - break; - } - - styles = 'top:' + top + ';left:' + left + ';width:' + width + ';height:' + height; - $columnWrapper.prepend('
'); - } - - /** - * Prepend px to the received value - * @return {String} - */ - function px(value) { - return value + 'px'; - } - - /** - * Create dynamic CSS rules required by the library; - * Using this approach we avoid to include an external css file. - * @return {Void} - */ - function addStylesheet() { - var sheet = (function() { - var style = document.createElement("style"); - - style.appendChild(document.createTextNode("")); - document.head.appendChild(style); - - return style.sheet; - })(); - - sheet.insertRule(columnSelector + "{ display:none; position: absolute; z-index: 9999; background: rgba(0,0,0,0.8); }", 0); - } - - function getActiveElement() { - return $element; - } - - function getOptions() { - return options; - } - - function getVisibility() { - return isVisible; - } - - function refresh() { - createColumns(true); - } - - exports.Focusable = { - setFocus: setFocus, - hide: hide, - refresh: refresh, - getActiveElement: getActiveElement, - getOptions: getOptions, - isVisible: getVisibility - }; -})(window); \ No newline at end of file diff --git a/app/focus-element-overlay.min.js b/app/focus-element-overlay.min.js deleted file mode 100644 index 9b22523..0000000 --- a/app/focus-element-overlay.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){function b(){r=$("body"),c(),n(),d()}function c(){window.jQuery&&window.$&&window.$.fn&&($.fn.focusable=function(a){return Focusable.setFocus(this,a),this})}function d(){r.on("click",v,g),$(window).on("resize",e),$(window).on("keyup",f)}function e(){s&&(s=w.findOnResize?$(s.selector):s,k())}function f(a){w.hideOnESC&&27===a.keyCode&&t&&j()}function g(){w.hideOnClick&&j()}function h(a,b){$("body").css("overflow","hidden"),w=$.extend(w,b),s=a,k(),r.find(v).fadeIn(w.fadeDuration)}function i(){r.find(v).remove()}function j(){t=!1,s=null,$("body").css("overflow",""),r.find(v).fadeOut(w.fadeDuration,i)}function k(){if(s){var a=0;for(t=!0,i();4>a;)l(a),a++}}function l(a){var b=s.offset(),c=0,d=0,e=m(s.outerWidth()),f="100%",g="";switch(a){case 0:e=m(b.left);break;case 1:d=m(b.left),f=m(b.top);break;case 2:d=m(b.left),c=m(s.outerHeight()+b.top);break;case 3:e="100%",d=m(s.outerWidth()+b.left)}g="top:"+c+";left:"+d+";width:"+e+";height:"+f,r.prepend('
')}function m(a){return a+"px"}function n(){var a=function(){var a=document.createElement("style");return a.appendChild(document.createTextNode("")),document.head.appendChild(a),a.sheet}();a.insertRule(v+"{ display:none; position: absolute; background: rgba(0,0,0,0.8); }",0)}function o(){return s}function p(){return w}function q(){return t}var r=null,s=null,t=!1,u="focusable-column",v="."+u,w={fadeDuration:700,hideOnClick:!1,hideOnESC:!1,findOnResize:!1};$(document).ready(b),a.Focusable={setFocus:h,hide:j,refresh:k,getActiveElement:o,getOptions:p,isVisible:q}}(window); \ No newline at end of file diff --git a/bower.json b/bower.json index 7432d24..f789f9c 100644 --- a/bower.json +++ b/bower.json @@ -1,24 +1,31 @@ { - "name": "Focusable element", - "version": "0.0.1", + "name": "focusable", + "version": "0.1.0", + "license": "MIT", + "description": "Spotlight on DOM elements adding an overlay on the rest of the page", + "repository": "zzarcon/focusable", "authors": [ - "zzarcon" + "Hector Zarco (zzarcon)", + "Tomas Aparicio (h2non)" ], - "description": "Set focus on DOM element adding overlay to the rest of the page", - "main": "app/focus-element-overlay.js", + "main": "focusable.js", "keywords": [ - "javascript", "focus", "dom", "element", "overlay", - "spotlight", - "jQuery" + "spotlight" ], - "license": "MIT", - "homepage": "www.github.com/zzarcon/focus-element-overlay", "ignore": [ "sample-app", - "gulpfile.js" + ".gitignore", + ".travis.yml", + ".editorconfig", + "Makefile", + "package.json", + "component.json", + "test", + "showcase", + "example" ] -} \ No newline at end of file +} diff --git a/component.json b/component.json new file mode 100644 index 0000000..a2ce718 --- /dev/null +++ b/component.json @@ -0,0 +1,24 @@ +{ + "name": "focusable", + "version": "0.1.0", + "license": "MIT", + "description": "Spotlight on DOM elements adding an overlay on the rest of the page", + "repository": "zzarcon/focusable", + "authors": [ + "Hector Zarco (zzarcon)", + "Tomas Aparicio (h2non)" + ], + "main": "focusable.js", + "scripts": [ + "focusable.js", + "focusable.min.js", + "focusable.min.js.map" + ], + "keywords": [ + "focus", + "dom", + "element", + "overlay", + "spotlight" + ] +} diff --git a/sample_app/demo.js b/example/demo.js similarity index 85% rename from sample_app/demo.js rename to example/demo.js index 814d5fe..27dfe47 100644 --- a/sample_app/demo.js +++ b/example/demo.js @@ -2,13 +2,15 @@ $(document).ready(init); function init() { + var focusElement = null + $('.show').on('click', show); $('.hide').on('click', hide); function show() { var selector = $(this).attr('data-selector'); var options = getOptions(); - Focusable.setFocus($(selector), options); + focusElement = Focusable($(selector), options); } function hide() { @@ -22,6 +24,6 @@ hideOnClick: $('#hide-on-click').is(':checked'), hideOnESC: $('#hide-on-esc').is(':checked'), findOnResize: $('#find-on-resize').is(':checked') - }; + } } -})(); \ No newline at end of file +})(); diff --git a/sample_app/index.html b/example/index.html similarity index 91% rename from sample_app/index.html rename to example/index.html index 3091192..390808c 100644 --- a/sample_app/index.html +++ b/example/index.html @@ -4,10 +4,10 @@ Focus element overlay sample app - +