forked from mendicant-original/community
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'long-names-37' of https://github.com/gjp/community into…
… gjp-long-names-37
- Loading branch information
Showing
4 changed files
with
276 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,263 @@ | |||
;(function(window, $) | |||
{ | |||
var counter = 0, | |||
$headCache = $('head'), | |||
oldBigText = window.BigText, | |||
oldjQueryMethod = $.fn.bigtext, | |||
BigText = { | |||
DEFAULT_MIN_FONT_SIZE_PX: null, | |||
DEFAULT_MAX_FONT_SIZE_PX: 528, | |||
GLOBAL_STYLE_ID: 'bigtext-style', | |||
STYLE_ID: 'bigtext-id', | |||
LINE_CLASS_PREFIX: 'bigtext-line', | |||
EXEMPT_CLASS: 'bigtext-exempt', | |||
DEFAULT_CHILD_SELECTOR: '> div', | |||
childSelectors: { | |||
div: '> div', | |||
ol: '> li', | |||
ul: '> li' | |||
}, | |||
noConflict: function(restore) | |||
{ | |||
if(restore) { | |||
$.fn.bigtext = oldjQueryMethod; | |||
window.BigText = oldBigText; | |||
} | |||
return BigText; | |||
}, | |||
init: function() | |||
{ | |||
if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { | |||
$headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; }', | |||
'.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); | |||
} | |||
}, | |||
bindResize: function(eventName, resizeFunction) | |||
{ | |||
if($.throttle) { | |||
// https://github.com/cowboy/jquery-throttle-debounce | |||
$(window).unbind(eventName).bind(eventName, $.throttle(100, resizeFunction)); | |||
} else { | |||
if($.fn.smartresize) { | |||
// https://github.com/lrbabe/jquery-smartresize/ | |||
eventName = 'smartresize.' + eventName; | |||
} | |||
$(window).unbind(eventName).bind(eventName, resizeFunction); | |||
} | |||
}, | |||
getStyleId: function(id) | |||
{ | |||
return BigText.STYLE_ID + '-' + id; | |||
}, | |||
generateStyleTag: function(id, css) | |||
{ | |||
return $('<style>' + css.join('\n') + '</style>').attr('id', id); | |||
}, | |||
clearCss: function(id) | |||
{ | |||
var styleId = BigText.getStyleId(id); | |||
$('#' + styleId).remove(); | |||
}, | |||
generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) | |||
{ | |||
var css = []; | |||
|
|||
BigText.clearCss(id); | |||
|
|||
for(var j=0, k=linesFontSizes.length; j<k; j++) { | |||
css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + | |||
(minFontSizes[j] ? ' white-space: normal;' : '') + | |||
(linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + | |||
(lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + | |||
'}'); | |||
} | |||
|
|||
return BigText.generateStyleTag(BigText.getStyleId(id), css); | |||
}, | |||
jQueryMethod: function(options) | |||
{ | |||
BigText.init(); | |||
|
|||
options = $.extend({ | |||
minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, | |||
maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, | |||
childSelector: '', | |||
resize: true | |||
}, options || {}); | |||
|
|||
return this.each(function() | |||
{ | |||
var $t = $(this).addClass('bigtext'), | |||
childSelector = options.childSelector || | |||
BigText.childSelectors[this.tagName.toLowerCase()] || | |||
BigText.DEFAULT_CHILD_SELECTOR, | |||
maxWidth = $t.width(), | |||
id = $t.attr('id'); | |||
|
|||
if(!id) { | |||
id = 'bigtext-id' + (counter++); | |||
$t.attr('id', id); | |||
} | |||
|
|||
if(options.resize) { | |||
BigText.bindResize('resize.bigtext-event-' + id, function() | |||
{ | |||
BigText.jQueryMethod.call($('#' + id), options); | |||
}); | |||
} | |||
|
|||
BigText.clearCss(id); | |||
|
|||
$t.find(childSelector).addClass(function(lineNumber, className) | |||
{ | |||
// remove existing line classes. | |||
return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), | |||
BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); | |||
}); | |||
|
|||
var sizes = calculateSizes($t, childSelector, maxWidth, options.maxfontsize, options.minfontsize); | |||
$headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); | |||
}); | |||
} | |||
}; | |||
|
|||
function testLineDimensions($line, maxWidth, property, size, interval, units) | |||
{ | |||
var width; | |||
$line.css(property, size + units); | |||
|
|||
width = $line.width(); | |||
|
|||
if(width >= maxWidth) { | |||
$line.css(property, ''); | |||
|
|||
if(width == maxWidth) { | |||
return { | |||
match: 'exact', | |||
size: parseFloat((parseFloat(size) - .1).toFixed(3)) | |||
}; | |||
} | |||
|
|||
return { | |||
match: 'estimate', | |||
size: parseFloat((parseFloat(size) - interval).toFixed(3)) | |||
}; | |||
} | |||
|
|||
return false; | |||
} | |||
|
|||
function calculateSizes($t, childSelector, maxWidth, maxFontSize, minFontSize) | |||
{ | |||
var $c = $t.clone(true) | |||
.addClass('bigtext-cloned') | |||
.css({ | |||
'min-width': parseInt(maxWidth, 10), | |||
width: 'auto', | |||
position: 'absolute', | |||
left: -9999, | |||
top: -9999 | |||
}).appendTo(document.body); | |||
|
|||
// font-size isn't the only thing we can modify, we can also mess with: | |||
// word-spacing and letter-spacing. | |||
// Note: webkit does not respect subpixel letter-spacing or word-spacing, | |||
// nor does it respect hundredths of a font-size em. | |||
var fontSizes = [], | |||
wordSpacings = [], | |||
minFontSizes = [], | |||
ratios = []; | |||
|
|||
$c.find(childSelector).css({ | |||
'float': 'left', | |||
'clear': 'left' | |||
}).each(function(lineNumber) { | |||
var $line = $(this), | |||
intervals = [4,1,.4,.1], | |||
lineMax; | |||
|
|||
if($line.hasClass(BigText.EXEMPT_CLASS)) { | |||
fontSizes.push(null); | |||
ratios.push(null); | |||
minFontSizes.push(false); | |||
return; | |||
} | |||
|
|||
// TODO we can cache this ratio? | |||
var autoGuessSubtraction = 20, // px | |||
currentFontSize = parseFloat($line.css('font-size')), | |||
lineWidth = $line.width(), | |||
ratio = (lineWidth / currentFontSize).toFixed(6), | |||
newFontSize = parseFloat(((maxWidth - autoGuessSubtraction) / ratio).toFixed(3)); | |||
|
|||
outer: for(var m=0, n=intervals.length; m<n; m++) { | |||
inner: for(var j=1, k=4; j<=k; j++) { | |||
if(newFontSize + j*intervals[m] > maxFontSize) { | |||
newFontSize = maxFontSize; | |||
break outer; | |||
} | |||
|
|||
lineMax = testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px'); | |||
if(lineMax !== false) { | |||
newFontSize = lineMax.size; | |||
|
|||
if(lineMax.match == 'exact') { | |||
break outer; | |||
} | |||
break inner; | |||
} | |||
} | |||
} | |||
|
|||
ratios.push(maxWidth / newFontSize); | |||
|
|||
if(newFontSize > maxFontSize) { | |||
fontSizes.push(maxFontSize); | |||
minFontSizes.push(false); | |||
} else if(!!minFontSize && newFontSize < minFontSize) { | |||
fontSizes.push(minFontSize); | |||
minFontSizes.push(true); | |||
} else { | |||
fontSizes.push(newFontSize); | |||
minFontSizes.push(false); | |||
} | |||
}).each(function(lineNumber) { | |||
var $line = $(this), | |||
wordSpacing = 0, | |||
interval = 1, | |||
maxWordSpacing; | |||
|
|||
if($line.hasClass(BigText.EXEMPT_CLASS)) { | |||
wordSpacings.push(null); | |||
return; | |||
} | |||
|
|||
// must re-use font-size, even though it was removed above. | |||
$line.css('font-size', fontSizes[lineNumber] + 'px'); | |||
|
|||
for(var m=1, n=5; m<n; m+=interval) { | |||
maxWordSpacing = testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px'); | |||
if(maxWordSpacing !== false) { | |||
wordSpacing = maxWordSpacing.size; | |||
break; | |||
} | |||
} | |||
|
|||
$line.css('font-size', ''); | |||
wordSpacings.push(wordSpacing); | |||
}).removeAttr('style'); | |||
|
|||
$c.remove(); | |||
|
|||
return { | |||
fontSizes: fontSizes, | |||
wordSpacings: wordSpacings, | |||
ratios: ratios, | |||
minFontSizes: minFontSizes | |||
}; | |||
} | |||
|
|||
$.fn.bigtext = BigText.jQueryMethod; | |||
window.BigText = BigText; | |||
|
|||
})(this, jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters