Skip to content

Commit

Permalink
js: Implement DynamicText class.
Browse files Browse the repository at this point in the history
This implements the DynamicText class for resizing of text to fit the
parent node.
  • Loading branch information
Brock Whittaker authored and timabbott committed May 12, 2017
1 parent 0ce0455 commit 6e7305f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"marked": false,
"moment": false,
"i18n": false,
"DynamicText": false,
"bridge": false,
"page_params": false,
"status_classes": false,
Expand Down
97 changes: 97 additions & 0 deletions static/js/dynamic_text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// This is a public instance of the `DynamicText` class.
// The `DynamicText` object serves to resize text that is set through its
// public methods so that the text won't ever overrun the parent container.
var DynamicText = (function () {
// the initialization of the `DynamicText` instance.
var DynamicText = function ($parent) {
if (typeof jQuery !== "undefined" && $parent instanceof jQuery) {
// we grab the first element in a jQuery list to run DynamicText on.
this.parent = $parent[0];
} else if ($parent instanceof Node) {
// this is a node rather than a list, so we just take the element given
// to run DynamicText on.
this.parent = $parent;
}

this.node = document.createElement("span");
this.node.style.whiteSpace = "nowrap";

this.prev_content = this.parent.innerHTML;
this.parent.innerHTML = "";
this.parent.appendChild(this.node);

this.update();
};

// an object for private functions that are inaccessible to the outside
// world.
var internal_funcs = {
insertText: function (type, text, node, parent) {
if (type === DynamicText.prototype.TYPE.TEXT) {
node.innerText = text;
} else if (type === DynamicText.prototype.TYPE.HTML) {
node.innerHTML = text;
} else {
blueslip.error("The method '" + type + "' is not a valid " +
" DynamicText input method.");
}

// reset the font-size to inherit the parent's size; 1em.
node.style.fontSize = "1em";

var width = {
node: node.offsetWidth,
parent: parent.clientWidth,
};

// if the width is larger than the parent, resize by the ratio of
// the parent's width to the node's width.
if (width.node > width.parent) {
node.style.fontSize = (width.parent / width.node) + "em";
} else {
node.style.fontSize = "1em";
}
},
};

DynamicText.prototype = {
// insertion enum types.
TYPE: {
TEXT: 1,
HTML: 2,
},

// re-set the content inside the span element and process for width.
// the structure goes like:
// FROM: <parent>content</parent>
// TO: <parent>
// <span style="font-size: {{ value }}">content</span>
// </parent>
update: function () {
// call `text` by default since if HTML is needed (unsafe), it can be
// done manually.
this.text(this.prev_content);
},

// this takes about 0.005ms for items that don't need resizing and 0.08ms
// for items that do need resizing.
text: function (text) {
internal_funcs.insertText(this.TYPE.TEXT, text, this.node, this.parent);
},

// this function takes approx 0.4ms/iteration.
// the speed is mostly limited to the slowness of the innerHTML function.
html: function (html) {
internal_funcs.insertText(this.TYPE.HTML, html, this.node, this.parent);
},
};

// keep these arguments updated with `DynamicText` class constructor.
return function ($node) {
return new DynamicText($node);
};
}());

if (typeof module !== 'undefined') {
module.exports = DynamicText;
}
1 change: 1 addition & 0 deletions zproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ def get_secret(key):
'js/feature_flags.js',
'js/loading.js',
'js/util.js',
'js/dynamic_text.js',
'js/rtl.js',
'js/dict.js',
'js/components.js',
Expand Down

0 comments on commit 6e7305f

Please sign in to comment.