whatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinbox
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
5.6 KiB
163 lines
5.6 KiB
9 years ago
|
/**
|
||
|
* Provides precise pixel measurements for blocks of text so that you can determine exactly how high and
|
||
|
* wide, in pixels, a given block of text will be. Note that when measuring text, it should be plain text and
|
||
|
* should not contain any HTML, otherwise it may not be measured correctly.
|
||
|
*
|
||
|
* The measurement works by copying the relevant CSS styles that can affect the font related display,
|
||
|
* then checking the size of an element that is auto-sized. Note that if the text is multi-lined, you must
|
||
|
* provide a **fixed width** when doing the measurement.
|
||
|
*
|
||
|
* If multiple measurements are being done on the same element, you create a new instance to initialize
|
||
|
* to avoid the overhead of copying the styles to the element repeatedly.
|
||
|
*/
|
||
|
Ext.define('Ext.util.TextMetrics', {
|
||
|
requires: [
|
||
|
'Ext.dom.Element'
|
||
|
],
|
||
|
|
||
|
statics: {
|
||
|
shared: null,
|
||
|
/**
|
||
|
* Measures the size of the specified text
|
||
|
* @param {String/HTMLElement} el The element, dom node or id from which to copy existing CSS styles
|
||
|
* that can affect the size of the rendered text
|
||
|
* @param {String} text The text to measure
|
||
|
* @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width
|
||
|
* in order to accurately measure the text height
|
||
|
* @return {Object} An object containing the text's size `{width: (width), height: (height)}`
|
||
|
* @static
|
||
|
*/
|
||
|
measure: function(el, text, fixedWidth){
|
||
|
var me = this,
|
||
|
shared = me.shared;
|
||
|
|
||
|
if(!shared){
|
||
|
shared = me.shared = new me(el, fixedWidth);
|
||
|
}
|
||
|
shared.bind(el);
|
||
|
shared.setFixedWidth(fixedWidth || 'auto');
|
||
|
return shared.getSize(text);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Destroy the TextMetrics instance created by {@link #measure}.
|
||
|
* @static
|
||
|
*/
|
||
|
destroy: function(){
|
||
|
var me = this;
|
||
|
Ext.destroy(me.shared);
|
||
|
me.shared = null;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Creates new TextMetrics.
|
||
|
* @param {String/HTMLElement/Ext.dom.Element} bindTo The element or its ID to bind to.
|
||
|
* @param {Number} [fixedWidth] A fixed width to apply to the measuring element.
|
||
|
*/
|
||
|
constructor: function(bindTo, fixedWidth){
|
||
|
var me = this,
|
||
|
measure = Ext.getBody().createChild({
|
||
|
//<debug>
|
||
|
// tell the spec runner to ignore this element when checking if the dom is clean
|
||
|
'data-sticky': true,
|
||
|
//</debug>
|
||
|
role: 'presentation',
|
||
|
cls: Ext.baseCSSPrefix + 'textmetrics'
|
||
|
});
|
||
|
|
||
|
me.measure = measure;
|
||
|
if (bindTo) {
|
||
|
me.bind(bindTo);
|
||
|
}
|
||
|
|
||
|
measure.position('absolute');
|
||
|
measure.setLocalXY(-1000, -1000);
|
||
|
measure.hide();
|
||
|
|
||
|
if (fixedWidth) {
|
||
|
measure.setWidth(fixedWidth);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns the size of the specified text based on the internal element's style and width properties
|
||
|
* @param {String} text The text to measure
|
||
|
* @return {Object} An object containing the text's size `{width: (width), height: (height)}`
|
||
|
*/
|
||
|
getSize: function(text){
|
||
|
var measure = this.measure,
|
||
|
size;
|
||
|
|
||
|
measure.setHtml(text);
|
||
|
size = measure.getSize();
|
||
|
measure.setHtml('');
|
||
|
return size;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Binds this TextMetrics instance to a new element
|
||
|
* @param {String/HTMLElement/Ext.dom.Element} el The element or its ID.
|
||
|
*/
|
||
|
bind: function(el){
|
||
|
var me = this;
|
||
|
|
||
|
me.el = Ext.get(el);
|
||
|
me.measure.setStyle(
|
||
|
me.el.getStyle(['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing', 'word-break'])
|
||
|
);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets a fixed width on the internal measurement element. If the text will be multiline, you have
|
||
|
* to set a fixed width in order to accurately measure the text height.
|
||
|
* @param {Number} width The width to set on the element
|
||
|
*/
|
||
|
setFixedWidth : function(width){
|
||
|
this.measure.setWidth(width);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns the measured width of the specified text
|
||
|
* @param {String} text The text to measure
|
||
|
* @return {Number} width The width in pixels
|
||
|
*/
|
||
|
getWidth : function(text){
|
||
|
this.measure.dom.style.width = 'auto';
|
||
|
return this.getSize(text).width;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns the measured height of the specified text
|
||
|
* @param {String} text The text to measure
|
||
|
* @return {Number} height The height in pixels
|
||
|
*/
|
||
|
getHeight : function(text){
|
||
|
return this.getSize(text).height;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Destroy this instance
|
||
|
*/
|
||
|
destroy: function(){
|
||
|
var me = this;
|
||
|
me.measure.destroy();
|
||
|
delete me.el;
|
||
|
delete me.measure;
|
||
|
}
|
||
|
}, function(){
|
||
|
Ext.Element.override({
|
||
|
/**
|
||
|
* Returns the width in pixels of the passed text, or the width of the text in this Element.
|
||
|
* @param {String} text The text to measure. Defaults to the innerHTML of the element.
|
||
|
* @param {Number} [min] The minumum value to return.
|
||
|
* @param {Number} [max] The maximum value to return.
|
||
|
* @return {Number} The text width in pixels.
|
||
|
* @member Ext.dom.Element
|
||
|
*/
|
||
|
getTextWidth : function(text, min, max){
|
||
|
return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.valueFrom(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000);
|
||
|
}
|
||
|
});
|
||
|
});
|