Comparing version 2.3.4 to 2.3.5
/** | ||
* fitty v2.3.4 - Snugly resizes text to fit its parent container | ||
* fitty v2.3.5 - Snugly resizes text to fit its parent container | ||
* Copyright (c) 2021 Rik Schennink <rik@pqina.nl> (https://pqina.nl/) | ||
@@ -4,0 +4,0 @@ */ |
/** | ||
* fitty v2.3.4 - Snugly resizes text to fit its parent container | ||
* fitty v2.3.5 - Snugly resizes text to fit its parent container | ||
* Copyright (c) 2021 Rik Schennink <rik@pqina.nl> (https://pqina.nl/) | ||
*/ | ||
var fitty = (function (w) { | ||
// no window, early exit | ||
if (!w) return; // node list to array helper method | ||
var toArray = function toArray(nl) { | ||
return [].slice.call(nl); | ||
}; // states | ||
var DrawState = { | ||
IDLE: 0, | ||
DIRTY_CONTENT: 1, | ||
DIRTY_LAYOUT: 2, | ||
DIRTY: 3 | ||
}; // all active fitty elements | ||
var fitties = []; // group all redraw calls till next frame, we cancel each frame request when a new one comes in. If no support for request animation frame, this is an empty function and supports for fitty stops. | ||
var redrawFrame = null; | ||
var requestRedraw = 'requestAnimationFrame' in w ? function () { | ||
w.cancelAnimationFrame(redrawFrame); | ||
redrawFrame = w.requestAnimationFrame(function () { | ||
return redraw(fitties.filter(function (f) { | ||
return f.dirty && f.active; | ||
})); | ||
}); | ||
} : function () {}; // sets all fitties to dirty so they are redrawn on the next redraw loop, then calls redraw | ||
var redrawAll = function redrawAll(type) { | ||
return function () { | ||
fitties.forEach(function (f) { | ||
return f.dirty = type; | ||
}); | ||
requestRedraw(); | ||
}; | ||
}; // redraws fitties so they nicely fit their parent container | ||
var redraw = function redraw(fitties) { | ||
// getting info from the DOM at this point should not trigger a reflow, let's gather as much intel as possible before triggering a reflow | ||
// check if styles of all fitties have been computed | ||
fitties.filter(function (f) { | ||
return !f.styleComputed; | ||
}).forEach(function (f) { | ||
f.styleComputed = computeStyle(f); | ||
}); // restyle elements that require pre-styling, this triggers a reflow, please try to prevent by adding CSS rules (see docs) | ||
fitties.filter(shouldPreStyle).forEach(applyStyle); // we now determine which fitties should be redrawn | ||
var fittiesToRedraw = fitties.filter(shouldRedraw); // we calculate final styles for these fitties | ||
fittiesToRedraw.forEach(calculateStyles); // now we apply the calculated styles from our previous loop | ||
fittiesToRedraw.forEach(function (f) { | ||
applyStyle(f); | ||
markAsClean(f); | ||
}); // now we dispatch events for all restyled fitties | ||
fittiesToRedraw.forEach(dispatchFitEvent); | ||
}; | ||
var markAsClean = function markAsClean(f) { | ||
return f.dirty = DrawState.IDLE; | ||
}; | ||
var calculateStyles = function calculateStyles(f) { | ||
// get available width from parent node | ||
f.availableWidth = f.element.parentNode.clientWidth; // the space our target element uses | ||
f.currentWidth = f.element.scrollWidth; // remember current font size | ||
f.previousFontSize = f.currentFontSize; // let's calculate the new font size | ||
f.currentFontSize = Math.min(Math.max(f.minSize, f.availableWidth / f.currentWidth * f.previousFontSize), f.maxSize); // if allows wrapping, only wrap when at minimum font size (otherwise would break container) | ||
f.whiteSpace = f.multiLine && f.currentFontSize === f.minSize ? 'normal' : 'nowrap'; | ||
}; // should always redraw if is not dirty layout, if is dirty layout, only redraw if size has changed | ||
var shouldRedraw = function shouldRedraw(f) { | ||
return f.dirty !== DrawState.DIRTY_LAYOUT || f.dirty === DrawState.DIRTY_LAYOUT && f.element.parentNode.clientWidth !== f.availableWidth; | ||
}; // every fitty element is tested for invalid styles | ||
var computeStyle = function computeStyle(f) { | ||
// get style properties | ||
var style = w.getComputedStyle(f.element, null); // get current font size in pixels (if we already calculated it, use the calculated version) | ||
f.currentFontSize = parseFloat(style.getPropertyValue('font-size')); // get display type and wrap mode | ||
f.display = style.getPropertyValue('display'); | ||
f.whiteSpace = style.getPropertyValue('white-space'); // styles computed | ||
return true; | ||
}; // determines if this fitty requires initial styling, can be prevented by applying correct styles through CSS | ||
var shouldPreStyle = function shouldPreStyle(f) { | ||
var preStyle = false; // if we already tested for prestyling we don't have to do it again | ||
if (f.preStyleTestCompleted) return false; // should have an inline style, if not, apply | ||
if (!/inline-/.test(f.display)) { | ||
preStyle = true; | ||
f.display = 'inline-block'; | ||
} // to correctly calculate dimensions the element should have whiteSpace set to nowrap | ||
if (f.whiteSpace !== 'nowrap') { | ||
preStyle = true; | ||
f.whiteSpace = 'nowrap'; | ||
} // we don't have to do this twice | ||
f.preStyleTestCompleted = true; | ||
return preStyle; | ||
}; // apply styles to single fitty | ||
var applyStyle = function applyStyle(f) { | ||
f.element.style.whiteSpace = f.whiteSpace; | ||
f.element.style.display = f.display; | ||
f.element.style.fontSize = f.currentFontSize + 'px'; | ||
}; // dispatch a fit event on a fitty | ||
var dispatchFitEvent = function dispatchFitEvent(f) { | ||
f.element.dispatchEvent(new CustomEvent('fit', { | ||
detail: { | ||
oldValue: f.previousFontSize, | ||
newValue: f.currentFontSize, | ||
scaleFactor: f.currentFontSize / f.previousFontSize | ||
} | ||
})); | ||
}; // fit method, marks the fitty as dirty and requests a redraw (this will also redraw any other fitty marked as dirty) | ||
var fit = function fit(f, type) { | ||
return function () { | ||
f.dirty = type; | ||
if (!f.active) return; | ||
requestRedraw(); | ||
}; | ||
}; | ||
var init = function init(f) { | ||
// save some of the original CSS properties before we change them | ||
f.originalStyle = { | ||
whiteSpace: f.element.style.whiteSpace, | ||
display: f.element.style.display, | ||
fontSize: f.element.style.fontSize | ||
}; // should we observe DOM mutations | ||
observeMutations(f); // this is a new fitty so we need to validate if it's styles are in order | ||
f.newbie = true; // because it's a new fitty it should also be dirty, we want it to redraw on the first loop | ||
f.dirty = true; // we want to be able to update this fitty | ||
fitties.push(f); | ||
}; | ||
var destroy = function destroy(f) { | ||
return function () { | ||
// remove from fitties array | ||
fitties = fitties.filter(function (_) { | ||
return _.element !== f.element; | ||
}); // stop observing DOM | ||
if (f.observeMutations) f.observer.disconnect(); // reset the CSS properties we changes | ||
f.element.style.whiteSpace = f.originalStyle.whiteSpace; | ||
f.element.style.display = f.originalStyle.display; | ||
f.element.style.fontSize = f.originalStyle.fontSize; | ||
}; | ||
}; // add a new fitty, does not redraw said fitty | ||
var subscribe = function subscribe(f) { | ||
return function () { | ||
if (f.active) return; | ||
f.active = true; | ||
requestRedraw(); | ||
}; | ||
}; // remove an existing fitty | ||
var unsubscribe = function unsubscribe(f) { | ||
return function () { | ||
return f.active = false; | ||
}; | ||
}; | ||
var observeMutations = function observeMutations(f) { | ||
// no observing? | ||
if (!f.observeMutations) return; // start observing mutations | ||
f.observer = new MutationObserver(fit(f, DrawState.DIRTY_CONTENT)); // start observing | ||
f.observer.observe(f.element, f.observeMutations); | ||
}; // default mutation observer settings | ||
var mutationObserverDefaultSetting = { | ||
subtree: true, | ||
childList: true, | ||
characterData: true | ||
}; // default fitty options | ||
var defaultOptions = { | ||
minSize: 16, | ||
maxSize: 512, | ||
multiLine: true, | ||
observeMutations: 'MutationObserver' in w ? mutationObserverDefaultSetting : false | ||
}; // array of elements in, fitty instances out | ||
function fittyCreate(elements, options) { | ||
// set options object | ||
var fittyOptions = Object.assign({}, // expand default options | ||
defaultOptions, // override with custom options | ||
options); // create fitties | ||
var publicFitties = elements.map(function (element) { | ||
// create fitty instance | ||
var f = Object.assign({}, fittyOptions, { | ||
// internal options for this fitty | ||
element: element, | ||
active: true | ||
}); // initialise this fitty | ||
init(f); // expose API | ||
return { | ||
element: element, | ||
fit: fit(f, DrawState.DIRTY), | ||
unfreeze: subscribe(f), | ||
freeze: unsubscribe(f), | ||
unsubscribe: destroy(f) | ||
}; | ||
}); // call redraw on newly initiated fitties | ||
requestRedraw(); // expose fitties | ||
return publicFitties; | ||
} // fitty creation function | ||
function fitty(target) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
// if target is a string | ||
return typeof target === 'string' ? // treat it as a querySelector | ||
fittyCreate(toArray(document.querySelectorAll(target)), options) : // create single fitty | ||
fittyCreate([target], options)[0]; | ||
} // handles viewport changes, redraws all fitties, but only does so after a timeout | ||
var resizeDebounce = null; | ||
var onWindowResized = function onWindowResized() { | ||
w.clearTimeout(resizeDebounce); | ||
resizeDebounce = w.setTimeout(redrawAll(DrawState.DIRTY_LAYOUT), fitty.observeWindowDelay); | ||
}; // define observe window property, so when we set it to true or false events are automatically added and removed | ||
var events = ['resize', 'orientationchange']; | ||
Object.defineProperty(fitty, 'observeWindow', { | ||
set: function set(enabled) { | ||
var method = "".concat(enabled ? 'add' : 'remove', "EventListener"); | ||
events.forEach(function (e) { | ||
w[method](e, onWindowResized); | ||
}); | ||
} | ||
}); // fitty global properties (by setting observeWindow to true the events above get added) | ||
fitty.observeWindow = true; | ||
fitty.observeWindowDelay = 100; // public fit all method, will force redraw no matter what | ||
fitty.fitAll = redrawAll(DrawState.DIRTY); // export our fitty function, we don't want to keep it to our selves | ||
return fitty; | ||
})(typeof window === 'undefined' ? null : window); | ||
export default fitty; | ||
var e=function(e){if(e){var t=function(e){return[].slice.call(e)},n=0,i=1,r=2,o=3,a=[],l=null,u="requestAnimationFrame"in e?function(){e.cancelAnimationFrame(l),l=e.requestAnimationFrame((function(){return s(a.filter((function(e){return e.dirty&&e.active})))}))}:function(){},c=function(e){return function(){a.forEach((function(t){return t.dirty=e})),u()}},s=function(e){e.filter((function(e){return!e.styleComputed})).forEach((function(e){e.styleComputed=m(e)})),e.filter(y).forEach(v);var t=e.filter(p);t.forEach(d),t.forEach((function(e){v(e),f(e)})),t.forEach(S)},f=function(e){return e.dirty=n},d=function(e){e.availableWidth=e.element.parentNode.clientWidth,e.currentWidth=e.element.scrollWidth,e.previousFontSize=e.currentFontSize,e.currentFontSize=Math.min(Math.max(e.minSize,e.availableWidth/e.currentWidth*e.previousFontSize),e.maxSize),e.whiteSpace=e.multiLine&&e.currentFontSize===e.minSize?"normal":"nowrap"},p=function(e){return e.dirty!==r||e.dirty===r&&e.element.parentNode.clientWidth!==e.availableWidth},m=function(t){var n=e.getComputedStyle(t.element,null);return t.currentFontSize=parseFloat(n.getPropertyValue("font-size")),t.display=n.getPropertyValue("display"),t.whiteSpace=n.getPropertyValue("white-space"),!0},y=function(e){var t=!1;return!e.preStyleTestCompleted&&(/inline-/.test(e.display)||(t=!0,e.display="inline-block"),"nowrap"!==e.whiteSpace&&(t=!0,e.whiteSpace="nowrap"),e.preStyleTestCompleted=!0,t)},v=function(e){e.element.style.whiteSpace=e.whiteSpace,e.element.style.display=e.display,e.element.style.fontSize=e.currentFontSize+"px"},S=function(e){e.element.dispatchEvent(new CustomEvent("fit",{detail:{oldValue:e.previousFontSize,newValue:e.currentFontSize,scaleFactor:e.currentFontSize/e.previousFontSize}}))},h=function(e,t){return function(){e.dirty=t,e.active&&u()}},w=function(e){return function(){a=a.filter((function(t){return t.element!==e.element})),e.observeMutations&&e.observer.disconnect(),e.element.style.whiteSpace=e.originalStyle.whiteSpace,e.element.style.display=e.originalStyle.display,e.element.style.fontSize=e.originalStyle.fontSize}},b=function(e){return function(){e.active||(e.active=!0,u())}},z=function(e){return function(){return e.active=!1}},F=function(e){e.observeMutations&&(e.observer=new MutationObserver(h(e,i)),e.observer.observe(e.element,e.observeMutations))},g={minSize:16,maxSize:512,multiLine:!0,observeMutations:"MutationObserver"in e&&{subtree:!0,childList:!0,characterData:!0}},W=null,E=function(){e.clearTimeout(W),W=e.setTimeout(c(r),x.observeWindowDelay)},M=["resize","orientationchange"];return Object.defineProperty(x,"observeWindow",{set:function(t){var n="".concat(t?"add":"remove","EventListener");M.forEach((function(t){e[n](t,E)}))}}),x.observeWindow=!0,x.observeWindowDelay=100,x.fitAll=c(o),x}function C(e,t){var n=Object.assign({},g,t),i=e.map((function(e){var t=Object.assign({},n,{element:e,active:!0});return function(e){e.originalStyle={whiteSpace:e.element.style.whiteSpace,display:e.element.style.display,fontSize:e.element.style.fontSize},F(e),e.newbie=!0,e.dirty=!0,a.push(e)}(t),{element:e,fit:h(t,o),unfreeze:b(t),freeze:z(t),unsubscribe:w(t)}}));return u(),i}function x(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e?C(t(document.querySelectorAll(e)),n):C([e],n)[0]}}("undefined"==typeof window?null:window);export default e; |
{ | ||
"name": "fitty", | ||
"version": "2.3.4", | ||
"version": "2.3.5", | ||
"description": "Snugly resizes text to fit its parent container", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -26,2 +26,3 @@ import { babel } from '@rollup/plugin-babel'; | ||
sourcemap: false, | ||
plugins: isProduction ? [terser()] : [], | ||
file: 'dist/fitty.module.js', | ||
@@ -33,3 +34,3 @@ }, | ||
name: 'fitty', | ||
plugins: [terser()], | ||
plugins: isProduction ? [terser()] : [], | ||
file: 'dist/fitty.min.js', | ||
@@ -36,0 +37,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
3
22494
99