diff --git a/src/angular-ellipsis.js b/src/angular-ellipsis.js
index 1c5eb12..b7fd512 100644
--- a/src/angular-ellipsis.js
+++ b/src/angular-ellipsis.js
@@ -130,26 +130,15 @@ angular.module('dibari.angular-ellipsis', [])
//Set data-overflow on element for targeting
element.attr('data-overflowed', 'true');
- // Set complete text and remove one word at a time, until there is no overflow
- for (; i < bindArrayStartingLength; i++) {
- var current = bindArray.pop();
-
- //if the last string still overflowed, then truncate the last string
- if (bindArray.length === 0) {
- bindArray[0] = current.substring(0, Math.min(current.length, 5));
- }
-
- if (isHtml) {
- element.html(bindArray.join(ellipsisSeparator) + appendString);
- } else {
- element.text(bindArray.join(ellipsisSeparator)).html(element.html() + appendString);
- }
-
- if ((scope.useParent ? element.parent()[0] : element[0]).scrollHeight < initialMaxHeight || isOverflowed(element, scope.useParent) === false) {
- attributes.isTruncated = true;
- break;
- }
- }
+ const leastUpperBound = calculateLeastUpperBound(element, bindArray, ellipsisSeparator, appendString, isHtml, scope, initialMaxHeight);
+
+ if (isHtml) {
+ element.html(bindArray.slice(0, leastUpperBound).join(ellipsisSeparator) + appendString);
+ } else {
+ element.text(bindArray.slice(0, leastUpperBound).join(ellipsisSeparator)).html(element.html() + appendString);
+ }
+
+ attributes.isTruncated = true;
// If append string was passed and append click function included
if (ellipsisSymbol != appendString && typeof(scope.ellipsisAppendClick) !== 'undefined' && scope.ellipsisAppendClick !== '') {
@@ -186,6 +175,40 @@ angular.module('dibari.angular-ellipsis', [])
return thisElement[0].scrollHeight > thisElement[0].clientHeight;
}
+ function doesItFit(guess, element, bindArray, ellipsisSeparator, appendString, isHtml, scope, initialMaxHeight){
+ if (isHtml) {
+ element.html(bindArray.slice(0, guess).join(ellipsisSeparator) + appendString);
+ } else {
+ element.text(bindArray.slice(0, guess).join(ellipsisSeparator)).html(element.html() + appendString);
+ }
+
+ return ((scope.useParent ? element.parent()[0] : element[0]).scrollHeight < initialMaxHeight || isOverflowed(element, scope.useParent) === false);
+ }
+
+ function calculateLeastUpperBound(element, bindArray, ellipsisSeparator, appendString, isHtml, scope, initialMaxHeight){
+ var upperBound = bindArray.length;
+ var lowerBound = 0;
+
+ if(doesItFit(upperBound, element, bindArray, ellipsisSeparator, appendString, isHtml, scope, initialMaxHeight)){
+ lowerBound = upperBound;
+ } else {
+ while(true){
+ currentGuess = Math.floor((upperBound + lowerBound) / 2);
+ if(doesItFit(currentGuess, element, bindArray, ellipsisSeparator, appendString, isHtml, scope, initialMaxHeight)){
+ lowerBound = currentGuess;
+ } else {
+ upperBound = currentGuess;
+ }
+
+ if((upperBound - lowerBound) <= 1){
+ break;
+ }
+ }
+ }
+
+ return lowerBound;
+ }
+
/**
* Watchers
*/
diff --git a/src/angular-ellipsis.min.js b/src/angular-ellipsis.min.js
index e0d1fcb..0d78950 100644
--- a/src/angular-ellipsis.min.js
+++ b/src/angular-ellipsis.min.js
@@ -1 +1 @@
-angular.module("dibari.angular-ellipsis",[]).directive("ellipsis",["$timeout","$window","$sce",function(a,b,c){var d=function(b){var c=null,d=[];this.remove=function(b){-1!==d.indexOf(b)&&(d.splice(d.indexOf(b),1),0===d.length&&(a.cancel(c),c=null))},this.add=function(e){-1===d.indexOf(e)&&d.push(e),c||(c=a(function(){var a=d.slice();c=null,d.length=0,a.forEach(function(a){a()})},b))}},e=new d(0),f=new d(75);return{restrict:"A",scope:{ngBind:"=",ngBindHtml:"=",ellipsisAppend:"@",ellipsisAppendClick:"&",ellipsisSymbol:"@",ellipsisSeparator:"@",useParent:"@",ellipsisSeparatorReg:"="},compile:function(a,d,g){return function(a,d,g){function h(a){var b=0;return angular.forEach(a.parent().children(),function(c){c!=a[0]&&(b+=c.clientHeight)}),a.parent()[0].clientHeight-b}function i(){var b=a.ngBind||a.ngBindHtml,e=!1;if(c.isEnabled()&&angular.isObject(b)&&c.getTrustedHtml(b)&&(e=!0,b=c.getTrustedHtml(b)),b){var f=!a.ngBind&&!!a.ngBindHtml,i=0,k="undefined"!=typeof g.ellipsisSymbol?g.ellipsisSymbol:"…",l="undefined"!=typeof a.ellipsisSeparator?g.ellipsisSeparator:" ",m="undefined"!=typeof a.ellipsisSeparatorReg?a.ellipsisSeparatorReg:!1,n="undefined"!=typeof a.ellipsisAppend&&""!==a.ellipsisAppend?k+""+a.ellipsisAppend+"":k,o=m?b.match(m):b.split(l);if(g.isTruncated=!1,f?d.html(b):d.text(b),j(d,a.useParent)){var p=o.length,q=a.useParent?h(d):d[0].clientHeight;for(f?d.html(b+n):d.text(b).html(d.html()+n),d.attr("data-overflowed","true");p>i;i++)if(o.pop(),f?d.html(o.join(l)+n):d.text(o.join(l)).html(d.html()+n),(a.useParent?d.parent()[0]:d[0]).scrollHeighta[0].clientHeight}function k(){(g.lastWindowResizeWidth!=window.innerWidth||g.lastWindowResizeHeight!=window.innerHeight)&&i(),g.lastWindowResizeWidth=window.innerWidth,g.lastWindowResizeHeight=window.innerHeight}function l(){f.add(k)}g.lastWindowResizeTime=0,g.lastWindowResizeWidth=0,g.lastWindowResizeHeight=0,g.lastWindowTimeoutEvent=null,g.isTruncated=!1,a.$watch("ngBind",function(){e.add(i)}),a.$watch("ngBindHtml",function(){e.add(i)}),a.$watch("ellipsisAppend",function(){i()});var m=angular.element(b);m.bind("resize",l),a.$on("$destroy",function(){m.unbind("resize",l),e.remove(i),f.remove(k)})}}}}]);
\ No newline at end of file
+angular.module("dibari.angular-ellipsis",[]).directive("ellipsis",["$timeout","$window","$sce",function(a,b,c){var d=function(b){var c=null,d=[];this.remove=function(b){d.indexOf(b)!==-1&&(d.splice(d.indexOf(b),1),0===d.length&&(a.cancel(c),c=null))},this.add=function(e){d.indexOf(e)===-1&&d.push(e),c||(c=a(function(){var a=d.slice();c=null,d.length=0,a.forEach(function(a){a()})},b))}},e=new d(0),f=new d(75);return{restrict:"A",scope:{ngShow:"=",ngBind:"=",ngBindHtml:"=",ellipsisAppend:"@",ellipsisAppendClick:"&",ellipsisSymbol:"@",ellipsisSeparator:"@",useParent:"@",ellipsisSeparatorReg:"=",ellipsisFallbackFontSize:"@"},compile:function(a,d,g){return function(a,d,g){function h(a){return"undefined"!=typeof a}function i(a){var b=0;return angular.forEach(a.parent().children(),function(c){c!=a[0]&&(b+=c.clientHeight)}),a.parent()[0].clientHeight-b}function j(){var b=a.ngBind||a.ngBindHtml,e=!1;if(c.isEnabled()&&angular.isObject(b)&&c.getTrustedHtml(b)&&(e=!0,b=c.getTrustedHtml(b)),b){var f=!a.ngBind&&!!a.ngBindHtml,l="undefined"!=typeof g.ellipsisSymbol?g.ellipsisSymbol:"…",n="undefined"!=typeof a.ellipsisSeparator?g.ellipsisSeparator:" ",o="undefined"!=typeof a.ellipsisSeparatorReg&&a.ellipsisSeparatorReg,p="undefined"!=typeof a.ellipsisAppend&&""!==a.ellipsisAppend?l+""+a.ellipsisAppend+"":l,q=o?b.match(o):b.split(n);if(g.isTruncated=!1,f?d.html(b):d.text(b),h(g.ellipsisFallbackFontSize)&&k(d)&&d.css("font-size",g.ellipsisFallbackFontSize),k(d,a.useParent)){var s=(q.length,a.useParent?i(d):d[0].clientHeight);f?d.html(b+p):d.text(b).html(d.html()+p),d.attr("data-overflowed","true");const t=m(d,q,n,p,f,a,s);f?d.html(q.slice(0,t).join(n)+p):d.text(q.slice(0,t).join(n)).html(d.html()+p),g.isTruncated=!0,l!=p&&"undefined"!=typeof a.ellipsisAppendClick&&""!==a.ellipsisAppendClick&&d.find("span.angular-ellipsis-append").bind("click",function(b){a.$apply(function(){a.ellipsisAppendClick.call(a,{event:b})})}),!e&&c.isEnabled()&&c.trustAsHtml(b)}else d.attr("data-overflowed","false")}}function k(a,b){return a=b?a.parent():a,a[0].scrollHeight>a[0].clientHeight}function l(a,b,c,d,e,f,g,h){return f?b.html(c.slice(0,a).join(d)+e):b.text(c.slice(0,a).join(d)).html(b.html()+e),(g.useParent?b.parent()[0]:b[0]).scrollHeight