Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fitty

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fitty - npm Package Compare versions

Comparing version 2.3.4 to 2.3.5

2

dist/fitty.min.js
/**
* 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 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc