├── .csslintrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── demo ├── bigtextWizard.css ├── bigtextWizard.js ├── css │ ├── flexbox.css │ ├── images │ │ ├── button_bg.png │ │ ├── datepicker.gif │ │ ├── icon_sprite.png │ │ ├── progress_bar.gif │ │ ├── slider_h_bg.gif │ │ ├── slider_handles.png │ │ ├── slider_v_bg.gif │ │ ├── the_gradient.gif │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_228ef1_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── jquery-ui-1.8rc3.custom.css │ └── league-gothic │ │ ├── League_Gothic-webfont.eot │ │ ├── League_Gothic-webfont.svg │ │ ├── League_Gothic-webfont.ttf │ │ ├── League_Gothic-webfont.woff │ │ ├── stylesheet-delay.css.php │ │ └── stylesheet.css ├── js │ ├── jquery.ba-throttle-debounce.js │ ├── jquery.ba-throttle-debounce.min.js │ ├── modernizr-1.6.js │ └── modernizr-1.6.min.js ├── remoteFontLoad.html ├── simpleDemo.html ├── simpleDemoDiv.html ├── testTwoLines.html └── wizard.html ├── dist ├── bigtext.js └── test │ └── tests.js ├── grunt ├── banner.txt ├── config-lib │ ├── bytesize.js │ ├── clean.js │ ├── concat.js │ ├── csslint.js │ ├── gh-pages.js │ ├── jshint.js │ ├── lintspaces.js │ ├── mkdir.js │ ├── qunit.js │ ├── usebanner.js │ └── watch.js ├── config │ └── concat.js └── tasks.js ├── package.json ├── src ├── bigtext-test.js └── bigtext.js └── test └── test.html /.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [grunt/**] 16 | indent_style = tab 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | temp/ 3 | bower_components/ 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "eqnull": true, 5 | "forin": false, 6 | "immed": true, 7 | "indent": 2, 8 | "latedef": true, 9 | "noarg": true, 10 | "noempty": true, 11 | "nonew": true, 12 | "undef": true, 13 | "unused": true, 14 | "strict": true, 15 | "trailing": true, 16 | "browser": true, 17 | "devel": true, 18 | "jquery": true, 19 | "node": true, 20 | "predef": { 21 | "asyncTest": false, 22 | "deepEqual": false, 23 | "equal": false, 24 | "expect": false, 25 | "module": false, 26 | "notDeepEqual": false, 27 | "notEqual": false, 28 | "notStrictEqual": false, 29 | "ok": false, 30 | "QUnit": false, 31 | "raises": false, 32 | "start": false, 33 | "stop": false, 34 | "strictEqual": false, 35 | "test": false 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 6 4 | before_script: 5 | - npm install -g grunt-cli 6 | - npm install 7 | - npm install bower 8 | - bower install 9 | script: grunt -v 10 | 11 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 'use strict'; 3 | 4 | function loadConfig( path ) { 5 | var glob = require( "glob" ), 6 | object = {}, 7 | key; 8 | 9 | glob.sync( "*", { 10 | cwd: path 11 | }).forEach(function( option ) { 12 | key = option.replace( /\.js$/, "" ); 13 | if( !object.hasOwnProperty( key ) ) { 14 | object[ key ] = {}; 15 | } 16 | grunt.util._.extend( object[ key ], require( path + option ) ); 17 | }); 18 | 19 | return object; 20 | } 21 | 22 | var config = { 23 | pkg: grunt.file.readJSON( "package.json" ), 24 | banner: grunt.file.read( "grunt/banner.txt" ) 25 | }; 26 | 27 | grunt.util._.merge( config, loadConfig( "./grunt/config-lib/" ), loadConfig( "./grunt/config/" ) ); 28 | 29 | grunt.initConfig( config ); 30 | 31 | require( "matchdep" ).filterDev( "grunt-*" ).forEach( grunt.loadNpmTasks ); 32 | 33 | grunt.loadTasks( "grunt" ); 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Zach Leatherman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BigText 2 | 3 | [![Build Status](https://travis-ci.org/zachleat/BigText.png?branch=master)](https://travis-ci.org/zachleat/BigText) 4 | 5 | ## BigText Makes Text Big 6 | 7 | * Read the [original blog post](http://www.zachleat.com/web/bigtext-makes-text-big/) 8 | * Play around on the [demo](http://zachleat.github.io/BigText/demo/wizard.html) 9 | * Watch the [video](http://www.youtube.com/watch?v=OuqB6e6NPRM) 10 | 11 | ## [Download bigtext.js](https://zachleat.github.io/BigText/dist/bigtext.js) 12 | 13 | Or use [bower](http://bower.io/): `bower install bigtext` 14 | 15 | ## [Run the Tests](http://zachleat.github.io/BigText/test/test.html) 16 | 17 | ## Requirements 18 | 19 | 1. jQuery 20 | 1. A block level parent element. BigText will force all children to be block level as well. 21 | 22 | ## Learn More 23 | 24 | BigText works best on browsers that support [subpixel font scaling](http://status.modern.ie/subpixelfontscaling). In order to best serve sizes to all browsers, BigText will adjust `word-spacing` as well as `font-size`. 25 | 26 | ## Examples 27 | 28 | ### Simple Example 29 | 30 |
31 | BIGTEXT 32 | Makes Text Big 33 |
34 | 37 | 38 | ### Better, Progressive Enhancement-Based Example 39 | 40 | Use `display: inline` children (like a `span`) so the text will flow correctly if BigText doesn’t run. 41 | 42 |
43 | BIGTEXT 44 | Makes Text Big 45 |
46 | 52 | 53 | ### Using a List (ordered/unordered) 54 | 55 |
    56 |
  1. BIGTEXT
  2. 57 |
  3. Makes Text Big
  4. 58 |
59 | 62 | 63 | ### Restrict to a subset of children 64 | 65 | #### Opt-in children with JS 66 | 67 |
68 |

BIGTEXT

69 |

Makes Text Big

70 |
71 | 76 | 77 | #### Opt-out lines using markup 78 | 79 |
    80 |
  1. BIGTEXT
  2. 81 |
  3. Makes Text Big
  4. 82 |
83 | 86 | 87 | 88 | ### Mix and Match Fonts 89 | 90 |
    91 |
  1. 92 | BIG 93 | TEXT 94 |
  2. 95 |
  3. Makes Text Big
  4. 96 |
97 | 100 | 101 | Works also with `letter-spacing`, `word-spacing`, and `text-transform`. 102 | 103 | ### Using with Custom Font-Face 104 | 105 | **Warning**: a known issue exists with the [Google/TypeKit font loader in WebKit](https://github.com/typekit/webfontloader/issues/26). 106 | 107 |
108 | BIGTEXT 109 | Makes Text Big 110 |
111 | 112 | 125 | 126 | ### Change the default max font size 127 | 128 |
129 | BIG 130 |
131 | 136 | 137 | ### Adding a default min font size 138 | 139 |
140 | This is a super long line that will probably be resized to epically small proportions. We need a minimum font size! 141 |
142 | 147 | 148 | ### Is your text static and unchanging? 149 | 150 | See [Paravel's FitText plugin](http://fittextjs.com/). Curious how the two plugins compare? I've written a full [comparison between FitText and BigText](http://www.zachleat.com/web/fittext-and-bigtext/). 151 | 152 | ## Extra Features 153 | 154 | ### Re-BigText on Resize (Responsive BigText) 155 | 156 | As of 0.1.8, BigText implements its own debounced resize event. 157 | 158 | ### Debug Mode 159 | 160 | BigText uses an off-canvas detached node to improve performance when sizing. Setting `DEBUG_MODE` to true will leave this detached node on the canvas for visual inspection for problem resolution. 161 | 162 | BigText.DEBUG_MODE = true; 163 | 164 | ## Common Problems 165 | 166 | ### Lines Wrapping Pre-BigText 167 | The starting font-size must be small enough to guarantee that each individual line is not wrapping pre-BigText. If the line is too long, BigText will not size it correctly. 168 | 169 | ## Releases 170 | 171 | * `v0.1.0` Initial release 172 | * `v0.1.1` Added line exempt feature. 173 | * `v0.1.2` Responsive BigText resizes with media queries and resize events (optionally debounced). 174 | * `v0.1.3` 175 | * `v0.1.4` on `2013-08-24` Numerous bug fixes, improved accuracy, adds debug mode. 176 | * `v0.1.5` on `2013-10-14` BigText uses all children by default (#40) 177 | * `v0.1.6` Various bug fixes. 178 | 179 | 180 | ## Using the repo 181 | 182 | Run these commands: 183 | 184 | * `npm install` 185 | * `bower install` 186 | * `grunt` 187 | 188 | ## Configuring Grunt 189 | 190 | Rather than one giant `Gruntfile.js`, this project is using a modular Grunt setup. Each individual grunt configuration option key has its own file located in `grunt/config-lib/` (readonly upstream configs, do not modify these directly) or `grunt/config/` (project specific configs). You may use the same key in both directories, the objects are smartly combined using [Lo-Dash merge](http://lodash.com/docs#merge). 191 | 192 | For concatenation in the previous Gruntfile setup, you’d add another key to the giant object passed into `grunt.initConfig` like this: `grunt.initConfig({ concat: { /* YOUR CONFIG */ } });`. In the new configuration, you’ll create a `grunt/config/concat.js` with `module.exports = { /* YOUR CONFIG */ };`. 193 | 194 | ## License 195 | 196 | [MIT License](http://en.wikipedia.org/wiki/MIT_License) 197 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bigtext", 3 | "version": "0.1.8", 4 | "main": ["dist/bigtext.js"], 5 | "ignore": [ 6 | "**/.*" 7 | ], 8 | "dependencies": { 9 | "jquery": ">=1.9.1" 10 | }, 11 | "devDependencies": { 12 | "qunit": ">=1.12.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/bigtextWizard.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-right: 200px; 3 | overflow: hidden; 4 | background-repeat: no-repeat; 5 | } 6 | body.bigtextWizardWhite { 7 | -webkit-transition: 1.4s; 8 | background-color: #fff; 9 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ddd), to(#fff)); 10 | background-image: -moz-linear-gradient(#ddd, #fff); 11 | color: #111; 12 | } 13 | body.bigtextWizardBlack { 14 | -webkit-transition: 1.4s; 15 | background-color: #000; 16 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222), to(#000)); 17 | background-image: -moz-linear-gradient(#222, #000); 18 | color: #eee; 19 | } 20 | html, body { height: 100%; } 21 | body, textarea, h1, h2, h3 { font-family: Helvetica, Arial; } 22 | .ui-slider { cursor: pointer; } 23 | .ui-tabs { background-color: transparent; } 24 | .ui-tabs .ui-tabs-panel { background-color: #fff; } 25 | .info-box { padding: 0 .7em; margin: 1em 0; } 26 | #hint.info-box { display: table; margin: 1em auto; } 27 | .info-box .ui-icon { float: left; margin-right: .4em; } 28 | 29 | #centered { 30 | width: 100%; 31 | height: 100%; 32 | } 33 | #container { 34 | -webkit-perspective: 600; 35 | height: 100%; 36 | } 37 | #bigtext { 38 | -webkit-transform-style: preserve-3d; 39 | text-shadow: 0 0 1px hsla(0, 0%, 30%, 0.4); 40 | } 41 | #bigtext.blurred { 42 | color: #ddd; 43 | } 44 | #bigtext div { 45 | white-space: nowrap; 46 | cursor: none; 47 | } 48 | #bigtext > div:hover { 49 | cursor: text; 50 | } 51 | #bigtext > div:focus { 52 | outline: none; 53 | } 54 | #bigtext.animate3d { 55 | -webkit-transition: 0.3s; 56 | } 57 | @-webkit-keyframes fadeOut { 58 | from { 59 | opacity: 1; 60 | } 61 | to { 62 | opacity: 0; 63 | } 64 | } 65 | #bigtext.fadeOut { 66 | -webkit-animation-name: fadeOut; 67 | -webkit-animation-duration: 0.2s; 68 | -webkit-animation-iteration-count: 2; 69 | -webkit-animation-direction: alternate; 70 | } 71 | #bigtext.fadeIn { 72 | opacity: 1; 73 | } 74 | ::selection { 75 | background: #000; 76 | color: #fff; 77 | } 78 | ::-moz-selection { 79 | background: #000; 80 | color: #fff; 81 | } 82 | .bigtext { 83 | margin: 0 auto; 84 | width: 430px; 85 | font-family: Helvetica, Arial; 86 | } 87 | .csstransforms3d .no-3d-transforms-support { 88 | display: none; 89 | } 90 | #toolbar { 91 | position: fixed; 92 | right: 0; 93 | top: 0; 94 | width: 320px; 95 | padding: 20px; 96 | text-align: center; 97 | } 98 | textarea, 99 | select { 100 | width: 100%; 101 | } 102 | #font { 103 | height: 80px; 104 | } 105 | #customStyle { 106 | height: 120px; 107 | margin-top: 1em; 108 | font-family: 'Courier New'; 109 | } 110 | #code { 111 | font-size: 11px; 112 | width: 100%; 113 | padding: 10px 0; 114 | } 115 | #lineHeightSliders {} 116 | #lineHeightSliders .ui-slider { 117 | height: 80px; 118 | display: inline-block; 119 | margin: 0 10px; 120 | } 121 | #random-3d, 122 | #translate-buttons { 123 | margin-top: 1em; 124 | } 125 | 126 | @media print { 127 | #toolbar { display: none; } 128 | body { padding-right: 0; } 129 | } -------------------------------------------------------------------------------- /demo/bigtextWizard.js: -------------------------------------------------------------------------------- 1 | var BigTextWizard = { 2 | LINE_HEIGHT_STYLE_ID: 'bigtext-wizard-lineheight-styleinjection', 3 | CUSTOM_STYLE_ID: 'bigtext-wizard-styleinjection', 4 | DEFAULT_TEXT: '', 5 | loadedFonts: {}, 6 | fontUrls: { 7 | 'LeagueGothicRegular': 'css/league-gothic/stylesheet.css', 8 | 'Droid Sans': 'http://fonts.googleapis.com/css?family=Droid+Sans', 9 | 'Yanone Kaffeesatz': 'http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz', 10 | 'Molengo': 'http://fonts.googleapis.com/css?family=Molengo', 11 | 'Droid Sans Mono': 'http://fonts.googleapis.com/css?family=Droid+Sans+Mono', 12 | 'Arvo': 'http://fonts.googleapis.com/css?family=Arvo:regular,bold', 13 | 'Arimo': 'http://fonts.googleapis.com/css?family=Arimo', 14 | 'Puritan': 'http://fonts.googleapis.com/css?family=Puritan', 15 | 'IM Fell English': 'http://fonts.googleapis.com/css?family=IM+Fell+English' 16 | }, 17 | clear: function(ignoreFocus) 18 | { 19 | var cleared = $('
').html(BigTextWizard.DEFAULT_TEXT); 20 | $('#bigtext').empty().append(cleared); 21 | BigTextWizard._init(); 22 | cleared.trigger('focus'); 23 | }, 24 | _init: function() 25 | { 26 | var $bt = $('#bigtext'); 27 | $bt.bigtext(); 28 | 29 | BigTextWizard.initializeLineHeights(); 30 | BigTextWizard.initEditable.call($bt.find('> div')); 31 | }, 32 | init: function() 33 | { 34 | var fontFamily = $('#font').val(); 35 | if(BigTextWizard.loadedFonts[fontFamily]) { 36 | BigTextWizard._init(); 37 | } else { 38 | BigTextWizard.loadFont(fontFamily, BigTextWizard._init); 39 | } 40 | }, 41 | initEditable: function() 42 | { 43 | return this.attr({ 44 | contenteditable: true, 45 | spellcheck: false 46 | }) 47 | .unbind('keypress keyup, blur') 48 | .bind('keypress', function(event) 49 | { 50 | var $t = $(this); 51 | if(event.which == 13) { 52 | var element; 53 | 54 | if(!event.shiftKey) { 55 | element = $t.nextAll().eq(0); 56 | if(!element.length) { 57 | element = BigTextWizard.initEditable.call($('
')).appendTo($t.parent()); 58 | } 59 | } else { 60 | element = $t.prevAll().eq(0); 61 | } 62 | 63 | // IE8 wasn't letting focus here without a timeout. 64 | if($.browser.msie && $.browser.version <= 8) { 65 | window.setTimeout(function() { 66 | element.trigger('focus'); 67 | }, 100); 68 | } else { 69 | element.trigger('focus'); 70 | } 71 | return false; 72 | } 73 | }).bind('keyup', $.throttle(250, function() 74 | { 75 | var $t = $(this); 76 | if($t.text() && $t.text() != BigTextWizard.DEFAULT_TEXT) { 77 | $t.parent().removeClass('blurred'); 78 | } 79 | 80 | $t.parent().bigtext(); 81 | })).bind('blur', function() 82 | { 83 | var $t = $(this); 84 | if(!$.trim($t.text()) && $t.siblings().length > 0) { 85 | $t.remove(); 86 | } 87 | 88 | BigTextWizard.initializeLineHeights(); 89 | }); 90 | }, 91 | generateStyleTag: function(id, css) 92 | { 93 | return $('
').attr('id', id).html(''); 94 | }, 95 | transform3dEvent: function() { 96 | BigTextWizard.rotate3d.call($('#bigtext'), $('#3d-x-slider').is(':checked') ? 1 : 0, $('#3d-y-slider').is(':checked') ? 1 : 0, $('#3d-z-slider').is(':checked') ? 1 : 0, $('#3d-angle-slider').slider('value') + 'deg'); 97 | }, 98 | rotate3d: function(x, y, z, angle) { 99 | // front: -90 < x, y < 90 100 | this.css('-webkit-transform', 'rotate3d(' + x + ',' + y + ',' + z + ',' + angle + ')'); 101 | }, 102 | translate: function(x, y, z) 103 | { 104 | var existingTransform = this.css('-webkit-transform') || ''; //rotate3d(0, 0, 0, 0deg)'; 105 | 106 | this.css('-webkit-transform', (existingTransform ? existingTransform + ' ' : '') + 107 | 'translate3d(' + (x ? x + 'px' : '0') + ',' + (y ? y + 'px' : '0') + ',' + (z ? z + 'px' : '0') + ')'); 108 | }, 109 | resetTransform: function() 110 | { 111 | $('#bigtext').css('-webkit-transform', ''); 112 | }, 113 | loadFont: function(fontFamily, callback) 114 | { 115 | WebFont.load({ 116 | custom: { 117 | families: [fontFamily], 118 | urls : [BigTextWizard.fontUrls[fontFamily]] 119 | }, 120 | active: function() { 121 | BigTextWizard.loadedFonts[fontFamily] = true; 122 | callback(); 123 | } 124 | }); 125 | }, 126 | setCustomStyle: function() 127 | { 128 | var fontFace = $('#font').val(); 129 | $('#' + BigTextWizard.CUSTOM_STYLE_ID).remove(); 130 | BigTextWizard.generateStyleTag(BigTextWizard.CUSTOM_STYLE_ID, [$('#customStyle').val(), 131 | (fontFace ? '\n.bigtext { font-family: \'' + fontFace + '\'; }' : '')]) 132 | .appendTo('head'); 133 | }, 134 | setHtml: function() 135 | { 136 | function clean(html) 137 | { 138 | return (html || '').replace(//g, '>'); 139 | } 140 | 141 | var fontFace = $('#font').val(); 142 | $('#code').html(clean([ 143 | '', 144 | '', 145 | '', 146 | '', 147 | (fontFace ? '' : ''), 148 | '', 154 | '', 155 | '', 156 | '
', 157 | $('#bigtext').html(), 158 | '
', 159 | '', 160 | ''].join('\n'))); 161 | }, 162 | setLineHeightCss: function() 163 | { 164 | $('#' + BigTextWizard.LINE_HEIGHT_STYLE_ID).remove(); 165 | 166 | BigTextWizard.generateStyleTag(BigTextWizard.LINE_HEIGHT_STYLE_ID, $.makeArray($('#lineHeightSliders').find('> div').map(function(n) 167 | { 168 | var lineHeight = $(this).slider('value'); 169 | return lineHeight !== 1 ? '.bigtext > .' + BigText.LINE_CLASS_PREFIX + (n+1) + ' { line-height: ' + lineHeight + 'em; }' : null; 170 | }))).appendTo('head'); 171 | }, 172 | initializeLineHeights: function() 173 | { 174 | var $sliders = $('#lineHeightSliders'), 175 | $lines = $('#bigtext > div'); 176 | 177 | if($lines.length < 2) { 178 | $sliders.html('Add another line!'); 179 | return; 180 | } else if($lines.length == $sliders.find('> div.ui-slider').length - 1) { 181 | return; 182 | } 183 | 184 | $sliders.empty(); 185 | 186 | $lines.each(function(lineNumber) 187 | { 188 | if(!lineNumber) { 189 | return; 190 | } 191 | 192 | $('
').appendTo($sliders).slider({ 193 | min: 0, 194 | max: 2, 195 | step: .05, 196 | value: 1, 197 | orientation: 'vertical', 198 | range: 'min', 199 | animate: true 200 | }).bind('slidechange', function() { 201 | BigTextWizard.setLineHeightCss(); 202 | }); 203 | }); 204 | } 205 | }; 206 | 207 | 208 | $('#widthSlider').slider({ 209 | min: 260, 210 | max: 1024, 211 | range: 'min', 212 | value: 430 213 | }).bind('slidechange', function() { 214 | var value = $(this).slider('value'); 215 | $('#posterWidth').html(value); 216 | $('#bigtext').width(value).find('div').each(function() { 217 | $(this).removeAttr('style').removeAttr('class'); 218 | }); 219 | 220 | BigTextWizard.init(); 221 | }); 222 | 223 | $('#customStyle').bind('change', function() { 224 | BigTextWizard.setCustomStyle(); 225 | BigTextWizard.init(); 226 | }); 227 | 228 | $('#clear').button().bind('click', BigTextWizard.clear); 229 | 230 | $('#refresh').button().bind('click', BigTextWizard.init); 231 | 232 | $('#font').bind('change', function() 233 | { 234 | BigTextWizard.setCustomStyle(); 235 | BigTextWizard.init(); 236 | }); 237 | 238 | $('#tabs').tabs(); 239 | 240 | $('#3d-angle-slider').slider({ 241 | min: -70, 242 | max: 70, 243 | range: 'min', 244 | value: 0, 245 | step: 1 246 | }).bind('slidechange', function() 247 | { 248 | var deg = $(this).slider('value') ; 249 | $('#3d-angle-value').html(deg + ' degree' + (deg != 1 ? 's' : '')); 250 | BigTextWizard.transform3dEvent(); 251 | }); 252 | 253 | $('#3d-animate-slider').bind('change', function() 254 | { 255 | $('#bigtext').toggleClass('animate3d'); 256 | }); 257 | $('#tabs-3d .dimension-slider').bind('change', BigTextWizard.transform3dEvent); 258 | 259 | $('#reset-3d').button().bind('click', function() 260 | { 261 | $('#3d-angle-slider').slider('value', 0); 262 | }); 263 | 264 | $('#random-3d').button().bind('click', function() 265 | { 266 | if(Math.round(Math.random())) { 267 | $('#3d-x-slider').attr('checked', 'checked'); 268 | } else { 269 | $('#3d-x-slider').removeAttr('checked'); 270 | } 271 | 272 | if(Math.round(Math.random())) { 273 | $('#3d-y-slider').attr('checked', 'checked'); 274 | } else { 275 | $('#3d-y-slider').removeAttr('checked'); 276 | } 277 | 278 | if(Math.round(Math.random())) { 279 | $('#3d-z-slider').attr('checked', 'checked'); 280 | } else { 281 | $('#3d-z-slider').removeAttr('checked'); 282 | } 283 | 284 | // Setting the value triggers slidechange, which triggers transform3dEvent 285 | $('#3d-angle-slider').slider('value', Math.round(Math.random()*180) - 90); 286 | }); 287 | 288 | $('#translate-buttons button').button().bind('click', function() 289 | { 290 | var id = $(this).attr('id'), 291 | AMOUNT = 200, 292 | x = 0, 293 | y = 0, 294 | z = 0; 295 | 296 | switch(id) { 297 | case 'translate-x-minus': 298 | x = -1*AMOUNT; 299 | break; 300 | case 'translate-x-plus': 301 | x = AMOUNT; 302 | break; 303 | case 'translate-y-minus': 304 | y = -1*AMOUNT; 305 | break; 306 | case 'translate-y-plus': 307 | y = AMOUNT; 308 | break; 309 | case 'translate-z-minus': 310 | z = -1*AMOUNT; 311 | break; 312 | case 'translate-z-plus': 313 | z = AMOUNT; 314 | break; 315 | } 316 | 317 | BigTextWizard.translate.call($('#bigtext'), x, y, z); 318 | }); 319 | 320 | $(window).bind('click', function(event) 321 | { 322 | if(!$(event.target).closest('#toolbar').length) { 323 | $('#bigtext > div').eq(0).trigger('focus'); 324 | } 325 | }).bind('load', function() 326 | { 327 | BigTextWizard.setCustomStyle(); 328 | BigTextWizard.init(); 329 | 330 | $('#3d-animate-slider').trigger('click').trigger('change'); 331 | }).bind('keydown', function(event) 332 | { 333 | // Keyboard shortcuts 334 | if(event.ctrlKey && event.altKey) { 335 | var $bigtext = $('#bigtext'); 336 | 337 | switch(event.which) { 338 | case 90: // z 339 | BigTextWizard.clear(); 340 | return false; 341 | case 67: // c 342 | $('body').toggleClass('bigtextWizardWhite').toggleClass('bigtextWizardBlack'); 343 | return false; 344 | case 88: // x 345 | $('#random-3d').trigger('click'); 346 | return false; 347 | case 37: // left arrow 348 | BigTextWizard.rotate3d.call($bigtext, 0, 0, 1, '-90deg'); 349 | return false; 350 | case 39: // right arrow 351 | BigTextWizard.rotate3d.call($bigtext, 0, 0, 1, '90deg'); 352 | return false; 353 | case 82: // r 354 | $('#reset-3d').trigger('click'); 355 | return false; 356 | case 32: // space 357 | case 13: // enter 358 | $bigtext.removeClass('fadeIn').addClass('fadeOut'); 359 | //.find('> div').eq(0).trigger('focus'); 360 | 361 | window.setTimeout(function() 362 | { 363 | if(event.which == 32) { 364 | $('#random-3d').trigger('click'); 365 | } 366 | BigTextWizard.clear(); 367 | $bigtext.removeClass('fadeOut').addClass('fadeIn'); 368 | }, 200); 369 | 370 | return false; 371 | } 372 | } 373 | }); -------------------------------------------------------------------------------- /demo/css/flexbox.css: -------------------------------------------------------------------------------- 1 | /* Alex Russell's hbox and vbox classes 2 | * http://infrequently.org/2009/08/css-3-progress/ 3 | */ 4 | 5 | .hbox { 6 | display: -webkit-box; 7 | -webkit-box-orient: horizontal; 8 | -webkit-box-align: stretch; 9 | 10 | display: -moz-box; 11 | -moz-box-orient: horizontal; 12 | -moz-box-align: stretch; 13 | 14 | display: box; 15 | box-orient: horizontal; 16 | box-align: stretch; 17 | } 18 | 19 | .hbox > * { 20 | -webkit-box-flex: 0; 21 | -moz-box-flex: 0; 22 | box-flex: 0; 23 | display: block; 24 | } 25 | 26 | .vbox { 27 | display: -webkit-box; 28 | -webkit-box-orient: vertical; 29 | -webkit-box-align: stretch; 30 | 31 | display: -moz-box; 32 | -moz-box-orient: vertical; 33 | -moz-box-align: stretch; 34 | 35 | display: box; 36 | box-orient: vertical; 37 | box-align: stretch; 38 | } 39 | 40 | .vbox > * { 41 | -webkit-box-flex: 0; 42 | -moz-box-flex: 0; 43 | box-flex: 0; 44 | display: block; 45 | } 46 | 47 | .spacer { 48 | -webkit-box-flex: 1; 49 | -moz-box-flex: 1; 50 | box-flex: 1; 51 | } 52 | 53 | .reverse { 54 | -webkit-box-direction: reverse; 55 | -moz-box-direction: reverse; 56 | box-direction: reverse; 57 | } 58 | 59 | .boxFlex0 { 60 | -webkit-box-flex: 0; 61 | -moz-box-flex: 0; 62 | box-flex: 0; 63 | } 64 | 65 | .boxFlex1, .boxFlex { 66 | -webkit-box-flex: 1; 67 | -moz-box-flex: 1; 68 | box-flex: 1; 69 | } 70 | 71 | .boxFlex2 { 72 | -webkit-box-flex: 2; 73 | -moz-box-flex: 2; 74 | box-flex: 2; 75 | } 76 | 77 | .boxGroup1 { 78 | -webkit-box-flex-group: 1; 79 | -moz-box-flex-group: 1; 80 | box-flex-group: 1; 81 | } 82 | 83 | .boxGroup2 { 84 | -webkit-box-flex-group: 2; 85 | -moz-box-flex-group: 2; 86 | box-flex-group: 2; 87 | } 88 | 89 | .start { 90 | -webkit-box-pack: start; 91 | -moz-box-pack: start; 92 | box-pack: start; 93 | } 94 | 95 | .end { 96 | -webkit-box-pack: end; 97 | -moz-box-pack: end; 98 | box-pack: end; 99 | } 100 | 101 | .center { 102 | -webkit-box-pack: center; 103 | -moz-box-pack: center; 104 | box-pack: center; 105 | } -------------------------------------------------------------------------------- /demo/css/images/button_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/button_bg.png -------------------------------------------------------------------------------- /demo/css/images/datepicker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/datepicker.gif -------------------------------------------------------------------------------- /demo/css/images/icon_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/icon_sprite.png -------------------------------------------------------------------------------- /demo/css/images/progress_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/progress_bar.gif -------------------------------------------------------------------------------- /demo/css/images/slider_h_bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/slider_h_bg.gif -------------------------------------------------------------------------------- /demo/css/images/slider_handles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/slider_handles.png -------------------------------------------------------------------------------- /demo/css/images/slider_v_bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/slider_v_bg.gif -------------------------------------------------------------------------------- /demo/css/images/the_gradient.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/the_gradient.gif -------------------------------------------------------------------------------- /demo/css/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /demo/css/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /demo/css/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /demo/css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /demo/css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /demo/css/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /demo/css/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /demo/css/jquery-ui-1.8rc3.custom.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Aristo for jQuery UI 3 | * Licensed under Creative Commons Attribution-Share Alike 3.0 with permission from 280 North and Pinvoke. 4 | */ 5 | 6 | /* 7 | * jQuery UI CSS Framework 8 | * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) 9 | * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. 10 | */ 11 | 12 | /* === Layout helpers === */ 13 | .ui-helper-hidden { display: none; } 14 | .ui-helper-hidden-accessible { position: absolute; left: -99999999px; } 15 | .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } 16 | .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } 17 | .ui-helper-clearfix { display: inline-block; } 18 | /* required comment for clearfix to work in Opera \*/ 19 | * html .ui-helper-clearfix { height:1%; } 20 | .ui-helper-clearfix { display:block; } 21 | /* end clearfix */ 22 | .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } 23 | 24 | 25 | /* === Interaction Cues === */ 26 | .ui-state-disabled { cursor: default !important; } 27 | 28 | 29 | /* === Icons === */ 30 | 31 | /* states and images */ 32 | .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } 33 | 34 | 35 | /* === Misc visuals === -*/ 36 | 37 | /* Overlays */ 38 | .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } 39 | 40 | 41 | 42 | /* === Component containers === */ 43 | .ui-widget { font-family: Helvetica, Arial, sans-serif; outline: none;} 44 | .ui-widget a { outline: none; } 45 | .ui-widget .ui-widget { font-size: 1em; } 46 | .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica, Arial, sans-serif; font-size: 1em; } 47 | .ui-widget-content { border: 1px solid #dddddd; color: #333333; background: #FFFFFF; } 48 | .ui-widget-content a { color: #333333; } 49 | .ui-widget-header { border: 1px solid #8ab0c6; background: #a7cfe6; color: #ffffff; font-weight: bold; } 50 | .ui-widget-header a { color: #ffffff; } 51 | 52 | /* === Interaction states === */ 53 | .ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #5F83B9; } 54 | .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } 55 | .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #749aaf; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } 56 | .ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } 57 | .ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } 58 | .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } 59 | .ui-widget :active { outline: none; } 60 | 61 | /* === Interaction Cues === */ 62 | .ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #d2dbf4; background: #f4f8fd; color: #0d2054; -moz-border-radius: 0px !important; -webkit-border-radius: 0px !important; border-radius: 0px !important; font-size: 11px; } 63 | .ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #0d2054; } 64 | .ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #e2d0d0; background: #fcf0f0; color: #280b0b; -moz-border-radius: 0px !important; -webkit-border-radius: 0px !important; border-radius: 0px !important; font-size: 11px; } 65 | .ui-state-error a, .ui-widget-content .ui-state-error a { color: #280b0b; } 66 | .ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #280b0b; } 67 | .ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } 68 | .ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } 69 | .ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } 70 | .ui-state-highlight p, .ui-state-error p { margin: 8px 0px; padding: 1px 0px; } 71 | .ui-state-highlight .ui-icon, .ui-state-error .ui-icon { margin: -1px 8px 0px 0px !important; } 72 | 73 | /* === Icons === */ 74 | 75 | /* states and images */ 76 | .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } 77 | .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 78 | .ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } 79 | .ui-state-default .ui-icon { background-image: url(images/ui-icons_222222_256x240.png); } 80 | .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 81 | .ui-state-active .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } 82 | .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } 83 | .ui-state-error .ui-icon, .ui-state-error-text .ui-icon { background: url(images/icon_sprite.png) -16px 0px no-repeat !important; } 84 | 85 | /* positioning */ 86 | .ui-icon-carat-1-n { background-position: 0 0; } 87 | .ui-icon-carat-1-ne { background-position: -16px 0; } 88 | .ui-icon-carat-1-e { background-position: -32px 0; } 89 | .ui-icon-carat-1-se { background-position: -48px 0; } 90 | .ui-icon-carat-1-s { background-position: -64px 0; } 91 | .ui-icon-carat-1-sw { background-position: -80px 0; } 92 | .ui-icon-carat-1-w { background-position: -96px 0; } 93 | .ui-icon-carat-1-nw { background-position: -112px 0; } 94 | .ui-icon-carat-2-n-s { background-position: -128px 0; } 95 | .ui-icon-carat-2-e-w { background-position: -144px 0; } 96 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 97 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 98 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 99 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 100 | .ui-icon-triangle-1-s { background-position: -64px -16px; } 101 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 102 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 103 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 104 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 105 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 106 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 107 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 108 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 109 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 110 | .ui-icon-arrow-1-s { background-position: -64px -32px; } 111 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 112 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 113 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 114 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 115 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 116 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 117 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 118 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 119 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 120 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 121 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 122 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 123 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 124 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 125 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 126 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 127 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 128 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 129 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 130 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 131 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 132 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 133 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 134 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 135 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 136 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 137 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 138 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 139 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 140 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 141 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 142 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 143 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 144 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 145 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 146 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 147 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 148 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 149 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 150 | .ui-icon-arrow-4 { background-position: 0 -80px; } 151 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 152 | .ui-icon-extlink { background-position: -32px -80px; } 153 | .ui-icon-newwin { background-position: -48px -80px; } 154 | .ui-icon-refresh { background-position: -64px -80px; } 155 | .ui-icon-shuffle { background-position: -80px -80px; } 156 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 157 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 158 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 159 | .ui-icon-folder-open { background-position: -16px -96px; } 160 | .ui-icon-document { background-position: -32px -96px; } 161 | .ui-icon-document-b { background-position: -48px -96px; } 162 | .ui-icon-note { background-position: -64px -96px; } 163 | .ui-icon-mail-closed { background-position: -80px -96px; } 164 | .ui-icon-mail-open { background-position: -96px -96px; } 165 | .ui-icon-suitcase { background-position: -112px -96px; } 166 | .ui-icon-comment { background-position: -128px -96px; } 167 | .ui-icon-person { background-position: -144px -96px; } 168 | .ui-icon-print { background-position: -160px -96px; } 169 | .ui-icon-trash { background-position: -176px -96px; } 170 | .ui-icon-locked { background-position: -192px -96px; } 171 | .ui-icon-unlocked { background-position: -208px -96px; } 172 | .ui-icon-bookmark { background-position: -224px -96px; } 173 | .ui-icon-tag { background-position: -240px -96px; } 174 | .ui-icon-home { background-position: 0 -112px; } 175 | .ui-icon-flag { background-position: -16px -112px; } 176 | .ui-icon-calendar { background-position: -32px -112px; } 177 | .ui-icon-cart { background-position: -48px -112px; } 178 | .ui-icon-pencil { background-position: -64px -112px; } 179 | .ui-icon-clock { background-position: -80px -112px; } 180 | .ui-icon-disk { background-position: -96px -112px; } 181 | .ui-icon-calculator { background-position: -112px -112px; } 182 | .ui-icon-zoomin { background-position: -128px -112px; } 183 | .ui-icon-zoomout { background-position: -144px -112px; } 184 | .ui-icon-search { background-position: -160px -112px; } 185 | .ui-icon-wrench { background-position: -176px -112px; } 186 | .ui-icon-gear { background-position: -192px -112px; } 187 | .ui-icon-heart { background-position: -208px -112px; } 188 | .ui-icon-star { background-position: -224px -112px; } 189 | .ui-icon-link { background-position: -240px -112px; } 190 | .ui-icon-cancel { background-position: 0 -128px; } 191 | .ui-icon-plus { background-position: -16px -128px; } 192 | .ui-icon-plusthick { background-position: -32px -128px; } 193 | .ui-icon-minus { background-position: -48px -128px; } 194 | .ui-icon-minusthick { background-position: -64px -128px; } 195 | .ui-icon-close { background-position: -80px -128px; } 196 | .ui-icon-closethick { background-position: -96px -128px; } 197 | .ui-icon-key { background-position: -112px -128px; } 198 | .ui-icon-lightbulb { background-position: -128px -128px; } 199 | .ui-icon-scissors { background-position: -144px -128px; } 200 | .ui-icon-clipboard { background-position: -160px -128px; } 201 | .ui-icon-copy { background-position: -176px -128px; } 202 | .ui-icon-contact { background-position: -192px -128px; } 203 | .ui-icon-image { background-position: -208px -128px; } 204 | .ui-icon-video { background-position: -224px -128px; } 205 | .ui-icon-script { background-position: -240px -128px; } 206 | .ui-icon-alert { background-position: 0 -144px; } 207 | .ui-icon-info { background: url(images/icon_sprite.png) 0px 0px no-repeat !important; } 208 | .ui-icon-notice { background-position: -32px -144px; } 209 | .ui-icon-help { background-position: -48px -144px; } 210 | .ui-icon-check { background-position: -64px -144px; } 211 | .ui-icon-bullet { background-position: -80px -144px; } 212 | .ui-icon-radio-off { background-position: -96px -144px; } 213 | .ui-icon-radio-on { background-position: -112px -144px; } 214 | .ui-icon-pin-w { background-position: -128px -144px; } 215 | .ui-icon-pin-s { background-position: -144px -144px; } 216 | .ui-icon-play { background-position: 0 -160px; } 217 | .ui-icon-pause { background-position: -16px -160px; } 218 | .ui-icon-seek-next { background-position: -32px -160px; } 219 | .ui-icon-seek-prev { background-position: -48px -160px; } 220 | .ui-icon-seek-end { background-position: -64px -160px; } 221 | .ui-icon-seek-start { background-position: -80px -160px; } 222 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 223 | .ui-icon-seek-first { background-position: -80px -160px; } 224 | .ui-icon-stop { background-position: -96px -160px; } 225 | .ui-icon-eject { background-position: -112px -160px; } 226 | .ui-icon-volume-off { background-position: -128px -160px; } 227 | .ui-icon-volume-on { background-position: -144px -160px; } 228 | .ui-icon-power { background-position: 0 -176px; } 229 | .ui-icon-signal-diag { background-position: -16px -176px; } 230 | .ui-icon-signal { background-position: -32px -176px; } 231 | .ui-icon-battery-0 { background-position: -48px -176px; } 232 | .ui-icon-battery-1 { background-position: -64px -176px; } 233 | .ui-icon-battery-2 { background-position: -80px -176px; } 234 | .ui-icon-battery-3 { background-position: -96px -176px; } 235 | .ui-icon-circle-plus { background-position: 0 -192px; } 236 | .ui-icon-circle-minus { background-position: -16px -192px; } 237 | .ui-icon-circle-close { background-position: -32px -192px; } 238 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 239 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 240 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 241 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 242 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 243 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 244 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 245 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 246 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 247 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 248 | .ui-icon-circle-check { background-position: -208px -192px; } 249 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 250 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 251 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 252 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 253 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 254 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 255 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 256 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 257 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 258 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 259 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 260 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 261 | 262 | /* === Corner radius === */ 263 | .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } 264 | .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } 265 | .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } 266 | .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 267 | .ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } 268 | .ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 269 | .ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } 270 | .ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } 271 | .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } 272 | 273 | /* === Overlays === */ 274 | .ui-widget-overlay { background: #222d3f; opacity: .70; filter:Alpha(Opacity=70); } 275 | .ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } 276 | 277 | /* === Resizable === */ 278 | .ui-resizable { position: relative;} 279 | .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} 280 | .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } 281 | .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } 282 | .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } 283 | .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } 284 | .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } 285 | .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } 286 | .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } 287 | .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } 288 | .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;} 289 | 290 | /* === Accordion === */ 291 | 292 | .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; background: url(images/button_bg.png) repeat-x; } 293 | .ui-accordion .ui-accordion-header .ui-state-default { background-position: 0px 0px; } 294 | .ui-accordion .ui-accordion-header.ui-state-active { background-position: 0px -33px; border-color: #749aaf !important; } 295 | .ui-accordion .ui-accordion-header.ui-state-hover, .ui-accordion h3.ui-state-default { border-color: #aaaaaa; } 296 | .ui-accordion .ui-accordion-header.ui-state-active a { color:#1c4257; } 297 | .ui-accordion .ui-accordion-header .ui-icon { background: url(images/icon_sprite.png); } 298 | .ui-accordion .ui-accordion-header.ui-state-active .ui-icon { background-position: 0px -64px; } 299 | .ui-accordion .ui-accordion-header.ui-state-default .ui-icon { background-position: -16px -80px; } 300 | .ui-accordion .ui-accordion-li-fix { display: inline; } 301 | .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } 302 | .ui-accordion .ui-accordion-header a { display: block; font-size: 12px; padding: .5em .5em .5em .7em; font-weight: bold; color:#4f4f4f; text-shadow: 0px 1px 0px rgba(255,255,255,0.7); } 303 | .ui-accordion-icons .ui-accordion-header a { padding-left: 24px; } 304 | .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -7px; } 305 | .ui-accordion .ui-accordion-content { background: #f8fcfe; padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; font-size: 11px; border-color: #749aaf; } 306 | .ui-accordion .ui-accordion-content-active { display: block; } 307 | .ui-accordion .ui-accordion-header, .ui-accordion .ui-accordion-content { -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } 308 | .ui-accordion .ui-state-active { } 309 | 310 | /* === Autocomplete === */ 311 | .ui-autocomplete { position: absolute; z-index: 2 !important; cursor: default; background: #FFFFFF; border: 0px none !important; padding: 0px !important; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); } 312 | .ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } 313 | /* workarounds */ 314 | * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ 315 | 316 | /* === Menu === */ 317 | .ui-menu { 318 | list-style:none; 319 | padding: 2px; 320 | margin: 0; 321 | display:block; 322 | } 323 | .ui-menu .ui-menu { 324 | margin-top: -3px; 325 | } 326 | .ui-menu .ui-menu-item { 327 | margin:0; 328 | padding: 0; 329 | width: 100%; 330 | } 331 | .ui-menu .ui-menu-item a { 332 | text-decoration:none; 333 | display:block; 334 | border: 0px none; 335 | padding:.2em .4em; 336 | line-height:1.5; 337 | -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; 338 | } 339 | .ui-menu .ui-menu-item a.ui-state-hover, 340 | .ui-menu .ui-menu-item a.ui-state-active { 341 | background: #5f83b9; 342 | color: #FFFFFF; 343 | text-shadow: 0px 1px 1px #234386; 344 | font-weight: normal; 345 | } 346 | 347 | /* === Button === */ 348 | .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; border: 0px none !important; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } /* the overflow property removes extra width in IE */ 349 | .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ 350 | button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ 351 | .ui-button-icons-only { width: 3em; } 352 | button.ui-button-icons-only { width: 3.2em; } 353 | .ui-button span { -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; border: 1px solid; } 354 | 355 | 356 | /* === INPUT:SUBMIT BUG FIX === */ 357 | input.ui-button { background: url(images/button_bg.png) 0px 0px repeat-x !important; color: #4f4f4f; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; border: 1px solid #b6b6b6; outline: none; } 358 | input.ui-button:hover { background: url(images/button_bg.png) 0px 0px repeat-x !important; color: #313131; border-color: #9d9d9d; -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 0px 8px rgba(212,212,212,1); box-shadow: 0px 0px 8px rgba(212,212,212,1); } 359 | input.ui-button:active { background: url(images/button_bg.png) 0px bottom repeat-x !important; color: #4f4f4f; border-color: #b6b6b6; } 360 | 361 | /* === IE6 AND IE7 BUTTON WIDTH FIX === */ 362 | .ui-button { *display: inline !important; } 363 | 364 | .ui-state-default .ui-button-text { background: url(images/button_bg.png) 0px 0px repeat-x !important; color: #4f4f4f; border-color: #b6b6b6; } 365 | .ui-state-hover .ui-button-text { background: url(images/button_bg.png) 0px 0px repeat-x !important; color: #313131; border-color: #9d9d9d; -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 0px 8px rgba(212,212,212,1); box-shadow: 0px 0px 8px rgba(212,212,212,1); } 366 | .ui-state-active .ui-button-text { background: url(images/button_bg.png) 0px bottom repeat-x !important; color: #4f4f4f; border-color: #b6b6b6; } 367 | 368 | /*button text element */ 369 | .ui-button .ui-button-text { display: block; line-height: 1.4; font-weight: bold; font-size: 14px; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); } 370 | .ui-button-text-only .ui-button-text { padding: 5px 12px; } 371 | .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: 5px; text-indent: -9999999px; } 372 | .ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: 5px 12px 5px 25px; } 373 | .ui-button-text-icons .ui-button-text { padding-right: 1.8em; } 374 | /* no icon support for input elements, provide padding by default */ 375 | input.ui-button { padding: .4em 1em; } 376 | 377 | /*button icon element(s) */ 378 | .ui-button .ui-icon { border: 0px none; } 379 | .ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; margin-left: 6px; } 380 | .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } 381 | .ui-button-text-icon .ui-icon-primary, .ui-button-text-icons .ui-icon-primary, .ui-button-icons-only .ui-icon-primary { left: .5em; } 382 | .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } 383 | 384 | /*button sets*/ 385 | .ui-buttonset { margin-right: 7px; } 386 | .ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } 387 | .ui-buttonset, .ui-buttonset span { -moz-border-radius: 0px !important; -webkit-border-radius: 0px !important; border-radius: 0px !important; } 388 | .ui-corner-left .ui-button-text { -moz-border-radius-topleft: 4px !important; -webkit-border-top-left-radius: 4px !important; border-top-left-radius: 4px !important; -moz-border-radius-bottomleft: 4px !important; -webkit-border-bottom-left-radius: 4px !important; border-bottom-left-radius: 4px !important; } 389 | .ui-corner-right .ui-button-text { -moz-border-radius-topright: 4px !important; -webkit-border-top-right-radius: 4px !important; border-top-right-radius: 4px !important; -moz-border-radius-bottomright: 4px !important; -webkit-border-bottom-right-radius: 4px !important; border-bottom-right-radius: 4px !important; } 390 | .ui-buttonset .ui-state-active .ui-button-text { cursor: default; background: url(images/button_bg.png) 0px -33px repeat-x !important; color: #1c4257; border-color: #7096ab; -moz-box-shadow: none !important; -webkit-box-shadow: none !important; box-shadow: none !important; } 391 | 392 | /* workarounds */ 393 | button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ 394 | 395 | 396 | 397 | 398 | 399 | /* === Dialog === */ 400 | .ui-dialog { position: absolute; padding: 0; width: 300px; overflow: hidden; background: #FFFFFF; -moz-box-shadow: 0px 5px 8px rgba(0,0,0,0.8); -webkit-box-shadow: 0px 5px 8px rgba(0,0,0,0.8); box-shadow: 0px 5px 8px rgba(0,0,0,0.8); } 401 | .ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; border-width: 0px 0px 1px 0px; border-color: #979797; background: url(images/the_gradient.gif) 0px 0px repeat-x; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } 402 | .ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; font-size: 13px; color: #000000; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); } 403 | .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: 6px; top: 50%; width: 16px; margin: -9px 0 0 0; height: 16px; } 404 | .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; background: url(images/icon_sprite.png) 0px -16px no-repeat; } 405 | .ui-dialog-titlebar .ui-state-hover { -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; border: 0px none; background: transparent; } 406 | .ui-dialog .ui-dialog-titlebar-close.ui-state-hover span { background-position: -16px -16px ; } 407 | .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } 408 | .ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; font-size: 12px; } 409 | .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } 410 | .ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; background: transparent !important; border: 0px none; } 411 | .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } 412 | .ui-draggable .ui-dialog-titlebar { cursor: move; } 413 | 414 | /* === Slider === */ 415 | .ui-slider { position: relative; text-align: left; border: 0px none; cursor: pointer; } 416 | .ui-state-focus .ui-slider-handle { border: 0px none; } 417 | .ui-slider .ui-slider-handle { background: url(images/slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: pointer; } 418 | .ui-slider .ui-state-hover { background-position: 0px 0px !important; } 419 | .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; } 420 | .ui-slider .ui-state-default { border: 0px none; } 421 | 422 | .ui-slider-horizontal { height: 5px; background: url(images/slider_h_bg.gif) 0px 0px repeat-x;} 423 | .ui-slider-horizontal .ui-slider-handle { top: -9px; margin-left: -12px; } 424 | .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; background: url(images/slider_h_bg.gif) 0px -5px repeat-x; } 425 | .ui-slider-horizontal .ui-slider-range-min { left: 0; } 426 | .ui-slider-horizontal .ui-slider-range-max { right: 0; } 427 | 428 | .ui-slider-vertical { width: 5px; height: 100px; background: url(images/slider_v_bg.gif) -5px 0px repeat-y; } 429 | .ui-slider-vertical .ui-slider-handle { /*left: -.3em;*/ margin-left: -.6em; margin-bottom: -.6em; } 430 | .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; background: url(images/slider_v_bg.gif) 0px 0px repeat-y; } 431 | .ui-slider-vertical .ui-slider-range-min { bottom: 0; } 432 | .ui-slider-vertical .ui-slider-range-max { top: 0; } 433 | 434 | /* === Tabs === */ 435 | .ui-tabs { background: #FFFFFF; position: relative; padding: .2em; zoom: 1; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; border: 0px none; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ 436 | .ui-tabs .ui-tabs-nav { border-color: #a8a8a8; border-width: 0px 0px 1px 0px; margin: 0; padding: 0; background: transparent; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } 437 | .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; } 438 | .ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; font-size: 12px; } 439 | .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } 440 | .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } 441 | .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ 442 | .ui-tabs .ui-tabs-panel { display: block; border: 0; padding: 1em 1.4em; background: none; font-size: 12px; border-color: #a8a8a8; border-width: 0px 1px 1px 1px; border-style: solid; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px;} 443 | .ui-tabs .ui-tabs-hide { display: none !important; } 444 | .ui-tabs .ui-tabs-nav li.ui-state-default { background: #cccccc url(images/button_bg.png) 0px 0px repeat-x; border-color: #a8a8a8; } 445 | .ui-tabs .ui-tabs-nav li.ui-state-default a { color: #4f4f4f !important; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); } 446 | .ui-tabs .ui-tabs-nav li.ui-state-active { background: #FFFFFF; } 447 | .ui-tabs-panel .ui-button { border-width: 0px; background: transparent; } 448 | 449 | /* === Datepicker === */ 450 | .ui-datepicker { width: 17em; padding: .2em .2em 0; background: #FFFFFF url(images/datepicker.gif) left top repeat-x; -moz-box-shadow: 0px 5px 10px rgba(0,0,0,0.8); -webkit-box-shadow: 0px 5px 10px rgba(0,0,0,0.8); box-shadow: 0px 5px 10px rgba(0,0,0,0.8); } 451 | .ui-datepicker .ui-datepicker-header { position:relative; padding:2px 0px 6px 0px; background: transparent; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; border: 0px none; } 452 | .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 6px; width: 16px; height: 16px; border: 0px none; cursor: pointer; } 453 | .ui-datepicker .ui-datepicker-prev { left:2px; } 454 | .ui-datepicker .ui-datepicker-next { right:2px; } 455 | .ui-datepicker .ui-datepicker-header .ui-state-hover { background: transparent; border: 0px none; } 456 | .ui-datepicker .ui-datepicker-prev span { background-position: 0px -32px !important; } 457 | .ui-datepicker .ui-datepicker-next span { background-position: -16px -32px !important; } 458 | .ui-datepicker .ui-datepicker-prev-hover span { background-position: 0px -48px !important; } 459 | .ui-datepicker .ui-datepicker-next-hover span { background-position: -16px -48px !important; } 460 | .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; background: url(images/icon_sprite.png) no-repeat; } 461 | .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; font-size: 12px; color: #000000; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); } 462 | .ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } 463 | .ui-datepicker select.ui-datepicker-month-year {width: 100%;} 464 | .ui-datepicker select.ui-datepicker-month, 465 | .ui-datepicker select.ui-datepicker-year { width: 49%;} 466 | .ui-datepicker table {width: 100%; font-size: 10px; border-collapse: collapse; margin: 0 0 .4em; } 467 | .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } 468 | .ui-datepicker td { border: 0; padding: 1px; } 469 | .ui-datepicker td span, .ui-datepicker td a { display: block; padding: 2px 3px 3px; text-align: right; text-decoration: none; } 470 | .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } 471 | .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } 472 | .ui-datepicker-buttonpane button { background: url(images/button_bg.png) 0px 0px repeat-x !important; color: #4f4f4f !important; border-color: #b6b6b6 !important; font-weight: bold !important; font-size: 12px; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); } 473 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } 474 | .ui-datepicker .ui-datepicker-calendar a { background: transparent; border: 0px none; } 475 | .ui-datepicker .ui-datepicker-calendar .ui-state-active { } 476 | .ui-datepicker .ui-datepicker-calendar a.ui-state-hover { color: #1c4257; } 477 | .ui-datepicker .ui-datepicker-current-day .ui-state-default { background: #5f83b9; color: #FFFFFF !important; text-shadow: 0px 1px 1px #234386; font-weight: bold; } 478 | 479 | /* with multiple calendars */ 480 | .ui-datepicker.ui-datepicker-multi { width:auto; } 481 | .ui-datepicker-multi .ui-datepicker-group { float:left; } 482 | .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } 483 | .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } 484 | .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } 485 | .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } 486 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } 487 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } 488 | .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } 489 | .ui-datepicker-row-break { clear:both; width:100%; } 490 | 491 | /* RTL support */ 492 | .ui-datepicker-rtl { direction: rtl; } 493 | .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } 494 | .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } 495 | .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } 496 | .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } 497 | .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } 498 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } 499 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } 500 | .ui-datepicker-rtl .ui-datepicker-group { float:right; } 501 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 502 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } 503 | 504 | /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ 505 | .ui-datepicker-cover { 506 | display: none; /*sorry for IE5*/ 507 | display/**/: block; /*sorry for IE5*/ 508 | position: absolute; /*must have*/ 509 | z-index: -1; /*must have*/ 510 | filter: mask(); /*must have*/ 511 | top: -4px; /*must have*/ 512 | left: -4px; /*must have*/ 513 | width: 200px; /*must have*/ 514 | height: 200px; /*must have*/ 515 | } 516 | 517 | /* === Progressbar === */ 518 | .ui-progressbar { height: 12px; text-align: left; background: url(images/progress_bar.gif) 0px -14px repeat-x; } 519 | .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; background: url(images/progress_bar.gif) 0px 0px repeat-x; } -------------------------------------------------------------------------------- /demo/css/league-gothic/League_Gothic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/league-gothic/League_Gothic-webfont.eot -------------------------------------------------------------------------------- /demo/css/league-gothic/League_Gothic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/league-gothic/League_Gothic-webfont.ttf -------------------------------------------------------------------------------- /demo/css/league-gothic/League_Gothic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachleat/BigText/4649d726278fe4914e3255084ef92ce48cb14bb2/demo/css/league-gothic/League_Gothic-webfont.woff -------------------------------------------------------------------------------- /demo/css/league-gothic/stylesheet-delay.css.php: -------------------------------------------------------------------------------- 1 | where trailing callbacks 46 | // executed later than they should. Reworked a fair amount of internal 47 | // logic as well. 48 | // 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over 49 | // from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the 50 | // no_trailing throttle parameter and debounce functionality. 51 | // 52 | // Topic: Note for non-jQuery users 53 | // 54 | // jQuery isn't actually required for this plugin, because nothing internal 55 | // uses any jQuery methods or properties. jQuery is just used as a namespace 56 | // under which these methods can exist. 57 | // 58 | // Since jQuery isn't actually required for this plugin, if jQuery doesn't exist 59 | // when this plugin is loaded, the method described below will be created in 60 | // the `Cowboy` namespace. Usage will be exactly the same, but instead of 61 | // $.method() or jQuery.method(), you'll need to use Cowboy.method(). 62 | 63 | (function(window,undefined){ 64 | '$:nomunge'; // Used by YUI compressor. 65 | 66 | // Since jQuery really isn't required for this plugin, use `jQuery` as the 67 | // namespace only if it already exists, otherwise use the `Cowboy` namespace, 68 | // creating it if necessary. 69 | var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ), 70 | 71 | // Internal method reference. 72 | jq_throttle; 73 | 74 | // Method: jQuery.throttle 75 | // 76 | // Throttle execution of a function. Especially useful for rate limiting 77 | // execution of handlers on events like resize and scroll. If you want to 78 | // rate-limit execution of a function to a single time, see the 79 | // method. 80 | // 81 | // In this visualization, | is a throttled-function call and X is the actual 82 | // callback execution: 83 | // 84 | // > Throttled with `no_trailing` specified as false or unspecified: 85 | // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| 86 | // > X X X X X X X X X X X X 87 | // > 88 | // > Throttled with `no_trailing` specified as true: 89 | // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| 90 | // > X X X X X X X X X X 91 | // 92 | // Usage: 93 | // 94 | // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback ); 95 | // > 96 | // > jQuery('selector').bind( 'someevent', throttled ); 97 | // > jQuery('selector').unbind( 'someevent', throttled ); 98 | // 99 | // This also works in jQuery 1.4+: 100 | // 101 | // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) ); 102 | // > jQuery('selector').unbind( 'someevent', callback ); 103 | // 104 | // Arguments: 105 | // 106 | // delay - (Number) A zero-or-greater delay in milliseconds. For event 107 | // callbacks, values around 100 or 250 (or even higher) are most useful. 108 | // no_trailing - (Boolean) Optional, defaults to false. If no_trailing is 109 | // true, callback will only execute every `delay` milliseconds while the 110 | // throttled-function is being called. If no_trailing is false or 111 | // unspecified, callback will be executed one final time after the last 112 | // throttled-function call. (After the throttled-function has not been 113 | // called for `delay` milliseconds, the internal counter is reset) 114 | // callback - (Function) A function to be executed after delay milliseconds. 115 | // The `this` context and all arguments are passed through, as-is, to 116 | // `callback` when the throttled-function is executed. 117 | // 118 | // Returns: 119 | // 120 | // (Function) A new, throttled, function. 121 | 122 | $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) { 123 | // After wrapper has stopped being called, this timeout ensures that 124 | // `callback` is executed at the proper times in `throttle` and `end` 125 | // debounce modes. 126 | var timeout_id, 127 | 128 | // Keep track of the last time `callback` was executed. 129 | last_exec = 0; 130 | 131 | // `no_trailing` defaults to falsy. 132 | if ( typeof no_trailing !== 'boolean' ) { 133 | debounce_mode = callback; 134 | callback = no_trailing; 135 | no_trailing = undefined; 136 | } 137 | 138 | // The `wrapper` function encapsulates all of the throttling / debouncing 139 | // functionality and when executed will limit the rate at which `callback` 140 | // is executed. 141 | function wrapper() { 142 | var that = this, 143 | elapsed = +new Date() - last_exec, 144 | args = arguments; 145 | 146 | // Execute `callback` and update the `last_exec` timestamp. 147 | function exec() { 148 | last_exec = +new Date(); 149 | callback.apply( that, args ); 150 | }; 151 | 152 | // If `debounce_mode` is true (at_begin) this is used to clear the flag 153 | // to allow future `callback` executions. 154 | function clear() { 155 | timeout_id = undefined; 156 | }; 157 | 158 | if ( debounce_mode && !timeout_id ) { 159 | // Since `wrapper` is being called for the first time and 160 | // `debounce_mode` is true (at_begin), execute `callback`. 161 | exec(); 162 | } 163 | 164 | // Clear any existing timeout. 165 | timeout_id && clearTimeout( timeout_id ); 166 | 167 | if ( debounce_mode === undefined && elapsed > delay ) { 168 | // In throttle mode, if `delay` time has been exceeded, execute 169 | // `callback`. 170 | exec(); 171 | 172 | } else if ( no_trailing !== true ) { 173 | // In trailing throttle mode, since `delay` time has not been 174 | // exceeded, schedule `callback` to execute `delay` ms after most 175 | // recent execution. 176 | // 177 | // If `debounce_mode` is true (at_begin), schedule `clear` to execute 178 | // after `delay` ms. 179 | // 180 | // If `debounce_mode` is false (at end), schedule `callback` to 181 | // execute after `delay` ms. 182 | timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay ); 183 | } 184 | }; 185 | 186 | // Set the guid of `wrapper` function to the same of original callback, so 187 | // it can be removed in jQuery 1.4+ .unbind or .die by using the original 188 | // callback as a reference. 189 | if ( $.guid ) { 190 | wrapper.guid = callback.guid = callback.guid || $.guid++; 191 | } 192 | 193 | // Return the wrapper function. 194 | return wrapper; 195 | }; 196 | 197 | // Method: jQuery.debounce 198 | // 199 | // Debounce execution of a function. Debouncing, unlike throttling, 200 | // guarantees that a function is only executed a single time, either at the 201 | // very beginning of a series of calls, or at the very end. If you want to 202 | // simply rate-limit execution of a function, see the 203 | // method. 204 | // 205 | // In this visualization, | is a debounced-function call and X is the actual 206 | // callback execution: 207 | // 208 | // > Debounced with `at_begin` specified as false or unspecified: 209 | // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| 210 | // > X X 211 | // > 212 | // > Debounced with `at_begin` specified as true: 213 | // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| 214 | // > X X 215 | // 216 | // Usage: 217 | // 218 | // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback ); 219 | // > 220 | // > jQuery('selector').bind( 'someevent', debounced ); 221 | // > jQuery('selector').unbind( 'someevent', debounced ); 222 | // 223 | // This also works in jQuery 1.4+: 224 | // 225 | // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) ); 226 | // > jQuery('selector').unbind( 'someevent', callback ); 227 | // 228 | // Arguments: 229 | // 230 | // delay - (Number) A zero-or-greater delay in milliseconds. For event 231 | // callbacks, values around 100 or 250 (or even higher) are most useful. 232 | // at_begin - (Boolean) Optional, defaults to false. If at_begin is false or 233 | // unspecified, callback will only be executed `delay` milliseconds after 234 | // the last debounced-function call. If at_begin is true, callback will be 235 | // executed only at the first debounced-function call. (After the 236 | // throttled-function has not been called for `delay` milliseconds, the 237 | // internal counter is reset) 238 | // callback - (Function) A function to be executed after delay milliseconds. 239 | // The `this` context and all arguments are passed through, as-is, to 240 | // `callback` when the debounced-function is executed. 241 | // 242 | // Returns: 243 | // 244 | // (Function) A new, debounced, function. 245 | 246 | $.debounce = function( delay, at_begin, callback ) { 247 | return callback === undefined 248 | ? jq_throttle( delay, at_begin, false ) 249 | : jq_throttle( delay, callback, at_begin !== false ); 250 | }; 251 | 252 | })(this); 253 | -------------------------------------------------------------------------------- /demo/js/jquery.ba-throttle-debounce.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery throttle / debounce - v1.1 - 3/7/2010 3 | * http://benalman.com/projects/jquery-throttle-debounce-plugin/ 4 | * 5 | * Copyright (c) 2010 "Cowboy" Ben Alman 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://benalman.com/about/license/ 8 | */ 9 | (function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); -------------------------------------------------------------------------------- /demo/js/modernizr-1.6.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Modernizr v1.6 3 | * http://www.modernizr.com 4 | * 5 | * Developed by: 6 | * - Faruk Ates http://farukat.es/ 7 | * - Paul Irish http://paulirish.com/ 8 | * 9 | * Copyright (c) 2009-2010 10 | * Dual-licensed under the BSD or MIT licenses. 11 | * http://www.modernizr.com/license/ 12 | */ 13 | 14 | 15 | /* 16 | * Modernizr is a script that detects native CSS3 and HTML5 features 17 | * available in the current UA and provides an object containing all 18 | * features with a true/false value, depending on whether the UA has 19 | * native support for it or not. 20 | * 21 | * Modernizr will also add classes to the element of the page, 22 | * one for each feature it detects. If the UA supports it, a class 23 | * like "cssgradients" will be added. If not, the class name will be 24 | * "no-cssgradients". This allows for simple if-conditionals in your 25 | * CSS, giving you fine control over the look & feel of your website. 26 | * 27 | * @author Faruk Ates 28 | * @author Paul Irish 29 | * @copyright (c) 2009-2010 Faruk Ates. 30 | * @contributor Ben Alman 31 | */ 32 | 33 | window.Modernizr = (function(window,doc,undefined){ 34 | 35 | var version = '1.6', 36 | 37 | ret = {}, 38 | 39 | /** 40 | * !! DEPRECATED !! 41 | * 42 | * enableHTML5 is a private property for advanced use only. If enabled, 43 | * it will make Modernizr.init() run through a brief while() loop in 44 | * which it will create all HTML5 elements in the DOM to allow for 45 | * styling them in Internet Explorer, which does not recognize any 46 | * non-HTML4 elements unless created in the DOM this way. 47 | * 48 | * enableHTML5 is ON by default. 49 | * 50 | * The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be 51 | * replaced in 2.0 in lieu of the modular, configurable nature of 2.0. 52 | */ 53 | enableHTML5 = true, 54 | 55 | 56 | docElement = doc.documentElement, 57 | 58 | /** 59 | * Create our "modernizr" element that we do most feature tests on. 60 | */ 61 | mod = 'modernizr', 62 | m = doc.createElement( mod ), 63 | m_style = m.style, 64 | 65 | /** 66 | * Create the input element for various Web Forms feature tests. 67 | */ 68 | f = doc.createElement( 'input' ), 69 | 70 | smile = ':)', 71 | 72 | tostring = Object.prototype.toString, 73 | 74 | // List of property values to set for css tests. See ticket #21 75 | prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '), 76 | 77 | // Following spec is to expose vendor-specific style properties as: 78 | // elem.style.WebkitBorderRadius 79 | // and the following would be incorrect: 80 | // elem.style.webkitBorderRadius 81 | 82 | // Webkit ghosts their properties in lowercase but Opera & Moz do not. 83 | // Microsoft foregoes prefixes entirely <= IE8, but appears to 84 | // use a lowercase `ms` instead of the correct `Ms` in IE9 85 | 86 | // More here: http://github.com/Modernizr/Modernizr/issues/issue/21 87 | domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 88 | 89 | ns = {'svg': 'http://www.w3.org/2000/svg'}, 90 | 91 | tests = {}, 92 | inputs = {}, 93 | attrs = {}, 94 | 95 | classes = [], 96 | 97 | featurename, // used in testing loop 98 | 99 | 100 | 101 | // todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead 102 | testMediaQuery = function(mq){ 103 | 104 | var st = document.createElement('style'), 105 | div = doc.createElement('div'), 106 | ret; 107 | 108 | st.textContent = mq + '{#modernizr{height:3px}}'; 109 | (doc.head || doc.getElementsByTagName('head')[0]).appendChild(st); 110 | div.id = 'modernizr'; 111 | docElement.appendChild(div); 112 | 113 | ret = div.offsetHeight === 3; 114 | 115 | st.parentNode.removeChild(st); 116 | div.parentNode.removeChild(div); 117 | 118 | return !!ret; 119 | 120 | }, 121 | 122 | 123 | /** 124 | * isEventSupported determines if a given element supports the given event 125 | * function from http://yura.thinkweb2.com/isEventSupported/ 126 | */ 127 | isEventSupported = (function(){ 128 | 129 | var TAGNAMES = { 130 | 'select':'input','change':'input', 131 | 'submit':'form','reset':'form', 132 | 'error':'img','load':'img','abort':'img' 133 | }; 134 | 135 | function isEventSupported(eventName, element) { 136 | 137 | element = element || document.createElement(TAGNAMES[eventName] || 'div'); 138 | eventName = 'on' + eventName; 139 | 140 | // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those 141 | var isSupported = (eventName in element); 142 | 143 | if (!isSupported) { 144 | // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element 145 | if (!element.setAttribute) { 146 | element = document.createElement('div'); 147 | } 148 | if (element.setAttribute && element.removeAttribute) { 149 | element.setAttribute(eventName, ''); 150 | isSupported = typeof element[eventName] == 'function'; 151 | 152 | // If property was created, "remove it" (by setting value to `undefined`) 153 | if (typeof element[eventName] != 'undefined') { 154 | element[eventName] = undefined; 155 | } 156 | element.removeAttribute(eventName); 157 | } 158 | } 159 | 160 | element = null; 161 | return isSupported; 162 | } 163 | return isEventSupported; 164 | })(); 165 | 166 | 167 | // hasOwnProperty shim by kangax needed for Safari 2.0 support 168 | var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty; 169 | if (typeof _hasOwnProperty !== 'undefined' && typeof _hasOwnProperty.call !== 'undefined') { 170 | hasOwnProperty = function (object, property) { 171 | return _hasOwnProperty.call(object, property); 172 | }; 173 | } 174 | else { 175 | hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ 176 | return ((property in object) && typeof object.constructor.prototype[property] === 'undefined'); 177 | }; 178 | } 179 | 180 | /** 181 | * set_css applies given styles to the Modernizr DOM node. 182 | */ 183 | function set_css( str ) { 184 | m_style.cssText = str; 185 | } 186 | 187 | /** 188 | * set_css_all extrapolates all vendor-specific css strings. 189 | */ 190 | function set_css_all( str1, str2 ) { 191 | return set_css(prefixes.join(str1 + ';') + ( str2 || '' )); 192 | } 193 | 194 | /** 195 | * contains returns a boolean for if substr is found within str. 196 | */ 197 | function contains( str, substr ) { 198 | return (''+str).indexOf( substr ) !== -1; 199 | } 200 | 201 | /** 202 | * test_props is a generic CSS / DOM property test; if a browser supports 203 | * a certain property, it won't return undefined for it. 204 | * A supported CSS property returns empty string when its not yet set. 205 | */ 206 | function test_props( props, callback ) { 207 | for ( var i in props ) { 208 | if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], m ) ) ) { 209 | return true; 210 | } 211 | } 212 | } 213 | 214 | /** 215 | * test_props_all tests a list of DOM properties we want to check against. 216 | * We specify literally ALL possible (known and/or likely) properties on 217 | * the element including the non-vendor prefixed one, for forward- 218 | * compatibility. 219 | */ 220 | function test_props_all( prop, callback ) { 221 | 222 | var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1), 223 | props = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' '); 224 | 225 | return !!test_props( props, callback ); 226 | } 227 | 228 | 229 | /** 230 | * Tests 231 | */ 232 | 233 | tests['flexbox'] = function() { 234 | /** 235 | * set_prefixed_value_css sets the property of a specified element 236 | * adding vendor prefixes to the VALUE of the property. 237 | * @param {Element} element 238 | * @param {string} property The property name. This will not be prefixed. 239 | * @param {string} value The value of the property. This WILL be prefixed. 240 | * @param {string=} extra Additional CSS to append unmodified to the end of 241 | * the CSS string. 242 | */ 243 | function set_prefixed_value_css(element, property, value, extra) { 244 | property += ':'; 245 | element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || ''); 246 | } 247 | 248 | /** 249 | * set_prefixed_property_css sets the property of a specified element 250 | * adding vendor prefixes to the NAME of the property. 251 | * @param {Element} element 252 | * @param {string} property The property name. This WILL be prefixed. 253 | * @param {string} value The value of the property. This will not be prefixed. 254 | * @param {string=} extra Additional CSS to append unmodified to the end of 255 | * the CSS string. 256 | */ 257 | function set_prefixed_property_css(element, property, value, extra) { 258 | element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || ''); 259 | } 260 | 261 | var c = doc.createElement('div'), 262 | elem = doc.createElement('div'); 263 | 264 | set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;'); 265 | set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;'); 266 | 267 | c.appendChild(elem); 268 | docElement.appendChild(c); 269 | 270 | var ret = elem.offsetWidth === 42; 271 | 272 | c.removeChild(elem); 273 | docElement.removeChild(c); 274 | 275 | return ret; 276 | }; 277 | 278 | // On the S60 and BB Storm, getContext exists, but always returns undefined 279 | // http://github.com/Modernizr/Modernizr/issues/issue/97/ 280 | 281 | tests['canvas'] = function() { 282 | var elem = doc.createElement( 'canvas' ); 283 | return !!(elem.getContext && elem.getContext('2d')); 284 | }; 285 | 286 | tests['canvastext'] = function() { 287 | return !!(ret['canvas'] && typeof doc.createElement( 'canvas' ).getContext('2d').fillText == 'function'); 288 | }; 289 | 290 | 291 | tests['webgl'] = function(){ 292 | 293 | var elem = doc.createElement( 'canvas' ); 294 | 295 | try { 296 | if (elem.getContext('webgl')){ return true; } 297 | } catch(e){ } 298 | 299 | try { 300 | if (elem.getContext('experimental-webgl')){ return true; } 301 | } catch(e){ } 302 | 303 | return false; 304 | }; 305 | 306 | /* 307 | * The Modernizr.touch test only indicates if the browser supports 308 | * touch events, which does not necessarily reflect a touchscreen 309 | * device, as evidenced by tablets running Windows 7 or, alas, 310 | * the Palm Pre / WebOS (touch) phones. 311 | * 312 | * Additionally, Chrome (desktop) used to lie about its support on this, 313 | * but that has since been rectified: http://crbug.com/36415 314 | * 315 | * We also test for Firefox 4 Multitouch Support. 316 | * 317 | * For more info, see: http://modernizr.github.com/Modernizr/touch.html 318 | */ 319 | 320 | tests['touch'] = function() { 321 | 322 | return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)'); 323 | 324 | }; 325 | 326 | 327 | /** 328 | * geolocation tests for the new Geolocation API specification. 329 | * This test is a standards compliant-only test; for more complete 330 | * testing, including a Google Gears fallback, please see: 331 | * http://code.google.com/p/geo-location-javascript/ 332 | * or view a fallback solution using google's geo API: 333 | * http://gist.github.com/366184 334 | */ 335 | tests['geolocation'] = function() { 336 | return !!navigator.geolocation; 337 | }; 338 | 339 | // Per 1.6: 340 | // This used to be Modernizr.crosswindowmessaging but the longer 341 | // name has been deprecated in favor of a shorter and property-matching one. 342 | // The old API is still available in 1.6, but as of 2.0 will throw a warning, 343 | // and in the first release thereafter disappear entirely. 344 | tests['postmessage'] = function() { 345 | return !!window.postMessage; 346 | }; 347 | 348 | // Web SQL database detection is tricky: 349 | 350 | // In chrome incognito mode, openDatabase is truthy, but using it will 351 | // throw an exception: http://crbug.com/42380 352 | // We can create a dummy database, but there is no way to delete it afterwards. 353 | 354 | // Meanwhile, Safari users can get prompted on any database creation. 355 | // If they do, any page with Modernizr will give them a prompt: 356 | // http://github.com/Modernizr/Modernizr/issues/closed#issue/113 357 | 358 | // We have chosen to allow the Chrome incognito false positive, so that Modernizr 359 | // doesn't litter the web with these test databases. As a developer, you'll have 360 | // to account for this gotcha yourself. 361 | tests['websqldatabase'] = function() { 362 | var result = !!window.openDatabase; 363 | /* 364 | if (result){ 365 | try { 366 | result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4); 367 | } catch(e) { 368 | } 369 | } 370 | */ 371 | return result; 372 | }; 373 | 374 | // Vendors have inconsistent prefixing with the experimental Indexed DB: 375 | // - Firefox is shipping indexedDB in FF4 as moz_indexedDB 376 | // - Webkit's implementation is accessible through webkitIndexedDB 377 | // We test both styles. 378 | tests['indexedDB'] = function(){ 379 | for (var i = -1, len = domPrefixes.length; ++i < len; ){ 380 | var prefix = domPrefixes[i].toLowerCase(); 381 | if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){ 382 | return true; 383 | } 384 | } 385 | return false; 386 | }; 387 | 388 | // documentMode logic from YUI to filter out IE8 Compat Mode 389 | // which false positives. 390 | tests['hashchange'] = function() { 391 | return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 ); 392 | }; 393 | 394 | // Per 1.6: 395 | // This used to be Modernizr.historymanagement but the longer 396 | // name has been deprecated in favor of a shorter and property-matching one. 397 | // The old API is still available in 1.6, but as of 2.0 will throw a warning, 398 | // and in the first release thereafter disappear entirely. 399 | tests['history'] = function() { 400 | return !!(window.history && history.pushState); 401 | }; 402 | 403 | tests['draganddrop'] = function() { 404 | return isEventSupported('drag') && 405 | isEventSupported('dragstart') && 406 | isEventSupported('dragenter') && 407 | isEventSupported('dragover') && 408 | isEventSupported('dragleave') && 409 | isEventSupported('dragend') && 410 | isEventSupported('drop'); 411 | }; 412 | 413 | tests['websockets'] = function(){ 414 | return ('WebSocket' in window); 415 | }; 416 | 417 | 418 | // http://css-tricks.com/rgba-browser-support/ 419 | tests['rgba'] = function() { 420 | // Set an rgba() color and check the returned value 421 | 422 | set_css( 'background-color:rgba(150,255,150,.5)' ); 423 | 424 | return contains( m_style.backgroundColor, 'rgba' ); 425 | }; 426 | 427 | tests['hsla'] = function() { 428 | // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally, 429 | // except IE9 who retains it as hsla 430 | 431 | set_css('background-color:hsla(120,40%,100%,.5)' ); 432 | 433 | return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' ); 434 | }; 435 | 436 | tests['multiplebgs'] = function() { 437 | // Setting multiple images AND a color on the background shorthand property 438 | // and then querying the style.background property value for the number of 439 | // occurrences of "url(" is a reliable method for detecting ACTUAL support for this! 440 | 441 | set_css( 'background:url(//:),url(//:),red url(//:)' ); 442 | 443 | // If the UA supports multiple backgrounds, there should be three occurrences 444 | // of the string "url(" in the return value for elem_style.background 445 | 446 | return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background); 447 | }; 448 | 449 | 450 | // In testing support for a given CSS property, it's legit to test: 451 | // elem.style[styleName] !== undefined 452 | // If the property is supported it will return an empty string, 453 | // if unsupported it will return undefined. 454 | // We'll take advantage of this quick test and skip setting a style 455 | // on our modernizr element, but instead just testing undefined vs 456 | // empty string. 457 | // The legacy set_css_all calls will remain in the source 458 | // (however, commented) for clarity, yet functionally they are 459 | // no longer needed. 460 | 461 | 462 | tests['backgroundsize'] = function() { 463 | return test_props_all( 'backgroundSize' ); 464 | }; 465 | 466 | tests['borderimage'] = function() { 467 | // set_css_all( 'border-image:url(m.png) 1 1 stretch' ); 468 | return test_props_all( 'borderImage' ); 469 | }; 470 | 471 | 472 | // Super comprehensive table about all the unique implementations of 473 | // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance 474 | 475 | tests['borderradius'] = function() { 476 | // set_css_all( 'border-radius:10px' ); 477 | return test_props_all( 'borderRadius', '', function( prop ) { 478 | return contains( prop, 'orderRadius' ); 479 | }); 480 | }; 481 | 482 | 483 | tests['boxshadow'] = function() { 484 | // set_css_all( 'box-shadow:#000 1px 1px 3px' ); 485 | return test_props_all( 'boxShadow' ); 486 | }; 487 | 488 | // Note: FF3.0 will false positive on this test 489 | tests['textshadow'] = function(){ 490 | return doc.createElement('div').style.textShadow === ''; 491 | }; 492 | 493 | 494 | tests['opacity'] = function() { 495 | // Browsers that actually have CSS Opacity implemented have done so 496 | // according to spec, which means their return values are within the 497 | // range of [0.0,1.0] - including the leading zero. 498 | 499 | set_css_all( 'opacity:.5' ); 500 | 501 | return contains( m_style.opacity, '0.5' ); 502 | }; 503 | 504 | 505 | tests['cssanimations'] = function() { 506 | // set_css_all( 'animation:"animate" 2s ease 2', 'position:relative' ); 507 | return test_props_all( 'animationName' ); 508 | }; 509 | 510 | 511 | tests['csscolumns'] = function() { 512 | // set_css_all( 'column-count:3' ); 513 | return test_props_all( 'columnCount' ); 514 | }; 515 | 516 | 517 | tests['cssgradients'] = function() { 518 | /** 519 | * For CSS Gradients syntax, please see: 520 | * http://webkit.org/blog/175/introducing-css-gradients/ 521 | * https://developer.mozilla.org/en/CSS/-moz-linear-gradient 522 | * https://developer.mozilla.org/en/CSS/-moz-radial-gradient 523 | * http://dev.w3.org/csswg/css3-images/#gradients- 524 | */ 525 | 526 | var str1 = 'background-image:', 527 | str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', 528 | str3 = 'linear-gradient(left top,#9f9, white);'; 529 | 530 | set_css( 531 | (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length) 532 | ); 533 | 534 | return contains( m_style.backgroundImage, 'gradient' ); 535 | }; 536 | 537 | 538 | tests['cssreflections'] = function() { 539 | // set_css_all( 'box-reflect:right 1px' ); 540 | return test_props_all( 'boxReflect' ); 541 | }; 542 | 543 | 544 | tests['csstransforms'] = function() { 545 | // set_css_all( 'transform:rotate(3deg)' ); 546 | return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]); 547 | }; 548 | 549 | 550 | tests['csstransforms3d'] = function() { 551 | // set_css_all( 'perspective:500' ); 552 | 553 | var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]); 554 | 555 | // Webkit’s 3D transforms are passed off to the browser's own graphics renderer. 556 | // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome (yet?). 557 | // As a result, Webkit typically recognizes the syntax but will sometimes throw a false 558 | // positive, thus we must do a more thorough check: 559 | if (ret){ 560 | 561 | // Webkit allows this media query to succeed only if the feature is enabled. 562 | // "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }" 563 | ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)'); 564 | } 565 | return ret; 566 | }; 567 | 568 | 569 | tests['csstransitions'] = function() { 570 | // set_css_all( 'transition:all .5s linear' ); 571 | return test_props_all( 'transitionProperty' ); 572 | }; 573 | 574 | 575 | // @font-face detection routine by Diego Perini 576 | // http://javascript.nwbox.com/CSSSupport/ 577 | tests['fontface'] = function(){ 578 | 579 | var 580 | sheet, 581 | head = doc.head || doc.getElementsByTagName('head')[0] || docElement, 582 | style = doc.createElement("style"), 583 | impl = doc.implementation || { hasFeature: function() { return false; } }; 584 | 585 | style.type = 'text/css'; 586 | head.insertBefore(style, head.firstChild); 587 | sheet = style.sheet || style.styleSheet; 588 | 589 | // removing it crashes IE browsers 590 | //head.removeChild(style); 591 | 592 | var supportAtRule = impl.hasFeature('CSS2', '') ? 593 | function(rule) { 594 | if (!(sheet && rule)) return false; 595 | var result = false; 596 | try { 597 | sheet.insertRule(rule, 0); 598 | result = !(/unknown/i).test(sheet.cssRules[0].cssText); 599 | sheet.deleteRule(sheet.cssRules.length - 1); 600 | } catch(e) { } 601 | return result; 602 | } : 603 | function(rule) { 604 | if (!(sheet && rule)) return false; 605 | sheet.cssText = rule; 606 | 607 | return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) && 608 | sheet.cssText 609 | .replace(/\r+|\n+/g, '') 610 | .indexOf(rule.split(' ')[0]) === 0; 611 | }; 612 | 613 | 614 | // DEPRECATED - allow for a callback 615 | ret._fontfaceready = function(fn){ 616 | fn(ret.fontface); 617 | }; 618 | 619 | return supportAtRule('@font-face { font-family: "font"; src: "font.ttf"; }'); 620 | 621 | }; 622 | 623 | 624 | // These tests evaluate support of the video/audio elements, as well as 625 | // testing what types of content they support. 626 | // 627 | // We're using the Boolean constructor here, so that we can extend the value 628 | // e.g. Modernizr.video // true 629 | // Modernizr.video.ogg // 'probably' 630 | // 631 | // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 632 | // thx to NielsLeenheer and zcorpan 633 | 634 | // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string. 635 | // Modernizr does not normalize for that. 636 | 637 | tests['video'] = function() { 638 | var elem = doc.createElement('video'), 639 | bool = !!elem.canPlayType; 640 | 641 | if (bool){ 642 | bool = new Boolean(bool); 643 | bool.ogg = elem.canPlayType('video/ogg; codecs="theora"'); 644 | 645 | // Workaround required for IE9, which doesn't report video support without audio codec specified. 646 | // bug 599718 @ msft connect 647 | var h264 = 'video/mp4; codecs="avc1.42E01E'; 648 | bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"'); 649 | 650 | bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"'); 651 | } 652 | return bool; 653 | }; 654 | 655 | tests['audio'] = function() { 656 | var elem = doc.createElement('audio'), 657 | bool = !!elem.canPlayType; 658 | 659 | if (bool){ 660 | bool = new Boolean(bool); 661 | bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"'); 662 | bool.mp3 = elem.canPlayType('audio/mpeg;'); 663 | 664 | // Mimetypes accepted: 665 | // https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements 666 | // http://bit.ly/iphoneoscodecs 667 | bool.wav = elem.canPlayType('audio/wav; codecs="1"'); 668 | bool.m4a = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;'); 669 | } 670 | return bool; 671 | }; 672 | 673 | 674 | // Both localStorage and sessionStorage are 675 | // tested via the `in` operator because otherwise Firefox will 676 | // throw an error: https://bugzilla.mozilla.org/show_bug.cgi?id=365772 677 | // if cookies are disabled 678 | 679 | // They require try/catch because of possible firefox configuration: 680 | // http://github.com/Modernizr/Modernizr/issues#issue/92 681 | 682 | // FWIW miller device resolves to [object Storage] in all supporting browsers 683 | // except for IE who does [object Object] 684 | 685 | // IE8 Compat mode supports these features completely: 686 | // http://www.quirksmode.org/dom/html5.html 687 | 688 | tests['localstorage'] = function() { 689 | try { 690 | return ('localStorage' in window) && window.localStorage !== null; 691 | } catch(e) { 692 | return false; 693 | } 694 | }; 695 | 696 | tests['sessionstorage'] = function() { 697 | try { 698 | return ('sessionStorage' in window) && window.sessionStorage !== null; 699 | } catch(e){ 700 | return false; 701 | } 702 | }; 703 | 704 | 705 | tests['webWorkers'] = function () { 706 | return !!window.Worker; 707 | }; 708 | 709 | 710 | tests['applicationcache'] = function() { 711 | return !!window.applicationCache; 712 | }; 713 | 714 | 715 | // Thanks to Erik Dahlstrom 716 | tests['svg'] = function(){ 717 | return !!doc.createElementNS && !!doc.createElementNS(ns.svg, "svg").createSVGRect; 718 | }; 719 | 720 | tests['inlinesvg'] = function() { 721 | var div = document.createElement('div'); 722 | div.innerHTML = ''; 723 | return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; 724 | }; 725 | 726 | // Thanks to F1lt3r and lucideer 727 | // http://github.com/Modernizr/Modernizr/issues#issue/35 728 | tests['smil'] = function(){ 729 | return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'animate'))); 730 | }; 731 | 732 | tests['svgclippaths'] = function(){ 733 | // Possibly returns a false positive in Safari 3.2? 734 | return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'clipPath'))); 735 | }; 736 | 737 | 738 | // input features and input types go directly onto the ret object, bypassing the tests loop. 739 | // Hold this guy to execute in a moment. 740 | function webforms(){ 741 | 742 | // Run through HTML5's new input attributes to see if the UA understands any. 743 | // We're using f which is the element created early on 744 | // Mike Taylr has created a comprehensive resource for testing these attributes 745 | // when applied to all input types: 746 | // http://miketaylr.com/code/input-type-attr.html 747 | // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 748 | ret['input'] = (function(props) { 749 | for (var i = 0,len=props.length;i element, if it exists: 885 | docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js'; 886 | 887 | // Add the new classes to the element. 888 | docElement.className += ' ' + classes.join( ' ' ); 889 | 890 | return ret; 891 | 892 | })(this,this.document); 893 | -------------------------------------------------------------------------------- /demo/js/modernizr-1.6.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Modernizr v1.6 3 | * http://www.modernizr.com 4 | * 5 | * Developed by: 6 | * - Faruk Ates http://farukat.es/ 7 | * - Paul Irish http://paulirish.com/ 8 | * 9 | * Copyright (c) 2009-2010 10 | * Dual-licensed under the BSD or MIT licenses. 11 | * http://www.modernizr.com/license/ 12 | */ 13 | window.Modernizr=function(i,e,u){function s(a,b){return(""+a).indexOf(b)!==-1}function D(a,b){for(var c in a)if(j[a[c]]!==u&&(!b||b(a[c],E)))return true}function n(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1);c=(a+" "+F.join(c+" ")+c).split(" ");return!!D(c,b)}function S(){f.input=function(a){for(var b=0,c=a.length;b7)};d.history=function(){return!!(i.history&&history.pushState)};d.draganddrop=function(){return o("drag")&& 20 | o("dragstart")&&o("dragenter")&&o("dragover")&&o("dragleave")&&o("dragend")&&o("drop")};d.websockets=function(){return"WebSocket"in i};d.rgba=function(){j.cssText="background-color:rgba(150,255,150,.5)";return s(j.backgroundColor,"rgba")};d.hsla=function(){j.cssText="background-color:hsla(120,40%,100%,.5)";return s(j.backgroundColor,"rgba")||s(j.backgroundColor,"hsla")};d.multiplebgs=function(){j.cssText="background:url(//:),url(//:),red url(//:)";return/(url\s*\(.*?){3}/.test(j.background)};d.backgroundsize= 21 | function(){return n("backgroundSize")};d.borderimage=function(){return n("borderImage")};d.borderradius=function(){return n("borderRadius","",function(a){return s(a,"orderRadius")})};d.boxshadow=function(){return n("boxShadow")};d.textshadow=function(){return e.createElement("div").style.textShadow===""};d.opacity=function(){var a=q.join("opacity:.5;")+"";j.cssText=a;return s(j.opacity,"0.5")};d.cssanimations=function(){return n("animationName")};d.csscolumns=function(){return n("columnCount")};d.cssgradients= 22 | function(){var a=("background-image:"+q.join("gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:")+q.join("linear-gradient(left top,#9f9, white);background-image:")).slice(0,-17);j.cssText=a;return s(j.backgroundImage,"gradient")};d.cssreflections=function(){return n("boxReflect")};d.csstransforms=function(){return!!D(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])};d.csstransforms3d=function(){var a=!!D(["perspectiveProperty","WebkitPerspective", 23 | "MozPerspective","OPerspective","msPerspective"]);if(a)a=Q("@media ("+q.join("transform-3d),(")+"modernizr)");return a};d.csstransitions=function(){return n("transitionProperty")};d.fontface=function(){var a,b=e.head||e.getElementsByTagName("head")[0]||l,c=e.createElement("style"),k=e.implementation||{hasFeature:function(){return false}};c.type="text/css";b.insertBefore(c,b.firstChild);a=c.sheet||c.styleSheet;b=k.hasFeature("CSS2","")?function(g){if(!(a&&g))return false;var r=false;try{a.insertRule(g, 24 | 0);r=!/unknown/i.test(a.cssRules[0].cssText);a.deleteRule(a.cssRules.length-1)}catch(x){}return r}:function(g){if(!(a&&g))return false;a.cssText=g;return a.cssText.length!==0&&!/unknown/i.test(a.cssText)&&a.cssText.replace(/\r+|\n+/g,"").indexOf(g.split(" ")[0])===0};f._fontfaceready=function(g){g(f.fontface)};return b('@font-face { font-family: "font"; src: "font.ttf"; }')};d.video=function(){var a=e.createElement("video"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('video/ogg; codecs="theora"'); 25 | b.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"')||a.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');b.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return b};d.audio=function(){var a=e.createElement("audio"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('audio/ogg; codecs="vorbis"');b.mp3=a.canPlayType("audio/mpeg;");b.wav=a.canPlayType('audio/wav; codecs="1"');b.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}return b};d.localstorage=function(){try{return"localStorage"in 26 | i&&i.localStorage!==null}catch(a){return false}};d.sessionstorage=function(){try{return"sessionStorage"in i&&i.sessionStorage!==null}catch(a){return false}};d.webWorkers=function(){return!!i.Worker};d.applicationcache=function(){return!!i.applicationCache};d.svg=function(){return!!e.createElementNS&&!!e.createElementNS(v.svg,"svg").createSVGRect};d.inlinesvg=function(){var a=document.createElement("div");a.innerHTML="";return(a.firstChild&&a.firstChild.namespaceURI)==v.svg};d.smil=function(){return!!e.createElementNS&& 27 | /SVG/.test(O.call(e.createElementNS(v.svg,"animate")))};d.svgclippaths=function(){return!!e.createElementNS&&/SVG/.test(O.call(e.createElementNS(v.svg,"clipPath")))};for(var H in d)if(R(d,H)){w=H.toLowerCase();f[w]=d[H]();P.push((f[w]?"":"no-")+w)}f.input||S();f.crosswindowmessaging=f.postmessage;f.historymanagement=f.history;f.addTest=function(a,b){a=a.toLowerCase();if(!f[a]){b=!!b();l.className+=" "+(b?"":"no-")+a;f[a]=b;return f}};j.cssText="";E=h=null;i.attachEvent&&function(){var a=e.createElement("div"); 28 | a.innerHTML="";return a.childNodes.length!==1}()&&function(a,b){function c(p){for(var m=-1;++m 2 | 3 | 4 | 5 | BigText on a List 6 | 13 | 14 | 15 |
16 |
This is
17 |
a longer second line
18 |
and an exempt line.
19 |
20 | 21 | 22 | 23 | 24 | 35 | 36 | -------------------------------------------------------------------------------- /demo/simpleDemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BigText on a List 6 | 27 | 34 | 35 | 36 | 43 | 44 | 45 |
    46 |
  1. Merry Christmas
  2. 47 |
  3. Soulwax
  4. 48 |
  5. The Grapevine Game
  6. 49 |
  7. Tick Talk
  8. 50 |
51 | 52 |
    53 |
  1. First
  2. 54 |
  3. Second
  4. 55 |
  5. This is the Third
  6. 56 |
  7. Fourth
  8. 57 |
58 | 59 |
    60 |
  1. This is a really long sentence that will result in a tiny font size. This is a really long sentence that will result in a tiny font size.
  2. 61 |
  3. This is a shorter line.
  4. 62 |
63 | 64 |
  1. This is
  2. a longer second line
  3. An even longer third line.
65 | 66 | -------------------------------------------------------------------------------- /demo/simpleDemoDiv.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BigText on a List 6 | 12 | 13 | 14 |
15 |
This is
16 |
a longer second line
17 |
and an exempt line.
18 |
19 | 20 |
This is a single line.
21 | 22 | 23 | 24 | 31 | 32 | -------------------------------------------------------------------------------- /demo/testTwoLines.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BigText 6 | 7 | 8 |
This is
a longer second line
9 |
This is
a longer second line
10 | 11 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /demo/wizard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BigText Wizard 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
EDIT ME
15 |
16 |
17 |
18 |
19 |
20 | 26 |
27 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |

52 | 53 | Darn. Your browser does not support 3d transforms, and the 3d stuff 54 | here won't work for you. If you want to check it out, try Safari or a dev build of Chrome. 55 |

56 |
57 |
58 | 59 | 60 | 61 | 62 |

Angle: 0 degrees

63 |
64 | 65 | 66 |
67 |

Translate

68 |
69 | 70 |
71 |
72 | 73 |
74 |
75 | 76 |
77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 |

Created by @zachleat.

85 |

Back to the blog post.

86 |
87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /dist/bigtext.js: -------------------------------------------------------------------------------- 1 | /*! BigText - v1.0.1 - 2017-10-02 2 | * https://github.com/zachleat/bigtext 3 | * Copyright (c) 2017 Zach Leatherman (@zachleat) 4 | * MIT License */ 5 | 6 | (function(window, $) { 7 | "use strict"; 8 | 9 | var counter = 0, 10 | $headCache = $('head'), 11 | oldBigText = window.BigText, 12 | oldjQueryMethod = $.fn.bigtext, 13 | BigText = { 14 | DEBUG_MODE: false, 15 | DEFAULT_MIN_FONT_SIZE_PX: null, 16 | DEFAULT_MAX_FONT_SIZE_PX: 528, 17 | GLOBAL_STYLE_ID: 'bigtext-style', 18 | STYLE_ID: 'bigtext-id', 19 | LINE_CLASS_PREFIX: 'bigtext-line', 20 | EXEMPT_CLASS: 'bigtext-exempt', 21 | noConflict: function(restore) 22 | { 23 | if(restore) { 24 | $.fn.bigtext = oldjQueryMethod; 25 | window.BigText = oldBigText; 26 | } 27 | return BigText; 28 | }, 29 | supports: { 30 | wholeNumberFontSizeOnly: (function() { 31 | if( !( 'getComputedStyle' in window ) ) { 32 | return true; 33 | } 34 | var test = $('
').css({ 35 | position: 'absolute', 36 | 'font-size': '14.1px' 37 | }).insertBefore( $('script').eq(0) ), 38 | computedStyle = window.getComputedStyle( test[0], null ); 39 | 40 | var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 41 | test.remove(); 42 | return ret; 43 | })() 44 | }, 45 | init: function() { 46 | if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 47 | $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 48 | '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 49 | } 50 | }, 51 | bindResize: function(eventName, resizeFunction) { 52 | var timeoutId; 53 | $(window).off(eventName).on(eventName, function() { 54 | if( timeoutId ) { 55 | clearTimeout( timeoutId ); 56 | } 57 | timeoutId = setTimeout( resizeFunction, 100 ); 58 | }); 59 | }, 60 | getStyleId: function(id) 61 | { 62 | return BigText.STYLE_ID + '-' + id; 63 | }, 64 | generateStyleTag: function(id, css) 65 | { 66 | return $('').attr('id', id); 67 | }, 68 | clearCss: function(id) 69 | { 70 | var styleId = BigText.getStyleId(id); 71 | $('#' + styleId).remove(); 72 | }, 73 | generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 74 | { 75 | var css = []; 76 | 77 | BigText.clearCss(id); 78 | 79 | for(var j=0, k=linesFontSizes.length; j= maxWidth) { 144 | // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size)); 145 | $line.css(property, ''); 146 | 147 | if(width === maxWidth) { 148 | return { 149 | match: 'exact', 150 | size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 151 | }; 152 | } 153 | 154 | // Since this is an estimate, we calculate how far over the width we went with the new value. 155 | // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 156 | // Otherwise, we revert to the underestimate. 157 | var under = maxWidth - previousWidth, 158 | over = width - maxWidth; 159 | 160 | return { 161 | match: 'estimate', 162 | size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 163 | }; 164 | } 165 | 166 | return width; 167 | }, 168 | calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize) 169 | { 170 | var $c = $t.clone(true) 171 | .addClass('bigtext-cloned') 172 | .css({ 173 | fontFamily: $t.css('font-family'), 174 | textTransform: $t.css('text-transform'), 175 | wordSpacing: $t.css('word-spacing'), 176 | letterSpacing: $t.css('letter-spacing'), 177 | position: 'absolute', 178 | left: BigText.DEBUG_MODE ? 0 : -9999, 179 | top: BigText.DEBUG_MODE ? 0 : -9999 180 | }) 181 | .appendTo(document.body); 182 | 183 | // font-size isn't the only thing we can modify, we can also mess with: 184 | // word-spacing and letter-spacing. WebKit does not respect subpixel 185 | // letter-spacing, word-spacing, or font-size. 186 | // TODO try -webkit-transform: scale() as a workaround. 187 | var fontSizes = [], 188 | wordSpacings = [], 189 | minFontSizes = [], 190 | ratios = []; 191 | 192 | $children.css('float', 'left').each(function() { 193 | var $line = $(this), 194 | // TODO replace 8, 4 with a proportional size to the calculated font-size. 195 | intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 196 | lineMax, 197 | newFontSize; 198 | 199 | if($line.hasClass(BigText.EXEMPT_CLASS)) { 200 | fontSizes.push(null); 201 | ratios.push(null); 202 | minFontSizes.push(false); 203 | return; 204 | } 205 | 206 | // TODO we can cache this ratio? 207 | var autoGuessSubtraction = 32, // font size in px 208 | currentFontSize = parseFloat($line.css('font-size')), 209 | ratio = ( $line.width() / currentFontSize ).toFixed(6); 210 | 211 | newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 212 | 213 | outer: for(var m=0, n=intervals.length; m maxFontSize) { 216 | newFontSize = maxFontSize; 217 | break outer; 218 | } 219 | 220 | lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 221 | if(typeof lineMax !== 'number') { 222 | newFontSize = lineMax.size; 223 | 224 | if(lineMax.match === 'exact') { 225 | break outer; 226 | } 227 | break inner; 228 | } 229 | } 230 | } 231 | 232 | ratios.push(maxWidth / newFontSize); 233 | 234 | if(newFontSize > maxFontSize) { 235 | fontSizes.push(maxFontSize); 236 | minFontSizes.push(false); 237 | } else if(!!minFontSize && newFontSize < minFontSize) { 238 | fontSizes.push(minFontSize); 239 | minFontSizes.push(true); 240 | } else { 241 | fontSizes.push(newFontSize); 242 | minFontSizes.push(false); 243 | } 244 | }).each(function(lineNumber) { 245 | var $line = $(this), 246 | wordSpacing = 0, 247 | interval = 1, 248 | maxWordSpacing; 249 | 250 | if($line.hasClass(BigText.EXEMPT_CLASS)) { 251 | wordSpacings.push(null); 252 | return; 253 | } 254 | 255 | // must re-use font-size, even though it was removed above. 256 | $line.css('font-size', fontSizes[lineNumber] + 'px'); 257 | 258 | for(var m=1, n=3; m', 15 | all[0] 16 | ) { 17 | continue; 18 | } 19 | 20 | return v > 4 ? v : undef; 21 | }()); 22 | 23 | // Be a little bit more forgiving on IE8 and Travis-CI/Ubuntu + PhantomJS 24 | if( ie && ie <= 8 || 25 | ua.indexOf( 'PhantomJS' ) > -1 && ua.indexOf( 'Linux' ) > -1 ) { 26 | 27 | BigTextTest.tolerance = 14; 28 | } else { 29 | BigTextTest.tolerance = 10; 30 | } 31 | 32 | // If the lines of text are blocks, testing their width will tell us nothing. 33 | BigTextTest.init = function() 34 | { 35 | return this.css('float', 'left'); 36 | }; 37 | 38 | BigTextTest.linesTest = function(assert, selector, expectedWidth, options) 39 | { 40 | options = $.extend( options, {} ); 41 | 42 | var tolerance = BigTextTest.tolerance, 43 | minWidth = expectedWidth - tolerance, 44 | maxWidth = expectedWidth + tolerance, 45 | $test = $(selector), 46 | $lines = options.childSelector ? $test.find( options.childSelector ) : $test.children(), 47 | startingFontSize = parseInt($lines.eq(0).css('font-size'), 10); 48 | 49 | BigTextTest.init.call($lines); 50 | 51 | $lines.each(function(j) 52 | { 53 | var width = $(this).width(); 54 | assert.ok(!(( minWidth < width ) && ( width < maxWidth )), 'Pretest: Line ' + j + ' should not be max width (' + minWidth + ' < ' + width + ' < ' + maxWidth + ', font-size: ' + $(this).css('font-size') + ')'); 55 | }); 56 | 57 | $test.bigtext(options); 58 | 59 | assert.ok('Class added.', $test.is('.bigtext')); 60 | 61 | $lines.each(function(j) 62 | { 63 | var $t = $(this), 64 | width = $t.width(), 65 | height = $t.height(), 66 | fontSize = parseFloat($t.css('font-size')), 67 | $heightElement = $('
A
').css({ 68 | 'font-size': fontSize, 69 | position: 'absolute' 70 | }).appendTo(document.body), 71 | expectedHeight = $heightElement.height(), 72 | minHeight = expectedHeight - tolerance, 73 | maxHeight = expectedHeight + tolerance; 74 | 75 | assert.ok('Line ' + j + ' class added.', $t.is('.bigtext-line' + j)); 76 | if($t.hasClass(BigText.EXEMPT_CLASS)) { 77 | // must be added to document to get font-size 78 | var defaultDocumentFontSize = parseInt($('
').appendTo(document.body).css('font-size'), 10); 79 | assert.equal(defaultDocumentFontSize, fontSize, 'Line ' + j + ' Font size must be unchanged'); 80 | } else { 81 | assert.ok(fontSize > startingFontSize, 'Line ' + j + ' Font size must be larger than the starting pixel size'); 82 | assert.ok(minWidth < width && width < maxWidth, 'Line ' + j + ' width should be about ' + expectedWidth + 'px (' + width + ')'); 83 | assert.ok(minHeight < height && height < maxHeight, 'Line ' + j + ' height should be about ' + expectedHeight + 'px (' + minHeight + ' < ' + height + ' < ' + maxHeight + ')'); 84 | } 85 | 86 | $heightElement.remove(); 87 | }); 88 | }; 89 | 90 | QUnit.test('testExists', function( assert ) 91 | { 92 | assert.ok(!!BigText); 93 | assert.ok(!!$.fn.bigtext); 94 | }); 95 | 96 | QUnit.test('testStyleInjection', function( assert ) 97 | { 98 | $('#qunit-fixture').html('
This is a simple test.
'); 99 | $('#test').bigtext(); 100 | 101 | assert.equal($('#' + BigText.getStyleId('test')).length, 1, 'Test to make sure the style tag was inserted.'); 102 | }); 103 | 104 | QUnit.test('testDoubleStyleInjection', function( assert ) 105 | { 106 | $('#qunit-fixture').html('
This is a simple test.
'); 107 | $('#test').bigtext().bigtext(); 108 | 109 | // FIXME this jQuery result won't return more than one element. 110 | assert.ok($('#' + BigText.getStyleId('test')).length === 1, 'Test to make sure the style tag wasn\'t inserted twice.'); 111 | }); 112 | 113 | 114 | QUnit.test('testCleanup', function( assert ) 115 | { 116 | $('#qunit-fixture').html('
This is a simple test.
'); 117 | $('#test').bigtext(); 118 | 119 | assert.ok($('.bigtext-cloned').length === 0, 'Clone should be deleted.'); 120 | }); 121 | 122 | QUnit.test('testOneLine', function( assert ) 123 | { 124 | $('#qunit-fixture').html('
This is a single line.
'); 125 | 126 | BigTextTest.linesTest( assert, '#test', 600); 127 | }); 128 | 129 | QUnit.test('testTwoLines', function( assert ) 130 | { 131 | $('#qunit-fixture').html('
This is
a longer second line
'); 132 | 133 | BigTextTest.linesTest( assert, '#test', 600); 134 | }); 135 | 136 | QUnit.test('testThreeLines', function( assert ) 137 | { 138 | $('#qunit-fixture').html('
This is
a longer second line
An even longer third line.
'); 139 | 140 | BigTextTest.linesTest( assert, '#test', 600); 141 | }); 142 | 143 | QUnit.test('testThreeLinesWithAList', function( assert ) 144 | { 145 | $('#qunit-fixture').html('
  1. This is
  2. a longer second line
  3. An even longer third line.
'); 146 | 147 | BigTextTest.linesTest( assert, '#test', 600); 148 | }); 149 | 150 | QUnit.test('testTwoElements', function( assert ) 151 | { 152 | $('#qunit-fixture').html('
This is
a longer second line
This is
a longer second line
'); 153 | 154 | BigTextTest.linesTest( assert, '#test', 600); 155 | BigTextTest.linesTest( assert, '#test2', 400); 156 | 157 | assert.notEqual($('#test').find('> div').eq(0).css('font-size'), 158 | $('#test2').find('> div').eq(0).css('font-size'), 159 | 'Line 1 of each is a different size.'); 160 | 161 | assert.notEqual($('#test').find('> div').eq(1).css('font-size'), 162 | $('#test2').find('> div').eq(1).css('font-size'), 163 | 'Line 2 of each is a different size.'); 164 | }); 165 | 166 | QUnit.test('testPercentageWidth', function( assert ) 167 | { 168 | $('#qunit-fixture').html('
This is a single line.
'); 169 | 170 | BigTextTest.linesTest( assert, '#test', 300); 171 | }); 172 | 173 | QUnit.test('testNoChildren', function( assert ) 174 | { 175 | $('#qunit-fixture').html('
This is a single line.
'); 176 | 177 | BigTextTest.linesTest( assert, '#test', 300); 178 | }); 179 | 180 | QUnit.test('testMaxFontSize', function( assert ) 181 | { 182 | $('#qunit-fixture').html('
1
'); 183 | $('#test').bigtext(); 184 | 185 | assert.equal(BigText.DEFAULT_MAX_FONT_SIZE_PX + 'px', 186 | $('#test > div').css('font-size'), 187 | 'Font size should equal the maximum.'); 188 | }); 189 | 190 | QUnit.test('testUnbrokenSingleWord', function( assert ) 191 | { 192 | $('#qunit-fixture').html('
This
'); 193 | var startingFontSize = parseInt($('#test > div').css('font-size'), 10); 194 | $('#test').bigtext(); 195 | 196 | assert.ok(parseInt($('#test > div').css('font-size'), 10) > startingFontSize, 'Font size must be larger than the starting pixel size.'); 197 | }); 198 | 199 | QUnit.test('testTwoLinesButOneExempt', function( assert ) 200 | { 201 | $('#qunit-fixture').html('
This is
a longer second line
'); 202 | 203 | BigTextTest.linesTest( assert, '#test', 400); 204 | }); 205 | 206 | QUnit.test('testExemptLineWithChild', function( assert ) 207 | { 208 | var defaultExemptLineFontSize, 209 | childFontSize, 210 | $test = $('#test'), 211 | $exempt; 212 | 213 | $('#qunit-fixture').html('
This is
a longer second line
'); 214 | $exempt = $test.find('.bigtext-exempt'); 215 | 216 | defaultExemptLineFontSize = $exempt.css('font-size'); 217 | $test.bigtext(); 218 | childFontSize = $exempt.css('font-size'); 219 | 220 | assert.equal(defaultExemptLineFontSize, childFontSize, 'Exempt line\'s child font size must be unchanged'); 221 | }); 222 | 223 | QUnit.test('testIdCssSelectorStyle', function( assert ) 224 | { 225 | var id = 'test-style-insert'; 226 | // Travic-CI / Ubuntu PhantomJS needed a font-family here (the default font wasn’t bolding correctly) 227 | $(document.head || 'head').append( '' ); 228 | $('#qunit-fixture').html('
This is a single line.
'); 229 | 230 | BigTextTest.linesTest( assert, '#test', 600); 231 | $('#' + id).remove(); 232 | }); 233 | 234 | QUnit.test('testMaxWidth', function( assert ) 235 | { 236 | $('#qunit-fixture').html('
This is a single line.
'); 237 | 238 | BigTextTest.linesTest( assert, '#test', 600); 239 | }); 240 | 241 | QUnit.test('testNoConflict', function( assert ) 242 | { 243 | $('#qunit-fixture').html('
This is a single line.
'); 244 | 245 | var BT = BigText.noConflict(); 246 | $.fn.bt = BT.jQueryMethod; 247 | 248 | $('#test').bt(); 249 | 250 | var defaultDocumentFontSize = $('
').appendTo(document.body).css('font-size'), 251 | childFontSize = $('#test > div').css('font-size'); 252 | 253 | assert.notEqual(defaultDocumentFontSize, childFontSize, 'Font size must not equal the default.'); 254 | }); 255 | 256 | QUnit.test('testMinFontSize', function( assert ) 257 | { 258 | $('#qunit-fixture').html('
This is a super long line that will probably be too long for this single line. This is a super long line that will probably be too long for this single line.
'); 259 | $('#test').bigtext({ 260 | minfontsize: 16 261 | }); 262 | 263 | assert.equal('16px', $('#test > div').css('font-size'), 'Font size should equal the minimum.'); 264 | assert.equal('normal', $('#test > div').css('white-space'), 'When minimum is set, word wrap should re-enable.'); 265 | }); 266 | 267 | QUnit.test('testChildClassReplace', function( assert ) 268 | { 269 | $('#qunit-fixture').html('
This is a single line.
'); 270 | 271 | BigTextTest.linesTest( assert, '#test', 600); 272 | assert.ok($('#test > div').hasClass('testbigtext-line1'), 'First line should still have testbigtext-line1 class'); 273 | assert.ok(!$('#test > div').hasClass('test'), 'First line should not have test class'); 274 | }); 275 | 276 | QUnit.test('testTextTransform', function( assert ) 277 | { 278 | $('#qunit-fixture').html('
This is a single line.
'); 279 | 280 | BigTextTest.linesTest( assert, '#test', 600); 281 | }); 282 | 283 | QUnit.test('testWordSpacing', function( assert ) 284 | { 285 | $('#qunit-fixture').html('
This is a single line.
'); 286 | 287 | BigTextTest.linesTest( assert, '#test', 600); 288 | }); 289 | 290 | QUnit.test('testLetterSpacing', function( assert ) 291 | { 292 | $('#qunit-fixture').html('
This is a single line.
'); 293 | 294 | BigTextTest.linesTest( assert, '#test', 600); 295 | }); 296 | 297 | QUnit.test('testSizes', function( assert ) 298 | { 299 | for( var j = 200, k = 800; j
This is a single line.
'); 301 | 302 | BigTextTest.linesTest( assert, '#test', j); 303 | } 304 | }); 305 | 306 | QUnit.test('testSpanChildren', function( assert ) 307 | { 308 | $('#qunit-fixture').html('
This isa longer second line
'); 309 | 310 | BigTextTest.linesTest( assert, '#test', 600); 311 | }); 312 | 313 | QUnit.test('testMixtureChildren', function( assert ) 314 | { 315 | $('#qunit-fixture').html('
This is
a longer second line
'); 316 | 317 | BigTextTest.linesTest( assert, '#test', 600); 318 | }); 319 | }( this, jQuery )); 320 | -------------------------------------------------------------------------------- /grunt/banner.txt: -------------------------------------------------------------------------------- 1 | /*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> 2 | <%= pkg.homepage ? " * " + pkg.homepage : "" %> 3 | * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %> (@<%= pkg.author.twitter %>) 4 | * <%= pkg.license %> License */ 5 | -------------------------------------------------------------------------------- /grunt/config-lib/bytesize.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dist: { 3 | src: [ 4 | "<%= pkg.config.dist %>/*.js", 5 | "<%= pkg.config.dist %>/*.css" 6 | ] 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /grunt/config-lib/clean.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | files: ["<%= pkg.config.dist %>/"] 3 | }; 4 | -------------------------------------------------------------------------------- /grunt/config-lib/concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: { 3 | stripBanners: true 4 | }, 5 | js: { 6 | src: [], 7 | dest: "<%= pkg.config.dist %>/<%= pkg.name %>.js" 8 | }, 9 | jstest: { 10 | src: [], 11 | dest: "<%= pkg.config.dist %>/test/tests.js" 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /grunt/config-lib/csslint.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: { 3 | // Use a .csslintrc file so the same options are reused in our editor. 4 | // See https://github.com/CSSLint/csslint/wiki/Rules 5 | csslintrc: ".csslintrc" 6 | }, 7 | src: [ "<%= pkg.config.src %>/**/*.css" ] 8 | }; 9 | -------------------------------------------------------------------------------- /grunt/config-lib/gh-pages.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: {}, 3 | src: ["<%= pkg.config.dist %>/**/*", "<%= pkg.config.test %>/**/*", "<%= pkg.config.demo %>/**/*", "<%= pkg.config.bower %>/**/*"] 4 | }; 5 | -------------------------------------------------------------------------------- /grunt/config-lib/jshint.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: { 3 | // Use a .jshintrc file so the same options are reused in our editor. 4 | jshintrc: ".jshintrc" 5 | }, 6 | src: [ "Gruntfile.js", "<%= pkg.config.src %>/**/*.js" ] 7 | }; 8 | -------------------------------------------------------------------------------- /grunt/config-lib/lintspaces.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: { 3 | src: [ 4 | '<%= pkg.config.src %>/**/*.js', 5 | '<%= pkg.config.src %>/**/*.css', 6 | '<%= pkg.config.grunt %>/**/*.js', 7 | '<%= pkg.config.grunt %>/**/*.css' 8 | ], 9 | options: { 10 | editorconfig: '.editorconfig' 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /grunt/config-lib/mkdir.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | init: { 3 | options: { 4 | create: [ "<%= pkg.config.src %>", "<%= pkg.config.demo %>" ] 5 | } 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /grunt/config-lib/qunit.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: ["<%= pkg.config.test %>/**/*.html"] 3 | }; 4 | -------------------------------------------------------------------------------- /grunt/config-lib/usebanner.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dist: { 3 | options: { 4 | position: "top", 5 | banner: "<%= banner %>" 6 | }, 7 | files: { 8 | src: [ "<%= pkg.config.dist %>/*.js", "<%= pkg.config.dist %>/*.css" ] 9 | } 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /grunt/config-lib/watch.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | files: [ "<%= pkg.config.src %>/**/*" ], 3 | tasks: [ "src", "test" ] 4 | }; 5 | -------------------------------------------------------------------------------- /grunt/config/concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | js: { 3 | src: ["src/bigtext.js"] 4 | }, 5 | jstest: { 6 | src: ["src/bigtext-test.js"] 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /grunt/tasks.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | "use strict"; 3 | 4 | grunt.registerTask( "init", [ "mkdir" ] ); 5 | 6 | grunt.registerTask( "default", [ "clean", "lint", "src", "test", "bytesize" ] ); 7 | 8 | grunt.registerTask( "lint", [ "csslint", "jshint", "lintspaces" ] ); 9 | grunt.registerTask( "src", [ "lint", "concat", "usebanner" ] ); 10 | grunt.registerTask( "test", [ "qunit" ] ); 11 | 12 | grunt.registerTask( "deploy", [ "default", "gh-pages" ] ); 13 | 14 | }; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bigtext", 3 | "title": "BigText", 4 | "version": "1.0.1", 5 | "main": "./dist/bigtext.js", 6 | "description": "Calculates the font-size and word-spacing needed to match a line of text to a specific width. (jQuery plugin)", 7 | "keywords": [ 8 | "grunt", 9 | "typography" 10 | ], 11 | "homepage": "https://github.com/zachleat/bigtext", 12 | "bugs": "https://github.com/zachleat/bigtext/issues", 13 | "author": { 14 | "name": "Zach Leatherman", 15 | "email": "zachleatherman@gmail.com", 16 | "twitter": "zachleat", 17 | "github": "zachleat", 18 | "url": "http://zachleat.com" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git://github.com/zachleat/bigtext.git" 23 | }, 24 | "scripts": { 25 | "test": "grunt test" 26 | }, 27 | "dependencies": {}, 28 | "devDependencies": { 29 | "bower": "^1.8.0", 30 | "bytesize": "~0.2.0", 31 | "glob": "~7.1.2", 32 | "grunt": "~1.0.1", 33 | "grunt-banner": "~0.6.0", 34 | "grunt-bytesize": "~0.2.0", 35 | "grunt-contrib-clean": "~1.1.0", 36 | "grunt-contrib-concat": "~1.0.1", 37 | "grunt-contrib-csslint": "~2.0.0", 38 | "grunt-contrib-jshint": "~1.1.0", 39 | "grunt-contrib-qunit": "~2.0.0", 40 | "grunt-contrib-watch": "~1.0.0", 41 | "grunt-gh-pages": "~2.0.0", 42 | "grunt-lintspaces": "~0.8.1", 43 | "grunt-mkdir": "~1.0.0", 44 | "grunt-replace": "~1.0.1", 45 | "load-grunt-tasks": "~3.5.2", 46 | "matchdep": "~1.0.0" 47 | }, 48 | "peerDependencies": {}, 49 | "engines": { 50 | "node": ">= 4", 51 | "npm": ">=1.2.10" 52 | }, 53 | "license": "MIT", 54 | "config": { 55 | "grunt": "grunt", 56 | "src": "src", 57 | "dist": "dist", 58 | "test": "test", 59 | "demo": "demo", 60 | "bower": "bower_components" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/bigtext-test.js: -------------------------------------------------------------------------------- 1 | /* global BigText:true */ 2 | (function( w, $ ) { 3 | "use strict"; 4 | 5 | var BigTextTest = {}, 6 | ua = navigator.userAgent, 7 | ie = (function(){ 8 | 9 | var undef, 10 | v = 3, 11 | div = document.createElement('div'), 12 | all = div.getElementsByTagName('i'); 13 | 14 | while ( 15 | div.innerHTML = '', 16 | all[0] 17 | ) { 18 | continue; 19 | } 20 | 21 | return v > 4 ? v : undef; 22 | }()); 23 | 24 | // Be a little bit more forgiving on IE8 and Travis-CI/Ubuntu + PhantomJS 25 | if( ie && ie <= 8 || 26 | ua.indexOf( 'PhantomJS' ) > -1 && ua.indexOf( 'Linux' ) > -1 ) { 27 | 28 | BigTextTest.tolerance = 14; 29 | } else { 30 | BigTextTest.tolerance = 10; 31 | } 32 | 33 | // If the lines of text are blocks, testing their width will tell us nothing. 34 | BigTextTest.init = function() 35 | { 36 | return this.css('float', 'left'); 37 | }; 38 | 39 | BigTextTest.linesTest = function(assert, selector, expectedWidth, options) 40 | { 41 | options = $.extend( options, {} ); 42 | 43 | var tolerance = BigTextTest.tolerance, 44 | minWidth = expectedWidth - tolerance, 45 | maxWidth = expectedWidth + tolerance, 46 | $test = $(selector), 47 | $lines = options.childSelector ? $test.find( options.childSelector ) : $test.children(), 48 | startingFontSize = parseInt($lines.eq(0).css('font-size'), 10); 49 | 50 | BigTextTest.init.call($lines); 51 | 52 | $lines.each(function(j) 53 | { 54 | var width = $(this).width(); 55 | assert.ok(!(( minWidth < width ) && ( width < maxWidth )), 'Pretest: Line ' + j + ' should not be max width (' + minWidth + ' < ' + width + ' < ' + maxWidth + ', font-size: ' + $(this).css('font-size') + ')'); 56 | }); 57 | 58 | $test.bigtext(options); 59 | 60 | assert.ok('Class added.', $test.is('.bigtext')); 61 | 62 | $lines.each(function(j) 63 | { 64 | var $t = $(this), 65 | width = $t.width(), 66 | height = $t.height(), 67 | fontSize = parseFloat($t.css('font-size')), 68 | $heightElement = $('
A
').css({ 69 | 'font-size': fontSize, 70 | position: 'absolute' 71 | }).appendTo(document.body), 72 | expectedHeight = $heightElement.height(), 73 | minHeight = expectedHeight - tolerance, 74 | maxHeight = expectedHeight + tolerance; 75 | 76 | assert.ok('Line ' + j + ' class added.', $t.is('.bigtext-line' + j)); 77 | if($t.hasClass(BigText.EXEMPT_CLASS)) { 78 | // must be added to document to get font-size 79 | var defaultDocumentFontSize = parseInt($('
').appendTo(document.body).css('font-size'), 10); 80 | assert.equal(defaultDocumentFontSize, fontSize, 'Line ' + j + ' Font size must be unchanged'); 81 | } else { 82 | assert.ok(fontSize > startingFontSize, 'Line ' + j + ' Font size must be larger than the starting pixel size'); 83 | assert.ok(minWidth < width && width < maxWidth, 'Line ' + j + ' width should be about ' + expectedWidth + 'px (' + width + ')'); 84 | assert.ok(minHeight < height && height < maxHeight, 'Line ' + j + ' height should be about ' + expectedHeight + 'px (' + minHeight + ' < ' + height + ' < ' + maxHeight + ')'); 85 | } 86 | 87 | $heightElement.remove(); 88 | }); 89 | }; 90 | 91 | QUnit.test('testExists', function( assert ) 92 | { 93 | assert.ok(!!BigText); 94 | assert.ok(!!$.fn.bigtext); 95 | }); 96 | 97 | QUnit.test('testStyleInjection', function( assert ) 98 | { 99 | $('#qunit-fixture').html('
This is a simple test.
'); 100 | $('#test').bigtext(); 101 | 102 | assert.equal($('#' + BigText.getStyleId('test')).length, 1, 'Test to make sure the style tag was inserted.'); 103 | }); 104 | 105 | QUnit.test('testDoubleStyleInjection', function( assert ) 106 | { 107 | $('#qunit-fixture').html('
This is a simple test.
'); 108 | $('#test').bigtext().bigtext(); 109 | 110 | // FIXME this jQuery result won't return more than one element. 111 | assert.ok($('#' + BigText.getStyleId('test')).length === 1, 'Test to make sure the style tag wasn\'t inserted twice.'); 112 | }); 113 | 114 | 115 | QUnit.test('testCleanup', function( assert ) 116 | { 117 | $('#qunit-fixture').html('
This is a simple test.
'); 118 | $('#test').bigtext(); 119 | 120 | assert.ok($('.bigtext-cloned').length === 0, 'Clone should be deleted.'); 121 | }); 122 | 123 | QUnit.test('testOneLine', function( assert ) 124 | { 125 | $('#qunit-fixture').html('
This is a single line.
'); 126 | 127 | BigTextTest.linesTest( assert, '#test', 600); 128 | }); 129 | 130 | QUnit.test('testTwoLines', function( assert ) 131 | { 132 | $('#qunit-fixture').html('
This is
a longer second line
'); 133 | 134 | BigTextTest.linesTest( assert, '#test', 600); 135 | }); 136 | 137 | QUnit.test('testThreeLines', function( assert ) 138 | { 139 | $('#qunit-fixture').html('
This is
a longer second line
An even longer third line.
'); 140 | 141 | BigTextTest.linesTest( assert, '#test', 600); 142 | }); 143 | 144 | QUnit.test('testThreeLinesWithAList', function( assert ) 145 | { 146 | $('#qunit-fixture').html('
  1. This is
  2. a longer second line
  3. An even longer third line.
'); 147 | 148 | BigTextTest.linesTest( assert, '#test', 600); 149 | }); 150 | 151 | QUnit.test('testTwoElements', function( assert ) 152 | { 153 | $('#qunit-fixture').html('
This is
a longer second line
This is
a longer second line
'); 154 | 155 | BigTextTest.linesTest( assert, '#test', 600); 156 | BigTextTest.linesTest( assert, '#test2', 400); 157 | 158 | assert.notEqual($('#test').find('> div').eq(0).css('font-size'), 159 | $('#test2').find('> div').eq(0).css('font-size'), 160 | 'Line 1 of each is a different size.'); 161 | 162 | assert.notEqual($('#test').find('> div').eq(1).css('font-size'), 163 | $('#test2').find('> div').eq(1).css('font-size'), 164 | 'Line 2 of each is a different size.'); 165 | }); 166 | 167 | QUnit.test('testPercentageWidth', function( assert ) 168 | { 169 | $('#qunit-fixture').html('
This is a single line.
'); 170 | 171 | BigTextTest.linesTest( assert, '#test', 300); 172 | }); 173 | 174 | QUnit.test('testNoChildren', function( assert ) 175 | { 176 | $('#qunit-fixture').html('
This is a single line.
'); 177 | 178 | BigTextTest.linesTest( assert, '#test', 300); 179 | }); 180 | 181 | QUnit.test('testMaxFontSize', function( assert ) 182 | { 183 | $('#qunit-fixture').html('
1
'); 184 | $('#test').bigtext(); 185 | 186 | assert.equal(BigText.DEFAULT_MAX_FONT_SIZE_PX + 'px', 187 | $('#test > div').css('font-size'), 188 | 'Font size should equal the maximum.'); 189 | }); 190 | 191 | QUnit.test('testUnbrokenSingleWord', function( assert ) 192 | { 193 | $('#qunit-fixture').html('
This
'); 194 | var startingFontSize = parseInt($('#test > div').css('font-size'), 10); 195 | $('#test').bigtext(); 196 | 197 | assert.ok(parseInt($('#test > div').css('font-size'), 10) > startingFontSize, 'Font size must be larger than the starting pixel size.'); 198 | }); 199 | 200 | QUnit.test('testTwoLinesButOneExempt', function( assert ) 201 | { 202 | $('#qunit-fixture').html('
This is
a longer second line
'); 203 | 204 | BigTextTest.linesTest( assert, '#test', 400); 205 | }); 206 | 207 | QUnit.test('testExemptLineWithChild', function( assert ) 208 | { 209 | var defaultExemptLineFontSize, 210 | childFontSize, 211 | $test = $('#test'), 212 | $exempt; 213 | 214 | $('#qunit-fixture').html('
This is
a longer second line
'); 215 | $exempt = $test.find('.bigtext-exempt'); 216 | 217 | defaultExemptLineFontSize = $exempt.css('font-size'); 218 | $test.bigtext(); 219 | childFontSize = $exempt.css('font-size'); 220 | 221 | assert.equal(defaultExemptLineFontSize, childFontSize, 'Exempt line\'s child font size must be unchanged'); 222 | }); 223 | 224 | QUnit.test('testIdCssSelectorStyle', function( assert ) 225 | { 226 | var id = 'test-style-insert'; 227 | // Travic-CI / Ubuntu PhantomJS needed a font-family here (the default font wasn’t bolding correctly) 228 | $(document.head || 'head').append( '' ); 229 | $('#qunit-fixture').html('
This is a single line.
'); 230 | 231 | BigTextTest.linesTest( assert, '#test', 600); 232 | $('#' + id).remove(); 233 | }); 234 | 235 | QUnit.test('testMaxWidth', function( assert ) 236 | { 237 | $('#qunit-fixture').html('
This is a single line.
'); 238 | 239 | BigTextTest.linesTest( assert, '#test', 600); 240 | }); 241 | 242 | QUnit.test('testNoConflict', function( assert ) 243 | { 244 | $('#qunit-fixture').html('
This is a single line.
'); 245 | 246 | var BT = BigText.noConflict(); 247 | $.fn.bt = BT.jQueryMethod; 248 | 249 | $('#test').bt(); 250 | 251 | var defaultDocumentFontSize = $('
').appendTo(document.body).css('font-size'), 252 | childFontSize = $('#test > div').css('font-size'); 253 | 254 | assert.notEqual(defaultDocumentFontSize, childFontSize, 'Font size must not equal the default.'); 255 | }); 256 | 257 | QUnit.test('testMinFontSize', function( assert ) 258 | { 259 | $('#qunit-fixture').html('
This is a super long line that will probably be too long for this single line. This is a super long line that will probably be too long for this single line.
'); 260 | $('#test').bigtext({ 261 | minfontsize: 16 262 | }); 263 | 264 | assert.equal('16px', $('#test > div').css('font-size'), 'Font size should equal the minimum.'); 265 | assert.equal('normal', $('#test > div').css('white-space'), 'When minimum is set, word wrap should re-enable.'); 266 | }); 267 | 268 | QUnit.test('testChildClassReplace', function( assert ) 269 | { 270 | $('#qunit-fixture').html('
This is a single line.
'); 271 | 272 | BigTextTest.linesTest( assert, '#test', 600); 273 | assert.ok($('#test > div').hasClass('testbigtext-line1'), 'First line should still have testbigtext-line1 class'); 274 | assert.ok(!$('#test > div').hasClass('test'), 'First line should not have test class'); 275 | }); 276 | 277 | QUnit.test('testTextTransform', function( assert ) 278 | { 279 | $('#qunit-fixture').html('
This is a single line.
'); 280 | 281 | BigTextTest.linesTest( assert, '#test', 600); 282 | }); 283 | 284 | QUnit.test('testWordSpacing', function( assert ) 285 | { 286 | $('#qunit-fixture').html('
This is a single line.
'); 287 | 288 | BigTextTest.linesTest( assert, '#test', 600); 289 | }); 290 | 291 | QUnit.test('testLetterSpacing', function( assert ) 292 | { 293 | $('#qunit-fixture').html('
This is a single line.
'); 294 | 295 | BigTextTest.linesTest( assert, '#test', 600); 296 | }); 297 | 298 | QUnit.test('testSizes', function( assert ) 299 | { 300 | for( var j = 200, k = 800; j
This is a single line.
'); 302 | 303 | BigTextTest.linesTest( assert, '#test', j); 304 | } 305 | }); 306 | 307 | QUnit.test('testSpanChildren', function( assert ) 308 | { 309 | $('#qunit-fixture').html('
This isa longer second line
'); 310 | 311 | BigTextTest.linesTest( assert, '#test', 600); 312 | }); 313 | 314 | QUnit.test('testMixtureChildren', function( assert ) 315 | { 316 | $('#qunit-fixture').html('
This is
a longer second line
'); 317 | 318 | BigTextTest.linesTest( assert, '#test', 600); 319 | }); 320 | }( this, jQuery )); 321 | -------------------------------------------------------------------------------- /src/bigtext.js: -------------------------------------------------------------------------------- 1 | (function(window, $) { 2 | "use strict"; 3 | 4 | var counter = 0, 5 | $headCache = $('head'), 6 | oldBigText = window.BigText, 7 | oldjQueryMethod = $.fn.bigtext, 8 | BigText = { 9 | DEBUG_MODE: false, 10 | DEFAULT_MIN_FONT_SIZE_PX: null, 11 | DEFAULT_MAX_FONT_SIZE_PX: 528, 12 | GLOBAL_STYLE_ID: 'bigtext-style', 13 | STYLE_ID: 'bigtext-id', 14 | LINE_CLASS_PREFIX: 'bigtext-line', 15 | EXEMPT_CLASS: 'bigtext-exempt', 16 | noConflict: function(restore) 17 | { 18 | if(restore) { 19 | $.fn.bigtext = oldjQueryMethod; 20 | window.BigText = oldBigText; 21 | } 22 | return BigText; 23 | }, 24 | supports: { 25 | wholeNumberFontSizeOnly: (function() { 26 | if( !( 'getComputedStyle' in window ) ) { 27 | return true; 28 | } 29 | var test = $('
').css({ 30 | position: 'absolute', 31 | 'font-size': '14.1px' 32 | }).insertBefore( $('script').eq(0) ), 33 | computedStyle = window.getComputedStyle( test[0], null ); 34 | 35 | var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 36 | test.remove(); 37 | return ret; 38 | })() 39 | }, 40 | init: function() { 41 | if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 42 | $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 43 | '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 44 | } 45 | }, 46 | bindResize: function(eventName, resizeFunction) { 47 | var timeoutId; 48 | $(window).off(eventName).on(eventName, function() { 49 | if( timeoutId ) { 50 | clearTimeout( timeoutId ); 51 | } 52 | timeoutId = setTimeout( resizeFunction, 100 ); 53 | }); 54 | }, 55 | getStyleId: function(id) 56 | { 57 | return BigText.STYLE_ID + '-' + id; 58 | }, 59 | generateStyleTag: function(id, css) 60 | { 61 | return $('').attr('id', id); 62 | }, 63 | clearCss: function(id) 64 | { 65 | var styleId = BigText.getStyleId(id); 66 | $('#' + styleId).remove(); 67 | }, 68 | generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 69 | { 70 | var css = []; 71 | 72 | BigText.clearCss(id); 73 | 74 | for(var j=0, k=linesFontSizes.length; j= maxWidth) { 139 | // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size)); 140 | $line.css(property, ''); 141 | 142 | if(width === maxWidth) { 143 | return { 144 | match: 'exact', 145 | size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 146 | }; 147 | } 148 | 149 | // Since this is an estimate, we calculate how far over the width we went with the new value. 150 | // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 151 | // Otherwise, we revert to the underestimate. 152 | var under = maxWidth - previousWidth, 153 | over = width - maxWidth; 154 | 155 | return { 156 | match: 'estimate', 157 | size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 158 | }; 159 | } 160 | 161 | return width; 162 | }, 163 | calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize) 164 | { 165 | var $c = $t.clone(true) 166 | .addClass('bigtext-cloned') 167 | .css({ 168 | fontFamily: $t.css('font-family'), 169 | textTransform: $t.css('text-transform'), 170 | wordSpacing: $t.css('word-spacing'), 171 | letterSpacing: $t.css('letter-spacing'), 172 | position: 'absolute', 173 | left: BigText.DEBUG_MODE ? 0 : -9999, 174 | top: BigText.DEBUG_MODE ? 0 : -9999 175 | }) 176 | .appendTo(document.body); 177 | 178 | // font-size isn't the only thing we can modify, we can also mess with: 179 | // word-spacing and letter-spacing. WebKit does not respect subpixel 180 | // letter-spacing, word-spacing, or font-size. 181 | // TODO try -webkit-transform: scale() as a workaround. 182 | var fontSizes = [], 183 | wordSpacings = [], 184 | minFontSizes = [], 185 | ratios = []; 186 | 187 | $children.css('float', 'left').each(function() { 188 | var $line = $(this), 189 | // TODO replace 8, 4 with a proportional size to the calculated font-size. 190 | intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 191 | lineMax, 192 | newFontSize; 193 | 194 | if($line.hasClass(BigText.EXEMPT_CLASS)) { 195 | fontSizes.push(null); 196 | ratios.push(null); 197 | minFontSizes.push(false); 198 | return; 199 | } 200 | 201 | // TODO we can cache this ratio? 202 | var autoGuessSubtraction = 32, // font size in px 203 | currentFontSize = parseFloat($line.css('font-size')), 204 | ratio = ( $line.width() / currentFontSize ).toFixed(6); 205 | 206 | newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 207 | 208 | outer: for(var m=0, n=intervals.length; m maxFontSize) { 211 | newFontSize = maxFontSize; 212 | break outer; 213 | } 214 | 215 | lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 216 | if(typeof lineMax !== 'number') { 217 | newFontSize = lineMax.size; 218 | 219 | if(lineMax.match === 'exact') { 220 | break outer; 221 | } 222 | break inner; 223 | } 224 | } 225 | } 226 | 227 | ratios.push(maxWidth / newFontSize); 228 | 229 | if(newFontSize > maxFontSize) { 230 | fontSizes.push(maxFontSize); 231 | minFontSizes.push(false); 232 | } else if(!!minFontSize && newFontSize < minFontSize) { 233 | fontSizes.push(minFontSize); 234 | minFontSizes.push(true); 235 | } else { 236 | fontSizes.push(newFontSize); 237 | minFontSizes.push(false); 238 | } 239 | }).each(function(lineNumber) { 240 | var $line = $(this), 241 | wordSpacing = 0, 242 | interval = 1, 243 | maxWordSpacing; 244 | 245 | if($line.hasClass(BigText.EXEMPT_CLASS)) { 246 | wordSpacings.push(null); 247 | return; 248 | } 249 | 250 | // must re-use font-size, even though it was removed above. 251 | $line.css('font-size', fontSizes[lineNumber] + 'px'); 252 | 253 | for(var m=1, n=3; m 2 | 3 | 4 | 5 | BigText Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

BigText Test Suite

18 |

19 |
20 |

21 |
    22 |
    23 | 24 | 25 | --------------------------------------------------------------------------------