From 1c30fc97c3e6d584ab6fa5cdd566fd28e37e577b Mon Sep 17 00:00:00 2001 From: Patrick Fisher Date: Tue, 25 Oct 2016 18:52:44 -0700 Subject: [PATCH] Binary search for performance --- dist/shave.js | 28 ++++++++++++++++++---------- src/shave.js | 29 +++++++++++++++++++---------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/dist/shave.js b/dist/shave.js index 422a64f4..03178807 100644 --- a/dist/shave.js +++ b/dist/shave.js @@ -32,22 +32,30 @@ function shave(target, maxHeight, opts) { if (el.offsetHeight < maxHeight) break; var fullText = el.textContent; - var trimmedText = fullText; - var lastSpace = void 0; - - do { - lastSpace = trimmedText.lastIndexOf(' '); - if (lastSpace < 0) break; // single word is too tall, do nothing - trimmedText = trimmedText.slice(0, lastSpace); - el.textContent = trimmedText; + var words = fullText.split(' '); + + // If 0 or 1 words, we're done + if (words.length < 2) break; + + // Binary search for number of words which can fit in allotted height + var max = words.length - 1; + var min = 0; + var pivot = void 0; + while (min < max) { + pivot = (min + max + 1) >> 1; + el.textContent = words.slice(0, pivot).join(' '); el.insertAdjacentHTML('beforeend', charHtml); - } while (el.offsetHeight > maxHeight); + if (el.offsetHeight > maxHeight) max = pivot - 1;else min = pivot; + } - var diff = fullText.slice(lastSpace); + el.textContent = words.slice(0, max).join(' '); + el.insertAdjacentHTML('beforeend', charHtml); + var diff = words.slice(max + 1).join(' '); el.insertAdjacentHTML('beforeend', ''); } } + var plugin = window.$ || window.jQuery || window.Zepto; if (plugin) { plugin.fn.extend({ diff --git a/src/shave.js b/src/shave.js index f7ce5f72..dac72f09 100644 --- a/src/shave.js +++ b/src/shave.js @@ -27,23 +27,32 @@ export default function shave(target, maxHeight, opts) { if (el.offsetHeight < maxHeight) break; const fullText = el.textContent; - let trimmedText = fullText; - let lastSpace; - - do { - lastSpace = trimmedText.lastIndexOf(' '); - if (lastSpace < 0) break; // single word is too tall, do nothing - trimmedText = trimmedText.slice(0, lastSpace); - el.textContent = trimmedText; + const words = fullText.split(' '); + + // If 0 or 1 words, we're done + if (words.length < 2) break; + + // Binary search for number of words which can fit in allotted height + let max = words.length - 1; + let min = 0; + let pivot; + while (min < max) { + pivot = (min + max + 1) >> 1; + el.textContent = words.slice(0, pivot).join(' '); el.insertAdjacentHTML('beforeend', charHtml); - } while (el.offsetHeight > maxHeight); + if (el.offsetHeight > maxHeight) max = pivot - 1; + else min = pivot; + } - const diff = fullText.slice(lastSpace); + el.textContent = words.slice(0, max).join(' '); + el.insertAdjacentHTML('beforeend', charHtml); + const diff = words.slice(max + 1).join(' '); el.insertAdjacentHTML('beforeend', ``); } } + const plugin = window.$ || window.jQuery || window.Zepto; if (plugin) { plugin.fn.extend({