├── .gitignore ├── livenavigate ├── .gitignore ├── example │ ├── link2.html │ ├── link1.html │ └── index.html ├── CHANGELOG ├── jquery.livenavigate.js ├── README.hashlisten.md ├── jquery.hashlisten.js └── README.md ├── History.md ├── instance ├── jquery.instance.js └── README.md ├── bower.json ├── package.json ├── selecttrap ├── selecttrap.css └── jquery.selecttrap.js ├── unorphan ├── jquery.unorphan.js └── README.md ├── console-shim └── console-shim.js ├── ensurevisible ├── README.md ├── jquery.ensurevisible.coffee └── jquery.ensurevisible.js ├── sort ├── README.md └── jquery.sort.js ├── ajaxsubmit └── jquery.ajaxsubmit.js ├── nomobilescroll └── jquery.nomobilescroll.js ├── scrollmonitor ├── scrollmonitor.coffee └── scrollmonitor.js ├── cycler ├── sample-1.md ├── README.md └── cycler.js ├── placeholder_polyfill └── jquery.placeholder_polyfill.js ├── ellipsify └── jquery.ellipsify.js ├── test ├── setup.js ├── selecttrap.js └── vendor │ └── jquery-1.5.2.js ├── fadeonload └── jquery.fadeonload.js ├── smartquotes └── jquery.smartquotes.js ├── micro_amd └── microalmond.js ├── pseudoinput └── jquery.pseudoinput.js ├── tabs └── jquery.tabs.js ├── hidpi └── jquery.hidpi.js ├── timer └── timer.js ├── buttonloading └── jquery.buttonloading.js ├── anchorjump └── jquery.anchorjump.js ├── scrollagent └── jquery.scrollagent.js ├── toggleable └── jquery.toggleable.js ├── scrope └── jquery.scrope.coffee ├── growl └── jquery.growl.js ├── preventoverscroll └── jquery.prevent_overscroll.js ├── size_responder └── size_responder.js ├── mailcheckhint └── jquery.mailcheckhint.js ├── fillsize └── jquery.fillsize.js ├── uiscreen └── jquery.uiscreen.js ├── README.textile ├── scrollstick └── jquery.scrollstick.js ├── autoexpand └── jquery.autoexpand.js └── paymentform └── jquery.paymentform.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /livenavigate/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.sw? 3 | .DS_Store 4 | Thumbs.db 5 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | ## v0.1.1 - October 20, 2014 2 | 3 | * Selecttrap: add support for hover. 4 | -------------------------------------------------------------------------------- /livenavigate/example/link2.html: -------------------------------------------------------------------------------- 1 |
2 | Hello from page 2! 3 |
4 | -------------------------------------------------------------------------------- /livenavigate/example/link1.html: -------------------------------------------------------------------------------- 1 |
2 | This is page 1. 3 | Don't forget to try the back button! 4 |
5 | -------------------------------------------------------------------------------- /livenavigate/CHANGELOG: -------------------------------------------------------------------------------- 1 | v0.1.1 2 | ------ 3 | 4 | - Add livenavigate. Hashlisten will now be an unmained repo--it 5 | will be maintained in the livenavigate repo instead. 6 | 7 | v0.1.0 - August 4, 2010 8 | ----------------------- 9 | 10 | - First version. 11 | -------------------------------------------------------------------------------- /instance/jquery.instance.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $.fn.instance = function (type) { 3 | var $this = this.first(); 4 | $this = $this.data('instance') || ($this.data('instance', $this) && $this); 5 | 6 | if ((type) && ((!$this._class) || ($this._class != type))) { 7 | $this.extend(type); 8 | $this._class = type; 9 | } 10 | 11 | return $this; 12 | }; 13 | })(jQuery); 14 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-stuff", 3 | "version": "0.1.1", 4 | "homepage": "https://github.com/rstacruz/jquery-stuff", 5 | "authors": [ 6 | "Rico Sta. Cruz " 7 | ], 8 | "description": "A collection of jQuery snippets", 9 | "keywords": [ 10 | "jquery" 11 | ], 12 | "license": "MIT", 13 | "ignore": [ 14 | "**/.*", 15 | "node_modules", 16 | "bower_components", 17 | "test", 18 | "tests" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-stuff", 3 | "description": "", 4 | "author": "Rico Sta. Cruz ", 5 | "version": "0.1.1", 6 | "scripts": { 7 | "test": "./node_modules/.bin/mocha -R spec", 8 | "autotest": "./node_modules/.bin/mocha --watch -R progress" 9 | }, 10 | "devDependencies": { 11 | "mocha": "~1.10.0", 12 | "chai": "~1.6.0", 13 | "jsdom": "~0.6.5", 14 | "supervisor": "~0.5.2", 15 | "sinon": "~1.7.2" 16 | }, 17 | "license": "MIT" 18 | } 19 | -------------------------------------------------------------------------------- /selecttrap/selecttrap.css: -------------------------------------------------------------------------------- 1 | .selecttrap { 2 | position: relative; 3 | display: inline-block; 4 | height: 26px; 5 | line-height: 26px; 6 | min-width: 100px; 7 | box-sizing: border-box; 8 | padding: 0 10px; } 9 | 10 | .selecttrap select { 11 | position: absolute; 12 | z-index: 1; 13 | height: 100%; 14 | width: 100%; 15 | left: 0; 16 | top: 0; 17 | background: white; 18 | border: 0; 19 | opacity: 0; } 20 | 21 | /* Customize me */ 22 | .selecttrap { 23 | background: #eee; 24 | border: solid 1px #ddd; 25 | border-radius: 2px; 26 | color: #333; } 27 | -------------------------------------------------------------------------------- /unorphan/jquery.unorphan.js: -------------------------------------------------------------------------------- 1 | /*! Unorphan (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/unorphan */ 3 | 4 | (function($) { 5 | $.fn.unorphan = function() { 6 | $(this).each(function() { 7 | var last = this.lastChild; 8 | 9 | if ((last) && (last.nodeType == 3)) { 10 | var text = last.nodeValue; 11 | var stripped = text.replace(/^\s*|\s*$/g, ' '); 12 | var spaces = stripped.match(/ /g).length; 13 | 14 | if (spaces > 1) { 15 | last.nodeValue = last.nodeValue.replace(/\s*([^\s]+\s*)$/g, '\xA0$1'); 16 | } 17 | } 18 | }); 19 | return this; 20 | }; 21 | })(jQuery); 22 | -------------------------------------------------------------------------------- /console-shim/console-shim.js: -------------------------------------------------------------------------------- 1 | /*! Console Shim (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/console-shim */ 3 | 4 | // Makes `console.log()` commands silently not fail if the current browser 5 | // doesn't have console API support. 6 | 7 | (function (console) { 8 | var methods = 'assert count debug dir dirxml error group groupCollapsed groupEnd info log markTimeline profile profileEnd table time timeEnd trace warn'.split(''); 9 | 10 | if (!console) console = window.console = {}; 11 | 12 | for (var i=0; i < methods.length; i++) { 13 | var fn = methods[i]; 14 | if (!console[fn]) console[fn] = (function() {}); 15 | } 16 | 17 | })(window.console); 18 | -------------------------------------------------------------------------------- /ensurevisible/README.md: -------------------------------------------------------------------------------- 1 | # Ensurevisible 2 | 3 | Example: 4 | 5 | ``` html 6 |
7 |
..
8 |
..
9 |
..
10 |
..
11 |
..
12 |
13 | ``` 14 | 15 | ``` css 16 | /* Items is a scrollable pane with a fixed height. */ 17 | .items { 18 | overflow: auto; 19 | height: 200px; } 20 | 21 | article { 22 | height: 50px; } 23 | ``` 24 | 25 | So `.items .active` should be *not* visible when `.items` is scrolled all the 26 | way up. 27 | 28 | ``` javascript 29 | $(".items .active").ensureVisible(); 30 | ``` 31 | 32 | After calling this, `.items` will scroll down just enough to reveal `.active`. 33 | 34 | 35 | -------------------------------------------------------------------------------- /livenavigate/jquery.livenavigate.js: -------------------------------------------------------------------------------- 1 | ;(function ($) { 2 | if (window.history.pushState) { 3 | $.navigate = function (href, silent) { 4 | window.history.pushState({ href: href }, "", href); 5 | if (silent !== true) { 6 | $(window).trigger('navigate', href); 7 | } 8 | }; 9 | 10 | var loaded = false; 11 | 12 | window.onpopstate = function (e, state) { 13 | if (!loaded) { loaded = true; return; } // Skip the first load 14 | $(window).trigger('navigate', window.location.pathname); 15 | }; 16 | } 17 | 18 | else { 19 | var skip = false; 20 | 21 | $.navigate = function (href, silent) { 22 | if (window.location.hash == '#!'+href) { return; } 23 | window.location.hash = "#!" + href; 24 | 25 | if (silent === true) { 26 | skip = true; 27 | } 28 | }; 29 | 30 | $.hashListen('!(.*)', function (href) { 31 | if (skip) { 32 | skip = false; 33 | } else { 34 | $(window).trigger('navigate', href); 35 | } 36 | }); 37 | } 38 | })(jQuery); 39 | -------------------------------------------------------------------------------- /sort/README.md: -------------------------------------------------------------------------------- 1 | # $.sort() 2 | Sorts the insides of a given element. 3 | 4 | ### Options 5 | 6 | * `via` (function, required) - should return the value to be sorted. 7 | * `items` (string) - the selector of the children. defaults to '\*'. 8 | * `order` (string) - the order ('desc' or 'asc'). defaults to 'asc'. 9 | 10 | ### Example 11 | 12 | ``` html 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
NumberName
48Rico
2Michael
52Ace
34 | ``` 35 | 36 | Simple example: 37 | 38 | ``` javascript 39 | $("table").sort({ 40 | via: function(tr) { return parseInt(tr.find('td:eq(1)').text()); }, 41 | }); 42 | ``` 43 | 44 | More complicated: 45 | 46 | ``` javascript 47 | $("table").sort({ 48 | via: function(tr) { return parseInt(tr.find('td:eq(1)').text()); }, 49 | items: 'tr:not(.heading)', 50 | order: 'desc' 51 | }); 52 | ``` 53 | -------------------------------------------------------------------------------- /ajaxsubmit/jquery.ajaxsubmit.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.ajaxSubmit (c) 2012, Rico Sta. Cruz. MIT License. 2 | * https://github.com/rstacruz/jquery-stuff/tree/master/ajaxsubmit */ 3 | 4 | // $.fn.ajaxSubmit() 5 | // Submits a given form via AJAX. Returns the AJAX object. 6 | // 7 | // The given `options` parameter is a dict object that will be passed onto as 8 | // options for `$.ajax()`. 9 | // 10 | // $("form#my-form").ajaxSubmit({ 11 | // success: function(data) { 12 | // alert("All done!"); 13 | // } 14 | // }); 15 | 16 | (function($) { 17 | $.fn.ajaxSubmit = function(options) { 18 | var $this = $(this).eq(0); 19 | 20 | if (!$this.is('form')) return false; 21 | 22 | var method = ($this.attr('method') || 'post').toLowerCase(); 23 | var url = $this.attr('action') || window.location.href; 24 | 25 | // Construct the options object to be passed to the AJAX request. 26 | if (!options) options = {}; 27 | options.url = url; 28 | options.method = options.method || method; 29 | options.data = $this.serialize(); 30 | 31 | return $.ajax(options); 32 | }; 33 | })(jQuery); 34 | -------------------------------------------------------------------------------- /nomobilescroll/jquery.nomobilescroll.js: -------------------------------------------------------------------------------- 1 | /*! --------------------------------------- 2 | * NoMobileScroll 3 | * http://github.com/rstacruz/jquery-stuff 4 | * ---------------------------------------- */ 5 | 6 | // Prevents iPad from scrolling. Great for fullscreen web apps. 7 | // 8 | // In addition to this JavaScript hack, you will also need to nest your scrollable areas: 9 | // 10 | // .scrollable, 11 | // .scrollable > div { 12 | // -webkit-overflow-scrolling: touch; 13 | // overflow: auto; 14 | // } 15 | // 16 | (function($) { 17 | $.noMobileScroll = function() { 18 | document.addEventListener('touchstart', function(e) { 19 | // Find the parent pane. 20 | var $pane; 21 | $(e.target).parents().each(function() { 22 | if ($pane) return; 23 | var $el = $(this); 24 | var flow = $el.css('overflow'); 25 | if ((flow === 'auto') || (flow === 'scroll')) { 26 | $pane = $el; 27 | } 28 | }); 29 | 30 | if ((!$pane) || ($pane[0].scrollHeight <= $pane.outerHeight())) { 31 | e.preventDefault(); 32 | } 33 | }); 34 | }; 35 | })(jQuery); 36 | 37 | -------------------------------------------------------------------------------- /scrollmonitor/scrollmonitor.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Monitors scrolling and executes something on different breakpoints. 3 | # 4 | # mon = monitor 5 | # if: (y) -> y < 300 6 | # enter: -> $('top').hide() 7 | # exit: -> $('top').show() 8 | # scroll: -> 9 | # 10 | # mon.update() 11 | # mon.enable() 12 | # mon.disable() 13 | # mon.status() #=> true/false 14 | ### 15 | 16 | window.ScrollMonitor = (options) -> 17 | last = null 18 | $window = $(window) 19 | 20 | # Build the callback 21 | update = -> 22 | y = $window.scrollTop() 23 | now = options.if(y) 24 | 25 | if last isnt now 26 | last = now 27 | 28 | if now and options.enter 29 | options.enter(y) 30 | else if !now and options.exit 31 | options.exit(y) 32 | 33 | if options.scroll 34 | options.scroll(y, now) 35 | 36 | # Bind it 37 | obj = 38 | update: update 39 | status: -> 40 | last 41 | enable: -> 42 | $window.on 'resize', update 43 | $window.on 'scroll', update 44 | @update() 45 | this 46 | disable: -> 47 | $window.off 'resize', update 48 | $window.off 'scroll', update 49 | this 50 | 51 | obj.enable() 52 | -------------------------------------------------------------------------------- /sort/jquery.sort.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.sort (c) 2012, Rico Sta. Cruz. MIT License. 2 | * https://github.com/rstacruz/jquery-stuff/tree/master/sort */ 3 | 4 | // $.fn.sort() 5 | // Sorts the insides of a given element. 6 | // Requires underscore.js. 7 | // 8 | // Options: 9 | // 10 | // * `via` (function, required) - should return the value to be sorted. 11 | // * `items` (string) - the selector of the children. defaults to '*'. 12 | // * `order` (string) - the order ('desc' or 'asc'). defaults to 'asc'. 13 | 14 | (function($, _) { 15 | $.fn.sort = function(options) { 16 | if (!options) options = {}; 17 | 18 | var via = options.via || function(el) { return el.text(); }; 19 | var sel = "> " + (options.items || '*'); 20 | var order = options.order || 'asc'; 21 | var parent = $(this); 22 | var list = []; 23 | 24 | // Build the list of elements while taking them out of the DOM. 25 | parent.find(sel).each(function() { list.push($(this).remove()); }); 26 | 27 | // Sort that list then add them back in. 28 | list = _.sortBy(list, via); 29 | if (order === 'desc') list.reverse(); 30 | _.each(list, function(element) { parent.append(element); }); 31 | 32 | return this; 33 | }; 34 | })(jQuery, _); 35 | -------------------------------------------------------------------------------- /cycler/sample-1.md: -------------------------------------------------------------------------------- 1 | ### HTML 2 | 3 | ``` html 4 |
5 |
    6 |
  • ... 7 |
  • ...
  • 8 |
  • ...
  • 9 |
