// Badonkatrunc 1.0.0, (http://badonkatrunc.com) // Copyright (c) 2012 Plexipixel, Inc. (http://plexipixel.com) // Developed by: Joel Day (joeld@plexipixel.com) // Co-conspirator: David Seelig // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. (function($){var methods={init:function(options){var all=this;var instanceOptions=$.extend(true,{},$.fn.badonkatrunc.defaultOptions,options);if(instanceOptions.fitDirection!="horizontal"&&instanceOptions.fitDirection!="vertical"){$.error("'"+instanceOptions.fitDirection+"' is not a valid fit direction. Use 'horizontal' or 'vertical.'");return this;}if(instanceOptions.truncateLocation!="start"&&instanceOptions.truncateLocation!="middle"&&instanceOptions.truncateLocation!="end"){$.error("'"+instanceOptions.truncateLocation+"' is not a valid truncation location. Use 'start,' 'middle' or 'end.'");return this;}if(instanceOptions.minimumFontSize>instanceOptions.maximumFontSize){$.error("Minimum font size can not exceed the maximum font size.");return this;}if(instanceOptions.minimumLetterSpacing>instanceOptions.maximumLetterSpacing){$.error("Minimum letter spacing can not exceed the maximum letter spacing.");return this;}return this.each(function(){var $this=$(this);var data=$(this).data("badonkatrunc");if(data){$this.badonkatrunc("destroy");}var instance=pluginInstance($this,instanceOptions,all);$(this).data("badonkatrunc",instance);instance.init();if(instance.options.automaticSizeTracking){resizeMonitor.add(instance);}});},destroy:function(){return this.each(function(){var $this=$(this);var data=$this.data("badonkatrunc");data.destroy();resizeMonitor.remove(data);dirtyMonitor.remove(data);$(window).unbind(".badonkatrunc");$this.removeData("badonkatrunc");});},refresh:function(){return this.each(function(){var $this=$(this);var data=$this.data("badonkatrunc");dirtyMonitor.remove(data);data.refresh();});},changeContents:function(newContents){return this.each(function(){var $this=$(this);var data=$this.data("badonkatrunc");if(typeof(newContents)=="string"){data.contentHtml=$("").text(newContents).html();}else{data.contentHtml=$(newContents).html();}dirtyMonitor.add(data);});}};$.fn.badonkatrunc=function(method){if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1));}else{if(typeof method==="object"||!method){return methods.init.apply(this,arguments);}else{$.error("Method "+method+" does not exist on jQuery.badonkatrunc");}}};$.fn.badonkatrunc.settings={sizeTrackingTimeout:1000/60};$.fn.badonkatrunc.defaultOptions={automaticSizeTracking:false,fitDirection:"horizontal",minimumFontSize:1,maximumFontSize:1,fontSizeSynced:false,minimumLetterSpacing:0,maximumLetterSpacing:0,letterSpacingSynced:false,truncate:true,truncateString:"…",truncateLocation:"end",truncateOnlyWholeWords:false,extraOptimizeLimit:8};$.fn.btrunc=$.fn.badonkatrunc;var pluginInstance=function($target,options,$targetGroup){var createRenderState=function(content,fontSize,letterSpacing){return{content:content,fontSize:fontSize,letterSpacing:letterSpacing};};var instance={target:$target,options:options,refresh:function(){var self=this;var view=createHtmlTextView(this.contentHtml);var text=this.contentHtml;var fontSize=this.options.maximumFontSize;var letterSpacing=this.options.maximumLetterSpacing;var renderFunc=function(){var state=createRenderState(text,fontSize,letterSpacing);self.renderState(state);};var overflowFunc=function(){return self.getCurrentOverflow();};if(this.options.maximumFontSize-this.options.minimumFontSize>0){optimize(self.options.minimumFontSize,self.options.maximumFontSize,function(value){fontSize=value;renderFunc();},overflowFunc);}if(this.options.maximumLetterSpacing-this.options.minimumLetterSpacing>0){var truncationLevel=1;if(this.options.truncate){optimize(0,1,function(value){truncationLevel=value;text=getTruncatedHtml(view,self.options.truncateString,self.options.truncateLocation,value,true);optimize(self.options.minimumLetterSpacing,0,function(value){letterSpacing=value;renderFunc();},overflowFunc);renderFunc();},overflowFunc);}if(truncationLevel==1){optimize(self.options.minimumLetterSpacing,self.options.maximumLetterSpacing,function(value){letterSpacing=value;renderFunc();},overflowFunc);}}if(this.options.truncate){optimize(0,1,function(value){text=getTruncatedHtml(view,self.options.truncateString,self.options.truncateLocation,value,self.options.truncateOnlyWholeWords);renderFunc();},overflowFunc,this.options.extraOptimizeLimit);}this.renderState(createRenderState(text,fontSize,letterSpacing),!this.options.truncate);this.currentOptimalState=this.currentRenderedState;this.syncFonts();},syncFonts:function(){if($targetGroup.length>1&&(this.options.fontSizeSynced||this.options.letterSpacingSynced)){var lowestFontSize=this.currentOptimalState.fontSize;var lowestLetterSpacing=this.currentOptimalState.letterSpacing;for(var i=0;i<$targetGroup.length;i++){var groupInstance=$($targetGroup[i]).data("badonkatrunc");if(groupInstance!=null&&groupInstance.currentOptimalState!=null){if(groupInstance.currentOptimalState.fontSize');this.settingsWrapper.addClass("badonkatrunc-wrapper");if(!$.browser.mozilla&&!$.browser.opera&&!($.browser.msie&&$.browser.version=="7.0")){this.settingsWrapper.css("display","block");}this.target.empty();this.target.append(this.settingsWrapper);this.refresh();},destroy:function(){this.target.empty();this.target.append(this.contentHtml);},renderState:function(state,forceAllowWrap){this.settingsWrapper.css("font-size",state.fontSize+"em");this.settingsWrapper.css("letter-spacing",state.letterSpacing+"em");var whiteSpace=(!forceAllowWrap&&this.options.fitDirection=="horizontal")?"nowrap":"normal";this.settingsWrapper.css("white-space",whiteSpace);this.settingsWrapper.empty();this.settingsWrapper.append(state.content);this.currentRenderedState=state;},getCurrentOverflow:function(){var wrapper=this.settingsWrapper[0];var overflow=(this.options.fitDirection=="horizontal")?wrapper.scrollWidth-$target.width():wrapper.offsetHeight-$target.height();return overflow;}};return instance;};var createDispatcher=function(updateFunc,addFunc,removeFunc,updateTimeout){var dispatcherInstance={_instances:[],_updateLoop:function(){if($.isFunction(updateFunc)){for(var i=0;i0){setTimeout(dispatcherInstance._updateLoop,updateTimeout);}}else{dispatcherInstance._instances=[];}},add:function(instance){if($.inArray(instance,this._instances)!=-1){return;}if($.isFunction(addFunc)){addFunc(instance);}this._instances.push(instance);if(this._instances.length==1){if(updateTimeout==null){setTimeout(this._updateLoop);}else{this._updateLoop();}}},remove:function(instance){var index=$.inArray(instance,this._instances);if(index!=-1){this._instances.splice(index,1);if($.isFunction(removeFunc)){removeFunc(instance);}}}};return dispatcherInstance;};var resizeMonitor=createDispatcher(function(instance){instance.elementSizeCache.update();},function(instance){instance.elementSizeCache={width:null,height:null,update:function(){var newWidth=instance.target.width();var newHeight=instance.target.height();var hasChanged=((this.width!=null&&newWidth!=this.width)||(this.height!=null&&newHeight!=this.height));this.width=newWidth;this.height=newHeight;if(hasChanged){this.changed();}},changed:function(){dirtyMonitor.add(instance);}};},function(instance){instance.elementSizeCache=undefined;},$.fn.badonkatrunc.settings.sizeTrackingTimeout);var dirtyMonitor=createDispatcher(function(instance){instance.refresh.apply(instance);},null,null,null);var getTruncatedHtml=function(htmlTextView,truncateString,truncateLocation,amount,wordRounded){var text=htmlTextView.text;if(amount>1){amount=1;}if(amount<0){amount=0;}if(amount==1){return htmlTextView.html;}var getTruncatedRange=function(begin,length){var words=text.split(" ");var totalEntities=(wordRounded)?words.length:text.length;var entityBegin=totalEntities*begin;var entityLength=totalEntities*length;if(wordRounded){var getCharacterPosition=function(wordIndex){var characterCount=0;for(var i=0;i");$content.html(contentHtml);var view={html:contentHtml,text:$content.text(),getHtmlSubstring:function(index,length){var element=$content.clone()[0];var totalProcessedLength=0;var totalOutputLength=0;var nodesWithinRange=[];var withinRange=false;var stripOutOfRangeTextInElement=function(node){if(node.nodeType==3){var dataLength=node.data.length;var newData="";var wasWithinRange=false;for(var i=0;i=index&&totalOutputLengthresult){moreOptimal=false;}else{if(result==mostOptimalResult){if(currentValue<=mostOptimalValue){moreOptimal=false;}}}}if(moreOptimal){mostOptimalResult=result;mostOptimalValue=currentValue;}}if(result==lastResult){sameResultCount++;if(extraOptimizeLimit==undefined||sameResultCount==extraOptimizeLimit){if(mostOptimalValue!=null){actionFunc(mostOptimalValue);}return;}}if(result>0){currentMax=currentValue;var difference=(currentValue-currentMin);currentValue-=(difference/2);}else{if(result<=0){currentMin=currentValue;currentValue=currentMax;}}lastResult=result;}};})(jQuery);