mirror of https://github.com/zulip/zulip.git
js: Implement DynamicText class.
This implements the DynamicText class for resizing of text to fit the parent node.
This commit is contained in:
parent
0ce04556bf
commit
6e7305f784
|
@ -16,6 +16,7 @@
|
||||||
"marked": false,
|
"marked": false,
|
||||||
"moment": false,
|
"moment": false,
|
||||||
"i18n": false,
|
"i18n": false,
|
||||||
|
"DynamicText": false,
|
||||||
"bridge": false,
|
"bridge": false,
|
||||||
"page_params": false,
|
"page_params": false,
|
||||||
"status_classes": false,
|
"status_classes": false,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -854,6 +854,7 @@ JS_SPECS = {
|
||||||
'js/feature_flags.js',
|
'js/feature_flags.js',
|
||||||
'js/loading.js',
|
'js/loading.js',
|
||||||
'js/util.js',
|
'js/util.js',
|
||||||
|
'js/dynamic_text.js',
|
||||||
'js/rtl.js',
|
'js/rtl.js',
|
||||||
'js/dict.js',
|
'js/dict.js',
|
||||||
'js/components.js',
|
'js/components.js',
|
||||||
|
|
Loading…
Reference in New Issue