10 |
11 | ``` 12 | 13 | ### CSS 14 | 15 | ``` sass 16 | # Stylus 17 | horizontal-slideshow(width, height) 18 | &, .slides, .slide 19 | display: block 20 | width: width 21 | height: height 22 | 23 | margin: 0 24 | padding: 0 25 | list-style: none 26 | 27 | & 28 | overflow: hidden 29 | position: relative 30 | 31 | .slides 32 | width: 99999px 33 | 34 | position: absolute 35 | top: 0 36 | left: 0 37 | 38 | .slide 39 | float: left 40 | 41 | 42 | .slideshow 43 | horizontal-slideshow(450px, 270px) 44 | ``` 45 | 46 | ### JS 47 | 48 | ``` javascript 49 | $(".slideshow").each(function() { 50 | var $slideshow = $(this); 51 | var $container = $slideshow.find('> .slides'); 52 | var $slides = $container.find('> .slide'); 53 | 54 | var width = $slideshow.width(); 55 | 56 | new Cycler($slides, { 57 | interval: 3000, 58 | onactivate: function(current, i, prev, j) { 59 | $container.animate({ left: -1 * width * i }); 60 | } 61 | }); 62 | }); 63 | ``` 64 | -------------------------------------------------------------------------------- /placeholder_polyfill/jquery.placeholder_polyfill.js: -------------------------------------------------------------------------------- 1 | /*! placeholderpoly (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/placeholder_polyfill */ 3 | 4 | // Crappiest placeholder polyfill ever. 5 | // Not as good as the others, but requires the least amount of effort. 6 | // 7 | // How to use: 8 | // 9 | // * Just load it. 10 | // 11 | // Restrictions 12 | // 13 | // * Passwords are silly. 14 | // * Placeholder disappears on focus. 15 | 16 | (function($, placeholder) { 17 | var alreadySupported = (placeholder in document.createElement('input')); 18 | if (alreadySupported) return; 19 | 20 | $('['+placeholder+']').live(placeholder+':clear focus', function() { 21 | var $input = $(this); 22 | var place = $input.attr(placeholder); 23 | 24 | if ($input.val() === place) $input.removeClass(placeholder).val(''); 25 | }); 26 | 27 | $('['+placeholder+']').live(placeholder+':restore blur', function() { 28 | var $input = $(this); 29 | var place = $input.attr(placeholder); 30 | 31 | if ($input.val() === '') $input.addClass(placeholder).val(place); 32 | }); 33 | 34 | $(function() { 35 | $('['+placeholder+']').trigger(placeholder+':restore'); 36 | }); 37 | })(jQuery, 'placeholder'); 38 | -------------------------------------------------------------------------------- /ensurevisible/jquery.ensurevisible.coffee: -------------------------------------------------------------------------------- 1 | # ### jQuery.fn.ensureVisible([speed], [callback]) 2 | # ### jQuery.fn.ensureVisible({ offset: 30, speed: 50 }, [speed], [callback]) 3 | # Ensures that a given item is visible in its scroll pane. 4 | jQuery.fn.ensureVisible = -> 5 | args = Array::slice.apply arguments 6 | opts = 7 | speed: 400 8 | offset: 0 9 | 10 | $.extend opts, args.shift() if typeof args[0] is 'object' 11 | opts.speed = args.shift() if typeof args[0] is 'number' 12 | opts.callback = args.shift() if typeof args[0] is 'function' 13 | 14 | parent = @offsetParent() 15 | oflow = parent.css('overflow-y') or parent.css('overflow') 16 | 17 | return this unless oflow is 'auto' or oflow is 'scroll' 18 | 19 | paneMin = parent.scrollTop() 20 | paneMax = paneMin + parent.innerHeight() 21 | 22 | itemMin = @position().top + paneMin - opts.offset 23 | itemMax = itemMin + @outerHeight() + opts.offset 24 | 25 | if itemMax > paneMax 26 | parent.stop().animate scrollTop: itemMax - parent.innerHeight(), 27 | opts.speed, opts.callback 28 | 29 | else if itemMin < paneMin 30 | parent.stop().animate scrollTop: itemMin, 31 | opts.speed, opts.callback 32 | 33 | else 34 | opts.callback() if typeof opts.callback is 'function' 35 | 36 | this 37 | -------------------------------------------------------------------------------- /ensurevisible/jquery.ensurevisible.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | jQuery.fn.ensureVisible = function() { 4 | var args, itemMax, itemMin, oflow, opts, paneMax, paneMin, parent; 5 | args = Array.prototype.slice.apply(arguments); 6 | opts = { 7 | speed: 400, 8 | offset: 0 9 | }; 10 | if (typeof args[0] === 'object') $.extend(opts, args.shift()); 11 | if (typeof args[0] === 'number') opts.speed = args.shift(); 12 | if (typeof args[0] === 'function') opts.callback = args.shift(); 13 | parent = this.offsetParent(); 14 | oflow = parent.css('overflow-y') || parent.css('overflow'); 15 | if (!(oflow === 'auto' || oflow === 'scroll')) return this; 16 | paneMin = parent.scrollTop(); 17 | paneMax = paneMin + parent.innerHeight(); 18 | itemMin = this.position().top + paneMin - opts.offset; 19 | itemMax = itemMin + this.outerHeight() + opts.offset; 20 | if (itemMax > paneMax) { 21 | parent.stop().animate({ 22 | scrollTop: itemMax - parent.innerHeight() 23 | }, opts.speed, opts.callback); 24 | } else if (itemMin < paneMin) { 25 | parent.stop().animate({ 26 | scrollTop: itemMin 27 | }, opts.speed, opts.callback); 28 | } else { 29 | if (typeof opts.callback === 'function') opts.callback(); 30 | } 31 | return this; 32 | }; 33 | 34 | }).call(this); 35 | -------------------------------------------------------------------------------- /scrollmonitor/scrollmonitor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Monitors scrolling and executes something on different breakpoints. 3 | * 4 | * mon = new ScrollMonitor({ 5 | * if: (y) -> y < 300 6 | * enter: -> $('top').hide() 7 | * exit: -> $('top').show() 8 | * scroll: -> 9 | * }) 10 | * 11 | * mon.update() 12 | * mon.enable() 13 | * mon.disable() 14 | * mon.status() #=> true/false 15 | */ 16 | 17 | window.ScrollMonitor = function(options) { 18 | var last = null; 19 | var $window = $(window); 20 | 21 | function update() { 22 | var y = $window.scrollTop(); 23 | var now = options["if"](y); 24 | 25 | if (last !== now) { 26 | last = now; 27 | if (now && options.enter) 28 | options.enter(y); 29 | else if (!now && options.exit) 30 | options.exit(y); 31 | } 32 | if (options.scroll) 33 | return options.scroll(y, now); 34 | } 35 | 36 | var obj = { 37 | update: update, 38 | status: function() { 39 | return last; 40 | }, 41 | enable: function() { 42 | $window.on('resize', update); 43 | $window.on('scroll', update); 44 | this.update(); 45 | return this; 46 | }, 47 | disable: function() { 48 | $window.off('resize', update); 49 | $window.off('scroll', update); 50 | return this; 51 | } 52 | }; 53 | 54 | return obj.enable(); 55 | }; 56 | -------------------------------------------------------------------------------- /ellipsify/jquery.ellipsify.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.ellipsify (c) 2011-2012, Rico Sta. Cruz. MIT License. 2 | * Based on http://snipplr.com/view/46615 3 | * https://github.com/rstacruz/jquery-stuff/tree/master/ellipsify */ 4 | 5 | // Usage: 6 | // $("article h2").ellipsify(); 7 | 8 | (function($) { 9 | $.fn.ellipsify = function() { 10 | var $this = $(this); 11 | 12 | if ($this.length > 1) { 13 | return $this.each(function() { $(this).ellipsify(); }); 14 | } 15 | 16 | var $clone = $this.clone(); 17 | var text = $this.html(); 18 | var shortened = false; 19 | var offset = 2; 20 | 21 | $clone.css({ 22 | display: 'none', 23 | position: 'absolute', 24 | overflow: 'visible', 25 | width: $this.width(), 26 | height: 'auto'}); 27 | 28 | $this.after($clone); 29 | 30 | function tooBig() { 31 | return $clone.outerHeight() > ($this.outerHeight() + offset); 32 | } 33 | 34 | while (text.length > 0 && tooBig()) { 35 | shortened = true; 36 | text = text.substr(0, text.lastIndexOf(' ')); 37 | $clone.html(text + '…'); 38 | } 39 | 40 | // Tooltip 41 | if ((shortened) && (!$this.attr('title'))) { 42 | $this.attr('title', $this.text()); 43 | } 44 | 45 | $this.html($clone.html()); 46 | $clone.remove(); 47 | 48 | return this; 49 | }; 50 | })(jQuery); 51 | -------------------------------------------------------------------------------- /livenavigate/README.hashlisten.md: -------------------------------------------------------------------------------- 1 | jQuery hashlisten v0.1.0 2 | ======================== 3 | 4 | Monitors the URL for changes in the hash. Requires JQuery 1.3+. 5 | 6 | This is often used for pages that have many states. If each state 7 | is represented by a different hash in the URL (for instance, 8 | http://site.com/#edit), clicking the back button will return the 9 | page to the previous state. 10 | 11 | The challenge: there is no browser event fired after clicking the 12 | back button. Hashlisten solves that by continuously monitoring 13 | the URL hash and triggering a callback when it's changed. 14 | 15 | Usage 16 | ----- 17 | 18 | 19 | Go to the new post 20 | 21 | // This JS callback will be called after the link is clicked 22 | $.hashListen('/post/:id', function (id) { 23 | $("#content").html("Loading post number "+id+"...); 24 | // etc 25 | }); 26 | 27 | More usage examples 28 | ------------------- 29 | 30 | // Example for http://site.com/#/post/2/edit 31 | $.hashListen('/post/:id/:action', function (id, action) { 32 | console.log("Parameters: " + id + ", " + action); 33 | //=> Parameters: 2, edit 34 | 35 | console.log("Matches:"); 36 | console.log(this.matches); // same as [id, action] 37 | //=> Matches: [2, 'edit'] 38 | 39 | console.log("The entire hash: " + this.hash); 40 | //=> The entire hash: /post/2/edit 41 | 42 | console.log("The previous hash: " + this.referrer); 43 | //=> The previous hash: #whatever_was_before 44 | }); 45 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | // Dependencies (global) 2 | global.assert = require('chai').assert; 3 | global.expect = require('chai').expect; 4 | global.extend = require('util')._extend; 5 | global.sinon = require('sinon'); 6 | 7 | // Dependencies (local) 8 | var jsdom = require('jsdom'); 9 | var sourceCache = cache(); 10 | 11 | // Helpers 12 | global.loadEnv = loadEnv; 13 | global.render = render; 14 | 15 | // ---- 16 | 17 | function render(html) { 18 | $('body').html(html); 19 | } 20 | 21 | function loadEnv(src) { 22 | var sources = [ 23 | getFile('test/vendor/jquery-1.9.1.js'), 24 | getFile(src) 25 | ]; 26 | 27 | return function(done) { 28 | jsdom.env({ 29 | html: '', 30 | src: sources, 31 | done: function(errors, window) { 32 | window.console = console; 33 | extend(global, { 34 | window : window, 35 | $ : window.$ 36 | }); 37 | done(errors); 38 | } 39 | }); 40 | }; 41 | } 42 | 43 | /** 44 | * Returns a file's contents -- getFile('test/vendor/x.js') 45 | */ 46 | 47 | function getFile(filepath) { 48 | var path = require('path'); 49 | var fs = require('fs'); 50 | var fpath = path.resolve(__dirname, '..', filepath); 51 | return fs.readFileSync(fpath).toString(); 52 | } 53 | 54 | /** 55 | * Creates a cache 56 | */ 57 | 58 | function cache() { 59 | var hash = {}; 60 | return function (key, fn) { 61 | key = JSON.stringify(key); 62 | if (!hash[key]) hash[key] = fn(); 63 | return hash[key]; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /fadeonload/jquery.fadeonload.js: -------------------------------------------------------------------------------- 1 | /*! fadeonload (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/fadeonload */ 3 | 4 | // Fades an image in on load. 5 | // 6 | // $('.wallpaper img').fadeonload(); 7 | // 8 | // The image doesn't have to be in the DOM at time of calling. 9 | // 10 | // Tip: add `opacity: 0` and the expected `width` and `weight` to the image in 11 | // the CSS so that it will be invisible before scripts can be called. This 12 | // prevents the image from 'peeking' before fading in. 13 | // 14 | (function($) { 15 | $.fn.fadeonload = function() { 16 | var $image = this; 17 | 18 | $(function() { 19 | $image.each(function() { 20 | // On document load (or immediately), if images are cached (and hence 21 | // "loaded" before the document DOM), manually trigger their fading in. 22 | if (this.complete) { 23 | $(this).trigger('load'); 24 | } 25 | else { 26 | $(this).css({ opacity: 0 }); 27 | } 28 | }); 29 | }); 30 | 31 | // On load, fade it in. Relies on jQ 1.8+ to do vendor-prefix-free 32 | // transitions. The timer is there to ensure that this happens after 33 | // other JS logic that may be attached to the image. 34 | this.on('load', function() { 35 | var $image = $(this); 36 | $image.show().css({ opacity: 0 }); 37 | setTimeout(function() { 38 | $image.css({ opacity: 1, transition: 'opacity 400ms linear' }); 39 | }, 25); 40 | }); 41 | 42 | return this; 43 | }; 44 | })(jQuery); 45 | -------------------------------------------------------------------------------- /unorphan/README.md: -------------------------------------------------------------------------------- 1 | # jQuery Unorphan 2 | #### Obliterate text orphans. 3 | 4 | `$.unorphan()` adjoins the last two words of any block of text to make sure 5 | that they will wrap together. 6 | 7 | See [Wikipedia](http://en.wikipedia.org/wiki/Widows_and_orphans) for a 8 | description of text orphans. 9 | 10 | ### Common usage 11 | 12 | ``` javascript 13 | $(function() { 14 | $("p, li, h2, h3, h4, h5, h6").unorphan(); 15 | }); 16 | ``` 17 | 18 | This changes: 19 | 20 | ``` html 21 |

