├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── package.json ├── unorphanize.jquery.js └── unorphanize.jquery.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | *.sql 27 | *.sqlite 28 | 29 | # OS generated files # 30 | ###################### 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | ehthumbs.db 37 | Thumbs.db 38 | 39 | # Node # 40 | ######## 41 | lib-cov 42 | *.seed 43 | *.log 44 | *.csv 45 | *.dat 46 | *.out 47 | *.pid 48 | *.gz 49 | 50 | pids 51 | logs 52 | results 53 | 54 | npm-debug.log 55 | node_modules 56 | index.html -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:false*/ 2 | module.exports = function(grunt) { 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | // Metadata. 7 | pkg: grunt.file.readJSON('package.json'), 8 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 9 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 10 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 11 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;' + 12 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', 13 | 14 | // Task configuration. 15 | 16 | uglify: { 17 | options: { 18 | banner: '<%= banner %>' 19 | }, 20 | dist: { 21 | src: 'unorphanize.jquery.js', 22 | dest: 'unorphanize.jquery.min.js' 23 | } 24 | }, 25 | 26 | jshint: { 27 | options: { 28 | "boss": true, 29 | "curly": true, 30 | "eqeqeq": true, 31 | "eqnull": true, 32 | "expr": true, 33 | "immed": true, 34 | "noarg": true, 35 | "onevar": true, 36 | "quotmark": "double", 37 | "smarttabs": true, 38 | "trailing": true, 39 | "undef": true, 40 | "unused": true, 41 | "globals": { 42 | jQuery: false, 43 | $: false 44 | } 45 | }, 46 | lib_test: { 47 | src: ['unorphanize.jquery.js'] 48 | } 49 | } 50 | 51 | }); 52 | 53 | // These plugins provide necessary tasks. 54 | grunt.loadNpmTasks('grunt-contrib-uglify'); 55 | grunt.loadNpmTasks('grunt-contrib-jshint'); 56 | 57 | // Default task. 58 | grunt.registerTask('default', ['jshint', 'uglify']); 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Simon Goellner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery Unorphanize 2 | -------------------- 3 | A small jQuery method for preventing or stopping orphans (widows) in text, paragraphs or whatever (unhindered by HTML). 4 | `~ 500 bytes minified` 5 | 6 | ### How it works 7 | ```js 8 | $(".selector").unorphanize(); 9 | ``` 10 | **Unorphanize** will take the jQuery selector (` $(".selector")`) you supply 11 | and without disturbing theinner html's markup will **replace the last space** 12 | with an ` ` preventing an [orphan](http://en.wikipedia.org/wiki/Widows_and_orphans) 13 | from occurring. 14 | 15 | 16 | If you wish the last line to have more than 2 words, you can supply an argument in `number` format like so: 17 | ```js 18 | $(".selector").unorphanize(2); 19 | ``` 20 | 21 | ### Why it's better than "Plugin X" 22 | Unorphanize will recognize if you have HTML elements, and not ruin them: Most other plugins will do it a bit faster, 23 | __*but*__ they will ignore HTML tags and put the space before/after them, or they will just not work. 24 | They may also put the __*space inside of a html*__ entity like: `blah` which as you can imagine is useless. 25 | You should, however, _run it before you bind events_ to inner dom elements, or you may lose those events. Or you can 26 | [delegate events from the parent](http://api.jquery.com/on/#direct-and-delegated-events) element. 27 | 28 | 29 | ### Example 30 | 31 | A Line of text which wraps and leaves an 32 | orphan. 33 | 34 | would change to: 35 | 36 | A line of text which wraps and leaves 37 | an orphan. 38 | 39 | and with `$(".selector").unorphanize(2);` we get: 40 | 41 | A line of text which wraps and 42 | leaves an orphan. 43 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-unorphanize", 3 | "version": "1.0.1", 4 | "main": "unorphanize.jquery.js", 5 | "description": "Prevent orphans in text with jQuery", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/simeydotme/jquery-unorphanize.git" 9 | }, 10 | "license": "MIT", 11 | "keywords": [ 12 | "jquery", 13 | "orphan", 14 | "widow", 15 | "javascript", 16 | "remove" 17 | ], 18 | "authors": [ 19 | "Simon Goellner " 20 | ], 21 | "ignore": [ 22 | ".gitattributes", 23 | ".gitignore", 24 | "Gruntfile.js", 25 | "*.json", 26 | "*.md", 27 | "*.txt", 28 | "*.html", 29 | "mode_modules" 30 | ], 31 | "dependencies": { 32 | "jquery": ">=1.10.2" 33 | }, 34 | "devDependencies": { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-unorphanize", 3 | "version": "1.0.1", 4 | "main": "unorphanize.jquery.js", 5 | "description": "Prevent orphans in text with jQuery", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/simeydotme/jquery-unorphanize.git" 9 | }, 10 | "license": "MIT", 11 | "keywords": [ 12 | "jquery", 13 | "orphan", 14 | "widow", 15 | "javascript", 16 | "remove" 17 | ], 18 | "author": "Simon Goellner ", 19 | "scripts": { 20 | "test": "echo \"Error: no test specified\" && exit 1" 21 | }, 22 | "devDependencies": { 23 | "grunt-contrib-uglify": "~0.2.4", 24 | "grunt-contrib-jshint": "~0.6.4" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /unorphanize.jquery.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.unorphanize = function( gather ) { 4 | 5 | // if we haven't supplied a number for the number 6 | // of words to join the orphan, or we supplied 7 | // it wrong, make it 1. 8 | if( typeof( gather ) !== "number" ) { 9 | gather = 1; 10 | } 11 | 12 | // make it chain-able 13 | return $(this).each( function() { 14 | 15 | var $el = $(this), htmlEls = [], 16 | text, els, i, lastIndex, lngth, replaceRegex; 17 | 18 | // "text" is going to be our "goto-girl" for string manipulation 19 | text = $el.html(); 20 | 21 | // grab any html tags like a,strong,em 22 | els = text.match(/<([A-Z][A-Z0-9]*)\b[^>]*>/gi); 23 | lngth = ( els !== null ) ? els.length : 0; 24 | 25 | // each time we match a html element opening tag (eg: ), 26 | // save it into array and replace it with a placeholder like: "__n__"; 27 | for( i = 0; i < lngth; i++ ) { 28 | htmlEls.push( els[i] ); 29 | text = text.replace( els[i] , "__"+i+"__"); 30 | } 31 | 32 | // now we find the given number of gathered words, and then insert a 33 | // non-breaking-space ( ) in to the given number of spaces. 34 | for( i = 0; i < gather; i++ ) { 35 | lastIndex = text.lastIndexOf(" "); 36 | if( lastIndex > 0 ) { 37 | text = text.substring(0, lastIndex) + " " + text.substring(lastIndex + 1); 38 | } 39 | } 40 | // now we have put the non-breaking-spaces in, we must replace the 41 | // placeholders with the original html elements we stored earlier. 42 | for( i = 0; i < lngth; i++ ) { 43 | replaceRegex = new RegExp("__"+i+"__"); 44 | text = text.replace( replaceRegex , htmlEls[i] ); 45 | } 46 | 47 | // and finally replace the html with the sparkly new text string. 48 | $el.html( text ); 49 | 50 | }); 51 | 52 | }; 53 | 54 | }(jQuery)); -------------------------------------------------------------------------------- /unorphanize.jquery.min.js: -------------------------------------------------------------------------------- 1 | /*! jquery-unorphanize - v1.0.1 - 2014-04-18 2 | * Copyright (c) 2014 Simon Goellner ; Licensed */ 3 | !function(a){a.fn.unorphanize=function(b){return"number"!=typeof b&&(b=1),a(this).each(function(){var c,d,e,f,g,h,i=a(this),j=[];for(c=i.html(),d=c.match(/<([A-Z][A-Z0-9]*)\b[^>]*>/gi),g=null!==d?d.length:0,e=0;g>e;e++)j.push(d[e]),c=c.replace(d[e],"__"+e+"__");for(e=0;b>e;e++)f=c.lastIndexOf(" "),f>0&&(c=c.substring(0,f)+" "+c.substring(f+1));for(e=0;g>e;e++)h=new RegExp("__"+e+"__"),c=c.replace(h,j[e]);i.html(c)})}}(jQuery); --------------------------------------------------------------------------------