Apples, bananas and oranges.

22 | ``` 23 | 24 | Into: 25 | 26 | ``` html 27 |

Apples, bananas and oranges.

28 | ``` 29 | 30 | ### Comparison to other utilities 31 | 32 | Other similar utilities include: 33 | 34 | * [jQWidont](http://davecardwell.co.uk/javascript/jquery/plugins/jquery-widont/jqwidont-uncompressed.js) 35 | * [Widow Fix](http://plugins.jquery.com/project/widowfix) 36 | * [Widont for WordPress](http://www.shauninman.com/archive/2007/01/03/widont_2_1_wordpress_plugin) 37 | 38 | As of time of writing, *Unorphan* works better than these because: 39 | 40 | * It does not mangle HTML at all (it operates on text nodes), you can be sure that your HTML 41 | tags will always be intact. 42 | 43 | * It does not rewrite `innerHTML`, causing your elements to unneededly reinitialize, and possibly 44 | losing events and data in the elements. 45 | 46 | * It's extremely small. (400 bytes) 47 | 48 | * It does the manipulation on the client side, making no impact to your in-page SEO efforts. 49 | 50 | ### Acknowledgements 51 | 52 | Original idea and implementation by [Shawn 53 | Inman](http://www.shauninman.com/archive/2007/01/03/widont_2_1_wordpress_plugin). 54 | 55 | -------------------------------------------------------------------------------- /smartquotes/jquery.smartquotes.js: -------------------------------------------------------------------------------- 1 | /*! Smartquotes (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/smartquotes */ 3 | 4 | // Translates plain ASCII punctuation characters into typographic punctuation 5 | // HTML entities. Inspired by Smartypants. 6 | // 7 | // $(function() { 8 | // $("body").smartquotes(); 9 | // }); 10 | // 11 | (function($) { 12 | // http://www.leancrew.com/all-this/2010/11/smart-quotes-in-javascript/ 13 | $.smartquotes = function(a) { 14 | a = a.replace(/(^|[-\u2014\s(\["])'/g, "$1\u2018"); // opening singles 15 | a = a.replace(/'/g, "\u2019"); // closing singles & apostrophes 16 | a = a.replace(/(^|[-\u2014/\[(\u2018\s])"/g, "$1\u201c"); // opening doubles 17 | a = a.replace(/"/g, "\u201d"); // closing doubles 18 | a = a.replace(/\.\.\./g, "\u2026"); // ellipses 19 | a = a.replace(/--/g, "\u2014"); // em-dashes 20 | return a; 21 | }; 22 | 23 | // http://stackoverflow.com/questions/298750/how-do-i-select-text-nodes-with-jquery 24 | function getTextNodesIn(el) { 25 | var exclude = 'iframe,pre,code'; 26 | return $(el).find(':not('+exclude+')').andSelf().contents().filter(function() { 27 | return this.nodeType == 3 && $(this).closest(exclude).length === 0; 28 | }); 29 | } 30 | 31 | $.fn.smartquotes = function(fn) { 32 | if (!fn) fn = $.smartquotes; 33 | 34 | var nodes = getTextNodesIn(this), len = nodes.length; 35 | for (var i=0; i 7 | // 8 | // 9 | // 10 | // Now call: 11 | // 12 | // $('.pseudoinput').pseudoInput(); 13 | // 14 | // Possible uses 15 | // ------------- 16 | // 17 | // One use of this is to make fake text boxes, like so: 18 | // 19 | // /* Basic styles: */ 20 | // .pseudoinput { cursor: text; } 21 | // .pseudoinput textarea { 22 | // margin: 0; padding: 0; 23 | // border: 0; outline: 0; 24 | // background: transparent; box-shadow: none; 25 | // ) 26 | // 27 | // .pseudoinput { /* style me like an input field */ } 28 | // .pseudoinput:focus { /* ... */ } 29 | // 30 | // Another use 31 | // ----------- 32 | // 33 | // Or maybe to highlight the fieldset: 34 | // 35 | // $('fieldset').pseudoInput(); 36 | // 37 | // Now you can style `fieldset.focus`! 38 | 39 | (function($) { 40 | 41 | $.fn.pseudoInput = function() { 42 | var $container = this; 43 | 44 | var input = ':input:visible:enabled'; 45 | var selector = { 46 | container: $container.selector, 47 | inputs: $container.selector + ' ' + input 48 | }; 49 | 50 | $(document).on('click.pseudoinput', selector.container, function(e) { 51 | if ($(e.target).is(input+ ', label, :input')) return; 52 | $(input, this).eq(0).focus(); 53 | }); 54 | 55 | $(document).on('focus.pseudoinput', selector.inputs, function() { 56 | $(this).closest(selector.container).addClass('focus'); 57 | }); 58 | 59 | $(document).on('blur.pseudoinput', selector.inputs, function() { 60 | $(this).closest(selector.container).removeClass('focus'); 61 | }); 62 | 63 | return $container; 64 | }; 65 | 66 | })(jQuery); 67 | -------------------------------------------------------------------------------- /tabs/jquery.tabs.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.tabs (c) 2012, Rico Sta. Cruz. MIT License. 2 | * https://github.com/rstacruz/jquery-stuff/tree/master/tabs */ 3 | 4 | // Simple tabs. 5 | // 6 | // // All options are optional. 7 | // $(".tabbed").tabbed(); 8 | // 9 | // $(".tabbed").tabbed({ 10 | // content: '.content', /* Selector for content areas. */ 11 | // links: '[href]', /* Selector for tab links. */ 12 | // active: 'active', /* Classname for active tabs/content areas. */ 13 | // activate: false /* Activate the tabs on start. Default: false */ 14 | // }); 15 | 16 | (function($) { 17 | $.fn.tabbed = function(options) { 18 | var defaults = { 19 | content: '> *:not(:first-child)', 20 | links: '[href]', 21 | active: 'active', 22 | activate: false 23 | }; 24 | 25 | if (!options) options = {}; 26 | options = $.extend({}, defaults, options); 27 | 28 | var self = $(this); 29 | 30 | // Selects the tab called `target` in the parent element `$parent`. 31 | function select($parent, target) { 32 | $parent.find(options.links) 33 | .removeClass(options.active) 34 | .filter("[href='#"+target+"']") 35 | .addClass(options.active); 36 | 37 | $parent.find(options.content).hide(); 38 | $parent.find('#'+target).show(); 39 | } 40 | 41 | // Register the click handler to delegate to the select() function. 42 | self.on("click", "[href]", function(e) { 43 | e.preventDefault(); 44 | var target = $(this).attr('href').substr(1); 45 | var $parent = $(this).closest(self); 46 | select($parent, target); 47 | }); 48 | 49 | // Activate the tabs if it's asked for. 50 | if (options.activate) { 51 | self.each(function() { 52 | var $parent = this; 53 | var $active = $parent.find(options.links).filter('.'+options.active); 54 | if ($active.length) { 55 | update($active.attr('href').substr(1)); 56 | } 57 | }); 58 | } 59 | }; 60 | 61 | })(jQuery); 62 | -------------------------------------------------------------------------------- /selecttrap/jquery.selecttrap.js: -------------------------------------------------------------------------------- 1 | /*! jQuery selecttrap -- https://github.com/rstacruz/jquery-stuff 2 | (c) 2013, Rico Sta. Cruz, MIT licensed */ 3 | 4 | ;(function($) { 5 | 6 | /** 7 | * Traps a selectbox in a wrapper, effectively allowing you to "skin" how it 8 | * looks like. 9 | * 10 | * $("select").selecttrap(); 11 | */ 12 | 13 | $.fn.selecttrap = function(options) { 14 | if (!options) options = {}; 15 | 16 | $(this).each(function() { 17 | var $select = $(this); 18 | 19 | // Don't reapply 20 | if ($select.parent().is('.selecttrap')) return; 21 | 22 | // Initialize box 23 | var $box = $select 24 | .wrap('
') 25 | .closest('div') 26 | .addClass(options['class']) 27 | .addClass($select.attr('class')); 28 | 29 | // Initialize artifacts 30 | var $text = $('
') 31 | .appendTo($box) 32 | .after('
'); 33 | 34 | // Change the placeholder text when the ' + 9 | '' + 10 | '' + 11 | '' + 12 | '' 13 | ); 14 | }); 15 | 16 | // ---- 17 | 18 | describe('elements', function() { 19 | beforeEach(function() { 20 | $('select').selecttrap(); 21 | }); 22 | 23 | it(".selecttrap", function() { 24 | assert.equal(1, $('body > .selecttrap').length); 25 | }); 26 | 27 | it(".selecttrap > select", function() { 28 | assert.equal(1, $('.selecttrap > select').length); 29 | }); 30 | 31 | it(".selecttrap > .st-text", function() { 32 | assert.equal(1, $('.selecttrap > .st-text').length); 33 | }); 34 | }); 35 | 36 | // ---- 37 | 38 | describe('respond', function() { 39 | beforeEach(function() { 40 | $('select').selecttrap(); 41 | }); 42 | 43 | it("initial", function() { 44 | assert.equal('One', $('.st-text').text()); 45 | }); 46 | 47 | it("changes", function() { 48 | $('select').val('v2').trigger('change'); 49 | assert.equal('Two', $('.st-text').text()); 50 | }); 51 | 52 | it("spaces", function() { 53 | $('select').val('v3').trigger('change'); 54 | assert.equal('Third item', $('.st-text').text()); 55 | }); 56 | }); 57 | 58 | // ---- 59 | 60 | describe('options.class', function() { 61 | beforeEach(function() { 62 | $('select').selecttrap({ 'class': 'mini' }); 63 | }); 64 | 65 | it('should work', function() { 66 | assert.isTrue($('.selecttrap').is('.mini')); 67 | }); 68 | }); 69 | 70 | describe('class inheritance', function() { 71 | it('should work', function() { 72 | $('select').addClass('small'); 73 | $('select').selecttrap(); 74 | assert.isTrue($('.selecttrap').is('.small')); 75 | }); 76 | }); 77 | 78 | // ---- 79 | 80 | describe('implicit values', function() { 81 | beforeEach(function() { 82 | $('select').selecttrap(); 83 | }); 84 | 85 | it('should work', function() { 86 | $('select').val('Fourth item').trigger('change'); 87 | assert.equal('Fourth item', $('select').val()); 88 | assert.equal('Fourth item', $('.st-text').text()); 89 | }); 90 | }); 91 | 92 | // ---- 93 | 94 | describe('multiple', function() { 95 | beforeEach(function() { 96 | render( 97 | '' + 101 | '' 105 | ); 106 | }); 107 | 108 | it('should work', function() { 109 | $('select').selecttrap(); 110 | 111 | assert(2, $('body .selecttrap').length); 112 | }); 113 | }); 114 | 115 | }); 116 | 117 | -------------------------------------------------------------------------------- /scrope/jquery.scrope.coffee: -------------------------------------------------------------------------------- 1 | $ = jQuery 2 | 3 | # Returns the scroll position thing. 4 | # 5 | # ## Example 6 | # $("#two").scrollPosition() // 0..1 or undefined 7 | # 8 | $.fn.scrollPosition = -> 9 | top = $(this).position().top 10 | min = Math.max(top - $(window).height(), 0) 11 | max = Math.min($('body').height() - $(window).height(), top + $(this).outerHeight()) 12 | 13 | val = ($(window).scrollTop() - min) / (max - min) 14 | 15 | val 16 | 17 | # Monitors scrolling. 18 | # 19 | # You can pass an attr delta to make it trigger before it's actually shown. 20 | # 21 | # ## Example 22 | # $("#two").monitorScroll({ callback: function(e, pos) { pos; } }); 23 | # // `pos` will be 0..1 -- what scrollPosition will give 24 | # 25 | $.fn.monitorScroll = (options) -> 26 | callback = options.callback || (->) 27 | delta = options.delta || 0 28 | 29 | $(this).each -> 30 | $this = $(this) 31 | 32 | if options.callback 33 | $this.bind 'peek', callback 34 | 35 | $(window).scroll -> 36 | pos = $this.scrollPosition() 37 | $this.trigger 'peek', pos if pos > (0.0-delta) && pos < (1.0+delta) 38 | 39 | # Initialize it 40 | callback.apply $(this), [null, ($this.scrollPosition() || 0)] 41 | 42 | $.fn.scrope = (elements) -> 43 | 44 | for selector of elements 45 | options = elements[selector] 46 | 47 | $(this).monitorScroll delta: options.top, callback: (e, pos) -> 48 | if options.fromTop 49 | p = -pos 50 | else 51 | p = (-pos + 0.5) * 2 # -1..1 52 | 53 | $el = if selector == '&' 54 | $(this) 55 | else 56 | $(this).find(selector) 57 | 58 | $el.setOffset top: options.top * p, bgTop: (options.bgTop||0) * p 59 | 60 | # Adds two CSS values together. 61 | # 62 | # ## Example 63 | # add('5px', 10) //=> 15px 64 | # 65 | add = (a, b) -> 66 | return a if parseFloat(b) == 0.0 67 | unit = "#{a}".match(/[^0-9]*$/) 68 | (parseFloat(a) + parseFloat(b)) + unit 69 | 70 | $.fn.setOffset = (options) -> 71 | console.log $(this).attr('id'), options if $(this).attr('id') == 'two' 72 | $(this).each -> 73 | $this = $(this) 74 | 75 | # Ensure that the element has positioning. 76 | if !$this.css('position') == 'static' 77 | $this.css position: 'relative', top: 0, left: 0 78 | 79 | fadeIn = false 80 | 81 | # Store the old 82 | if !$this.data('original_offset') 83 | bp = $this.css('backgroundPosition').split(' ') 84 | 85 | $this.data 'original_offset', 86 | top: $this.css('top'), 87 | left: $this.css('left') 88 | bgTop: bp[0] 89 | bgLeft: bp[1] 90 | 91 | fadeIn = true 92 | 93 | origin = $this.data('original_offset') 94 | 95 | if options.top or options.left 96 | $this.css 97 | top: add origin.top, (options.top || 0) 98 | left: add origin.left, (options.left || 0) 99 | 100 | if options.bgTop or options.bgLeft 101 | top = add origin.bgTop, (options.bgTop || 0) 102 | left = add origin.bgLeft, (options.bgLeft || 0) 103 | 104 | $this.css 105 | backgroundPosition: "#{left} #{top}" 106 | 107 | $this.fadeIn() if fadeIn 108 | -------------------------------------------------------------------------------- /growl/jquery.growl.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.growl (c) 2010-12, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/growl */ 3 | 4 | // Usage: 5 | // 6 | // $.growl("Message"); 7 | // $.growl({message: "Message"}); 8 | // $.growl({message: "Message", sticky: true, timeout: 10000, id: 'thnth', class: 'error'}); // Not impl yet 9 | // $.growl.kill(); // Hide all 10 | // 11 | // Todo: 12 | // - coallescing 13 | // 14 | ;(function($) { 15 | $.growl = function(message) { 16 | return $.growl.showMessage(message); 17 | }; 18 | 19 | $.extend($.growl, { 20 | // Options 21 | id: "growl", 22 | timeout: 5000, 23 | id_prefix: "growl-notification-", 24 | 25 | // State 26 | $notifs: null, 27 | 28 | // Construct the html. Override me if you like. 29 | buildHtml: function(options) { 30 | if (options.message && options.title) { 31 | return "

"+options.title+"

"+options.message+"

"; 32 | } else { 33 | return "

"+options.message+"

"; 34 | } 35 | }, 36 | 37 | showMessage: function(args) { 38 | // Alias for $.growl('message'). 39 | if (typeof args == "string") 40 | { return $.growl.showMessage({ 'message': args }); } 41 | 42 | if ((typeof args != "object") || 43 | (args.message === undefined)) 44 | { return; } 45 | 46 | var message = args.message; 47 | var self = this; 48 | 49 | // Build the container for messages. 50 | if (!self.$notifs) { 51 | self.$notifs = $("
"); 52 | $(document.body).append(self.$notifs); 53 | } 54 | 55 | // Build the HTML. 56 | var html = $.growl.buildHtml(args); 57 | 58 | // Construct the item. 59 | var item = $(html); 60 | if (args.classname) { item.addClass(args.classname); } 61 | 62 | item.find('.close').click(function() { 63 | self._killItem(item); 64 | }); 65 | 66 | // Either replace the old item (coallesce), or add the new item. 67 | var id = args.id ? (this.id_prefix + args.id) : null; 68 | var $old = args.id ? $("#"+id) : []; 69 | if ($old.length > 0) { 70 | // Replace the old item with the new one. 71 | $old.html(item.html()); 72 | $old.attr('class', item.attr('class')); 73 | item = $old; 74 | } 75 | else { 76 | // Add the new item. 77 | item.attr('id', id); 78 | self.$notifs.find('.items').prepend(item); 79 | } 80 | 81 | self.addTimer(item, args); 82 | }, 83 | 84 | addTimer: function($item, args) { 85 | var self = this; 86 | 87 | // Clear a timeout, if there is one. 88 | var timer = $item.data('growl-timer'); 89 | if (timer) { window.clearTimeout(timer); } 90 | 91 | // Add a timeout. 92 | if (args.sticky !== true) { 93 | timer = window.setTimeout(function() { 94 | self._killItem($item); 95 | }, args.timeout || self.timeout); 96 | $item.data('growl-timer', timer); 97 | } 98 | }, 99 | 100 | kill: function() { 101 | var self = this; 102 | self.$notifs.find('.items > *').each(function() { 103 | self._killItem($(this)); 104 | }); 105 | }, 106 | 107 | _killItem: function($item) { 108 | $item = $($item); 109 | $item.slideUp(function() { $(this).remove(); }); 110 | } 111 | }); 112 | })(jQuery); 113 | -------------------------------------------------------------------------------- /preventoverscroll/jquery.prevent_overscroll.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.preventOverscroll (c) 2012, Rico Sta. Cruz. MIT License. 2 | * https://github.com/rstacruz/jquery-stuff/tree/master/preventoverscroll */ 3 | 4 | // If you have an element with overflow: auto (or overflow: scroll), and you 5 | // try to use your mouse wheel to scroll it, the document will probably scroll 6 | // once your scroll pane is at its boundaries. 7 | // 8 | // 10 | // 11 | //
...
12 | // .scrollable { overflow: auto; height: 200px; } 13 | // 14 | // Simply use .preventOverscroll() to stop this behavior. 15 | // 16 | // $(".scrollable").preventOverscroll(); 17 | 18 | (function($) { 19 | $.fn.preventOverscroll = function() { 20 | // For WebKits, et al. 21 | if ('onmousewheel' in document.documentElement) { 22 | $(this).live('mousewheel', function(e) { 23 | var $this = $(this); 24 | 25 | var dy = e.originalEvent.wheelDeltaY; 26 | var dx = e.originalEvent.wheelDeltaX; 27 | 28 | // Sanity check for older browsers. 29 | if ((typeof dy === 'undefined') || 30 | (typeof dx === 'undefined') || 31 | (typeof this.scrollHeight === 'undefined')) { 32 | return; 33 | } 34 | 35 | // Get scrolling direction info, Webkit style. 36 | var scrolling = { 37 | down: dy < 0, 38 | up: dy > 0, 39 | left: dx > 0, 40 | right: dx < 0 41 | }; 42 | 43 | if (shouldStop($this, scrolling)) { 44 | e.preventDefault(); 45 | } 46 | }); 47 | } 48 | 49 | // For Moz. 50 | if ('MouseScrollEvent' in window) { 51 | $(this).live("DOMMouseScroll", function(e) { 52 | var $this = $(this); 53 | var ee = e.originalEvent; 54 | 55 | // Sanity check. 56 | if ((typeof ee.axis === 'undefined') || 57 | (typeof this.scrollHeight === 'undefined')) { 58 | return; 59 | } 60 | 61 | // Get scrolling direction info, Mozilla style. 62 | var horiz = (ee.axis === ee.HORIZONTAL_AXIS); 63 | var vert = (ee.axis === ee.VERTICAL_AXIS); 64 | var delta = ee.detail; 65 | 66 | var scrolling = { 67 | down: vert && delta > 0, 68 | up: vert && delta < 0, 69 | left: horiz && delta < 0, 70 | right: horiz && delta > 0 71 | }; 72 | 73 | if (shouldStop($this, scrolling)) { 74 | e.preventDefault(); 75 | e.stopPropagation(); 76 | } 77 | }); 78 | } 79 | 80 | // Given scrolling data `scrolling`, check if element `this` should stop 81 | // scrolling. Check if we're at boundaries. 82 | function shouldStop($this, scrolling) { 83 | // These are true/false of whether the content is already at boundaries. 84 | // For instance, `top` and `left` may both be true. 85 | var at = { 86 | top: ($this.scrollTop() === 0), 87 | left: ($this.scrollLeft() === 0), 88 | bottom: ($this[0].scrollHeight - $this.scrollTop() <= $this.height()), 89 | right: ($this[0].scrollWidth - $this.scrollLeft() <= $this.width()) 90 | }; 91 | 92 | return ( 93 | (scrolling.down && at.bottom) || 94 | (scrolling.up && at.top) || 95 | (scrolling.left && at.left) || 96 | (scrolling.right && at.right) 97 | ); 98 | } 99 | }; 100 | })(jQuery); 101 | -------------------------------------------------------------------------------- /size_responder/size_responder.js: -------------------------------------------------------------------------------- 1 | /*! SizeResponder (c) 2013, Rico Sta. Cruz. MIT License. 2 | * https://github.com/rstacruz/jquery-stuff/tree/master/size_responder */ 3 | 4 | // Performs a given callback (`enter`) when the window is resized to fit a 5 | // certain range. Another callback (`exit`) will be ran when the window is 6 | // resized not to fit that range. 7 | // 8 | // Perfect for responsive sites. 9 | // 10 | // Requires jQuery 1.7+. 11 | // 12 | // Simple example: 13 | // 14 | // SizeResponder.when({ 15 | // width: { min: 300 }, 16 | // }) 17 | // .on('enter', function() { 18 | // console.log("Browser was resized to < 300px width"); 19 | // }), 20 | // .on('exit', function() { 21 | // console.log("Browser was resized to > 300px width"); 22 | // }); 23 | // 24 | // More options: 25 | // 26 | // SizeResponder.when({ 27 | // width: { min: 300, max: 600 }, 28 | // height: { min: 30, max: 600 }, 29 | // }) 30 | // 31 | // .on('enter', function() { ... }) 32 | // .on('exit', function() { ... }) 33 | // .on('tick', function() { ... }) 34 | // 35 | // You can give an associated HTML class with the conditions using `.htmlClass()`: 36 | // 37 | // SizeResponder 38 | // .when({ height: { min: 300 }}) 39 | // .htmlClass('tall'); 40 | // 41 | // /* Toggles between and */ 42 | // 43 | (function(w, $) { 44 | function SizeResponder(options) { 45 | var self = this; 46 | $.extend(self, options || {}); 47 | 48 | self.emitter = $({}); 49 | 50 | self._matches = undefined; 51 | self._fn = $.proxy(self.onresize, self); 52 | 53 | self.enable(); 54 | setTimeout(function() { 55 | $(function() { self.onresize(); }); 56 | }, 0); 57 | 58 | return self; 59 | } 60 | 61 | SizeResponder.prototype = { 62 | onresize: function() { 63 | var matches = this.matches(); 64 | 65 | if (matches && this._matches !== true) { 66 | this.trigger('enter'); 67 | this._matches = true; 68 | } 69 | 70 | else if (!matches && this._matches !== false) { 71 | this.trigger('exit'); 72 | this._matches = false; 73 | } 74 | 75 | if (matches) this.trigger('tick'); 76 | }, 77 | 78 | // Delegate events to .emitter. 79 | trigger: function() { this.emitter.trigger.apply(this.emitter, arguments); return this; }, 80 | on: function() { this.emitter.on.apply(this.emitter, arguments); return this; }, 81 | off: function() { this.emitter.off.apply(this.emitter, arguments); return this; }, 82 | 83 | matches: function() { 84 | var match = true; 85 | var self = this; 86 | 87 | function check(what) { 88 | if (self[what] && match) { 89 | var size = $(window)[what](); 90 | if (typeof self[what].min === 'number' && size < self[what].min) match = false; 91 | if (typeof self[what].max === 'number' && size > self[what].max) match = false; 92 | } 93 | } 94 | 95 | check('width'); 96 | check('height'); 97 | return match; 98 | }, 99 | 100 | disable: function() { 101 | $(window).off('resize.sizeresponder'); 102 | }, 103 | 104 | enable: function() { 105 | this.disable(); 106 | $(window).on('resize.sizeresponder', this._fn); 107 | }, 108 | 109 | htmlClass: function(klass) { 110 | this.on('enter', function() { $('html').addClass(klass).removeClass('not-'+klass); }); 111 | this.on('exit', function() { $('html').removeClass(klass).addClass('not-'+klass); }); 112 | } 113 | }; 114 | 115 | SizeResponder.when = function(options) { 116 | return new SizeResponder(options); 117 | }; 118 | 119 | w.SizeResponder = SizeResponder; 120 | })(this, jQuery); 121 | -------------------------------------------------------------------------------- /cycler/README.md: -------------------------------------------------------------------------------- 1 | # Cycler 2 | 3 | Cycles between a given `list` at a given `interval`. 4 | Simply define an `onactivate` hook. 5 | 6 | All the options are optional except `onactivate`. 7 | 8 | ``` javascript 9 | c = new Cycler(list, { 10 | interval: 3000, 11 | initial: 0, /* first slide's index */ 12 | onactivate: function(current, index, prev, prevIndex) { ... }, /* Required */ 13 | onstart: function() { ... }, 14 | onpause: function() { ... } 15 | }); 16 | ``` 17 | 18 | Slideshow example 19 | ----------------- 20 | 21 | The most common usecase of Cycler is to make your own carousel/slideshow 22 | implementation. Here's how you might make one: 23 | 24 | ``` html 25 |
26 | 30 |
31 | 32 | 33 | 34 |
35 |
36 | ``` 37 | 38 | ``` javascript 39 | var $parent = $(".slideshow"); 40 | var $images = $parent.find("img"); 41 | 42 | var c = new Cycler($images, { 43 | interval: 5000, 44 | onactivate: function(current) { 45 | $images.hide(); 46 | $(current).show(); 47 | } 48 | }); 49 | 50 | // Custom controls example 51 | $parent.find("button.next").on("click", function() { c.next(); }); 52 | $parent.find("button.prev").on("click", function() { c.previous(); }); 53 | 54 | // Pause on hover example 55 | $parent.on("hover", function() { c.pause(); }, function() { c.start(); }); 56 | ``` 57 | 58 | Navigating 59 | ---------- 60 | 61 | You can switch by slides using `next()`, `previous()` and `goTo()`. When 62 | these are invoked, the interval timer is reset (that is, it will take 3000ms 63 | again to switch to the next slide). 64 | 65 | If these are called when the slideshow is paused, it should remain paused. 66 | 67 | Doing this will trigger the `onactivate` callback. 68 | 69 | ``` javascript 70 | c.next(); 71 | c.previous(); 72 | c.goTo(0); 73 | ``` 74 | 75 | The onactivate hook 76 | ------------------- 77 | 78 | This is where the magic happens. It's called everytime a new slide is activated. 79 | 80 | The callback takes 4 arguments: the current list item (`current`) + its 81 | index in the list (`index`), and the previous item (`prev`) + its index (`prevIndex`). 82 | 83 | ``` javascript 84 | var list = [ 'Apple', 'Banana', 'Cherry' ]; 85 | 86 | new Cycler(list, { 87 | onactivate: function(current, index, prev, prevIndex) { 88 | console.log("Switching from", prev, "to", current); 89 | console.log("(from", prevIndex, "to", index, ")"); 90 | }; 91 | }); 92 | 93 | // Result: 94 | // 95 | // Switching from null to "Apple" (from null to 0) 96 | // Switching from "Apple" to "Banana" (from 0 to 1) 97 | // Switching from "Banana" to "Cherry" (from 1 to 2) 98 | // Switching from "Cherry" to "Apple" (from 2 to 0) 99 | ``` 100 | 101 | Pausing 102 | ------- 103 | 104 | You can pause and unpause the slideshow with `pause()` and `start()`. Note 105 | that calling `start()` will reset the interval timer. 106 | 107 | These will call the `onpause` and `onstart` callbacks respectively. 108 | 109 | ``` javascript 110 | c.pause(); 111 | c.start(); 112 | ``` 113 | 114 | You can pass `true` as an argument (eg, `c.pause(true)`) to these to supress 115 | triggering the callbacks. 116 | 117 | Properties 118 | ---------- 119 | 120 | ``` javascript 121 | c.current /* Numeric index of current item */ 122 | c.list /* The list being cycled */ 123 | ``` 124 | 125 | Chainability 126 | ------------ 127 | 128 | All the methods are chainable, too, so you can do: 129 | 130 | ``` javascript 131 | c.next().pause(); 132 | ``` 133 | -------------------------------------------------------------------------------- /mailcheckhint/jquery.mailcheckhint.js: -------------------------------------------------------------------------------- 1 | /*! mailcheckhint (c) 2012, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/mailcheckhint */ 3 | 4 | // Simple one-shot integration for Mailcheck.js. 5 | // Requires Mailcheck: https://github.com/Kicksend/mailcheck 6 | // 7 | // Appends a after the when there's a suggestion. 8 | // The hint is clickable, and when you click it, it accepts the suggested email. 9 | // 10 | // Usage: 11 | // 12 | // $('input.email').enableMailcheckHint(); 13 | // 14 | // Customization can be done with all these optional args: 15 | // 16 | // $('input.email').enableMailcheckHint({ 17 | // message: "Did you mean %{email}?", 18 | // hintElement: "", 19 | // append: function($input, $hint) { $hint.hide(); $input.after($hint); $hint.slideDown(250); }, 20 | // dismiss: function($input, $hint) { $hint.slideUp(250, function() { $hint.remove(); }); } 21 | // }); 22 | // 23 | // There's also macros to make mailcheck easier to configure: 24 | // 25 | // $.mailcheck.addDomains(['rocketmail.com', 'yahoo.com.in']); 26 | // $.mailcheck.addTLDs('ph com.ph net.ph org.ph'); /* Auto-split the string */ 27 | // 28 | (function ($) { 29 | $.mailcheck = { 30 | addDomains: function(more) { 31 | if (typeof more === 'string') more = more.split(' '); 32 | Kicksend.mailcheck.defaultDomains = 33 | Kicksend.mailcheck.defaultDomains.concat(more); 34 | }, 35 | addTLDs: function(more) { 36 | if (typeof more === 'string') more = more.split(' '); 37 | Kicksend.mailcheck.defaultTopLevelDomains = 38 | Kicksend.mailcheck.defaultTopLevelDomains.concat(more); 39 | }, 40 | disableTLDs: function() { 41 | Kicksend.mailcheck.defaultTopLevelDomains = []; 42 | } 43 | }; 44 | 45 | $.fn.enableMailcheckHint = function(options) { 46 | var $hint; 47 | var $input = $(this); 48 | 49 | var defaults = { 50 | message: "Did you mean %{email}?", 51 | hintElement: "", 52 | append: function($input, $hint) { $hint.hide(); $input.after($hint); $hint.slideDown(250); }, 53 | dismiss: function($input, $hint) { $hint.slideUp(250, function() { $hint.remove(); }); } 54 | }; 55 | 56 | options = $.extend({}, defaults, (options || {})); 57 | 58 | $input.on('blur', function() { 59 | var $input = $(this); 60 | 61 | $input.mailcheck({ 62 | suggested: function(el, suggestion) { 63 | // Create element 64 | if ($hint) $hint.remove(); 65 | $hint = $(options.hintElement); 66 | 67 | // Construct message 68 | var msg = options.message; 69 | msg = msg.replace("%{email}", [ 70 | "", 73 | "", 74 | suggestion.address, 75 | "", 76 | "@", 77 | "", 78 | suggestion.domain, 79 | "" 80 | ].join('')); 81 | $hint = $hint.html(msg); 82 | 83 | // Add handler 84 | $hint.on('click', function(e) { 85 | // Accept suggestion 86 | e.preventDefault(); 87 | $input.val(suggestion.full); 88 | options.dismiss($input, $hint); 89 | $hint = null; 90 | 91 | // Move to the next 92 | var $inputs = $(':input'); 93 | var $focus = $inputs.get($inputs.index($input) + 1); 94 | $focus.focus(); 95 | }); 96 | 97 | // Show 98 | options.append($input, $hint); 99 | }, 100 | 101 | empty: function(element) { 102 | if ($hint) { 103 | options.dismiss($input, $hint); 104 | $hint = null; 105 | } 106 | } 107 | }); 108 | }); 109 | }; 110 | })(jQuery); 111 | -------------------------------------------------------------------------------- /fillsize/jquery.fillsize.js: -------------------------------------------------------------------------------- 1 | /*! fillsize (c) 2012-2013, Rico Sta. Cruz. MIT License. 2 | * http://github.com/rstacruz/jquery-stuff/tree/master/fillsize */ 3 | 4 | // Makes an element fill up its container. 5 | // 6 | // $(".container").fillsize("> img"); 7 | // 8 | // This binds a listener on window resizing to automatically scale down the 9 | // child (`> img` in this example) just so that enough of it will be visible in 10 | // the viewport of the container. 11 | // 12 | // This assumes that the container has `position: relative` (or any 'position', 13 | // really), and `overflow: hidden`. 14 | 15 | (function($) { 16 | $.fn.fillsize = function(selector) { 17 | var $parent = this; 18 | var $img; 19 | 20 | function resize() { 21 | if (!$img) $img = $parent.find(selector); 22 | 23 | $img.each(function() { 24 | if (!this.complete) return; 25 | var $img = $(this); 26 | // get alignment data attr. Can be "topleft", "bottom right", "leftright" (eq.left)... 27 | var data_align = $img.data('fillsize_align'); 28 | // init default alignment 29 | var h_align = "center"; 30 | var v_align = "center"; 31 | if(typeof data_align != "undefined"){ 32 | // parse horizontal alignment data 33 | if(data_align.indexOf("left")>-1){ 34 | h_align = "left"; 35 | } else if(data_align.indexOf("right")>-1){ 36 | h_align = "right"; 37 | } 38 | // parse vetical alignment data 39 | if(data_align.indexOf("top")>-1){ 40 | v_align = "top"; 41 | } else if(data_align.indexOf("bottom")>-1){ 42 | v_align = "bottom"; 43 | } 44 | } 45 | 46 | var parent = { height: $parent.innerHeight(), width: $parent.innerWidth() }; 47 | var imageRatio = $img.width() / $img.height(); 48 | var containerRatio = parent.width / parent.height; 49 | 50 | var css = { 51 | position: 'absolute', 52 | left: 0, top: 0, right: 'auto', bottom: 'auto' 53 | }; 54 | 55 | // If image is wider than the container 56 | if (imageRatio > containerRatio) { 57 | css.left = h_align == "center" ? 58 | Math.round((parent.width - imageRatio * parent.height) / 2) + 'px' // center 59 | : 60 | (h_align == "left" ? 61 | 0 // left 62 | : 63 | "auto" // neither 64 | ); 65 | css.right = h_align == "right" ? 66 | 0 // right 67 | : 68 | "auto"; // center or left 69 | css.width = 'auto'; 70 | css.height = '100%'; 71 | } 72 | 73 | // If the container is wider than the image 74 | else { 75 | css.top = v_align == "center" ? 76 | Math.round((parent.height - (parent.width / $img.width() * $img.height())) / 2) + 'px' // center 77 | : 78 | (v_align == "top" ? 79 | 0 // top 80 | : 81 | "auto" // neither (bottom) 82 | ); 83 | css.bottom = v_align == "center" ? 84 | "auto" // center 85 | : 86 | 0; // bottom 87 | css.height = 'auto'; 88 | css.width = '100%'; 89 | } 90 | 91 | $img.css(css); 92 | }); 93 | } 94 | 95 | // Make it happen on window resize. 96 | $(window).resize(resize); 97 | 98 | // Allow manual invocation by doing `.trigger('fillsize')` on the container. 99 | $(document).on('fillsize', $parent.selector, resize); 100 | 101 | // Resize on first load (or immediately if called after). 102 | $(function() { 103 | // If the child is an image, fill it up when image's real dimensions are 104 | // first determined. Needs to be .bind() because the load event will 105 | // bubble up. 106 | $(selector, $parent).bind('load', function() { 107 | setTimeout(resize, 25); 108 | }); 109 | 110 | resize(); 111 | }); 112 | 113 | return this; 114 | }; 115 | })(jQuery); -------------------------------------------------------------------------------- /livenavigate/README.md: -------------------------------------------------------------------------------- 1 | # Livenavigate 2 | #### In-page navigation that doesn't break the back button and actually changes the URL 3 | 4 | What it solves 5 | -------------- 6 | 7 | The usual approach to single-page apps are URL's like 8 | `http://domain.com/#!1938/article`. Livenavigate does the same thing, 9 | except that it your URL will be `http://domain.com/1938/article`, yet 10 | everything will be in-place via AJAX. 11 | 12 | This is only supported if your browser supports history states (FF4/Safari). 13 | Don't worry though--it will fallback to the hashbang method otherwise. 14 | 15 | For hashbang URL's, this relies on the awesome jQuery.hashListen. It 16 | uses the hash change event, and falls back to window timers if it's not 17 | available. 18 | 19 | End result: in-place navigation with nice URL's, no matter what browser. 20 | 21 | Usage 22 | ----- 23 | 24 | ``` javascript 25 | /* Bind this to like, say, links */ 26 | $.navigate('/admin/products'); 27 | ``` 28 | 29 | If the history states are available (Safari/FF4), it will change the actual URL 30 | of the page, yet still /not/ load the URL directly (but instead just trigger the 31 | `navigate` event). 32 | 33 | ``` javascript 34 | /* Here's how you listen to new pages */ 35 | $(window).bind('navigate', function (e, href) { 36 | /* href == '/admin/products' */ 37 | }); 38 | ``` 39 | 40 | If history states are not available, it will fall back to hashListen. 41 | 42 | You may also silently navigate to a given URL without trigerring the event 43 | handlers: 44 | 45 | ``` javascript 46 | $.navigate('/admin/products', true); 47 | ``` 48 | 49 | Common example 50 | -------------- 51 | 52 | In your HTML, include both JS files. (jQuery 1.3+ required) 53 | 54 | ``` html 55 |