123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
'use strict';
modulum('ImageWidget', ['ColoredWidgetBase', 'WidgetFactory'],
function(context, cls) {
cls.ImageWidget = context.oo.Class(cls.ColoredWidgetBase, function($super) {
return {
__name: 'ImageWidget',
_src: null,
_defaultColor: null,
_autoScale: false,
_scaleIconValue: null,
_gotFirstInitialImage: false,
_firstInitialSizing: true,
_initialAutoscaling: false,
_img: null,
_border: null,
_standalone: false,
_hasContent: false,
_alignment: null,
_onErrorHandler: null,
_initLayout: function() {
this._layoutInformation = new cls.LayoutInformation(this);
this._layoutInformation.shouldFillStack = true;
this._layoutEngine = new cls.ImageLayoutEngine(this);
this._layoutEngine._shouldFillHeight = true;
},
destroy: function() {
this._border = null;
$super.destroy.call(this);
},
manageMouseClick: function(domEvent) {
this._onRequestFocus(domEvent);
this.emit(context.constants.widgetEvents.click, domEvent);
return true;
},
setStandaloneImage: function(standalone) {
this._standalone = Boolean(standalone);
this._element.toggleClass('gbc_withBorder', this._standalone);
this._element.toggleClass('gbc_selfImage', this._standalone);
},
setClickableImage: function(clickable) {
if (clickable) {
this.addClass('clickable');
} else {
this.removeClass('clickable');
}
},
setValue: function(val) {
this.setSrc(val);
},
getValue: function() {
return this.getSrc();
},
setImage: function(image) {
this.setSrc(image);
},
getImage: function() {
return this.getSrc();
},
isFontImage: function() {
if (this._src) {
return this._src.startsWith('font:');
} else {
return false;
}
},
setSrc: function(src, directApply) {
this.getLayoutInformation().invalidateMeasure();
if (src !== this._src) {
var old = this._src,
initial = this.getLayoutInformation().getSizePolicyConfig().isInitial();
this._src = src;
if (initial && this._gotFirstInitialImage && old !== null && src !== null) {
this._firstInitialSizing = false;
}
if (initial && old === null && src !== null) {
this._gotFirstInitialImage = true;
}
this._updateImage(directApply);
}
this.domAttributesMutator(function() {
if (!this._destroyed && this._img && this.getTitle()) {
this._img.setAttribute("alt", this.getTitle());
}
}.bind(this));
},
getSrc: function() {
return this._src;
},
setTitle: function(title) {
$super.setTitle.call(this, title);
if (this._img) {
this._img.setAttribute('alt', title);
}
},
setStretch: function(stretch) {
this._element.toggleClass('stretch', stretch);
},
setAutoScale: function(setted) {
if (setted !== this._autoScale) {
this._autoScale = setted;
this._updateImage();
}
},
setScaleIconValue: function(value) {
this._scaleIconValue = value;
this.addClass('gbc_scaleIconValue');
this._updateImage(true);
},
setDefaultColor: function(color) {
this._defaultColor = color;
},
setFocus: function(fromMouse) {
this._element.domFocus();
},
getClipboardValue: function() {
return this.getValue();
},
setAlignment: function(y, x) {
var rtl = this.getStart() === 'right';
this._alignment = {
x: x,
y: y,
val: (x === 'horizontalCenter' || x === 'center' ? 'center' :
((x === 'right' && !rtl) || (x !== 'right' && rtl) ? 'right' : 'left')
) + ' ' +
(y === 'verticalCenter' || y === 'center' ? 'center' : (y === 'bottom' ? 'bottom' : 'top'))
};
var pos = {
'align-items': y === 'verticalCenter' ? 'center' : (y === 'bottom' ? 'flex-end' : 'flex-start'),
'justify-content': x === 'horizontalCenter' ? 'center' : (x === 'right' ? 'flex-end' : 'flex-start'),
'background-position': this._alignment.val
};
this.setStyle(pos);
},
_updateImage: function(directApply) {
if (!this._element) {
return;
}
if (this._hasContent) {
this._element.empty();
this._hasContent = false;
}
if (this._img) {
this._img.off('error.ImageWidget');
this._img.off('load.ImageWidget');
this._img = null;
}
var backgroundImage = null;
var backgroundSize = null;
var backgroundRepeat = null;
var backgroundPosition = null;
var width = null;
var height = null;
if (this._src) {
if (this._src.startsWith('font:')) {
var pattern = /font:([^:]+).ttf:([^:]+):?([^:]*)/,
match = this._src.match(pattern),
fontName, sCharCode, color, iCharCode, finalChar;
if (match) {
fontName = match[1];
sCharCode = match[2];
iCharCode = parseInt('0x' + sCharCode, 16);
if (0x10000 <= iCharCode && iCharCode <= 0x10FFFF) {
iCharCode = iCharCode - 0x10000;
finalChar = String.fromCharCode(0xD800 | (iCharCode >> 10)) +
String.fromCharCode(0xDC00 | (iCharCode & 0x3FF));
} else {
finalChar = String.fromCharCode('0x' + sCharCode);
}
color = match[3] || this._defaultColor;
}
if (fontName && sCharCode) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 640 512');
svg.setAttribute('preserveAspectRatio', 'xMinYMid meet');
var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('text-anchor', 'middle');
if (window.browserInfo.isEdge || window.browserInfo.isIE) {
text.setAttribute('dy', '0.7ex');
} else {
text.setAttribute('dominant-baseline', 'central');
}
text.setAttribute('x', '320');
text.setAttribute('y', '256');
text.setAttribute('font-size', '470');
text.setAttribute('font-family', '"image2font_' + fontName.trim() + '"');
if (this._scaleIconValue) {
svg.style.setProperty('--scaleIconValue', this._scaleIconValue);
}
if (directApply) {
text.textContent = finalChar;
} else {
window.requestAnimationFrame(function(text, character) {
text.textContent = character;
}.bind(this, text, finalChar));
}
if (color) {
text.setAttribute('fill', color);
}
svg.appendChild(text);
this._element.appendChild(svg);
this._hasContent = true;
this.emit(context.constants.widgetEvents.ready);
}
this.getElement().toggleClass('gbc_fixedSvg', !this._autoScale && !this._scaleIconValue);
} else {
var isInitial = this.getLayoutInformation().getSizePolicyConfig().isInitial();
if (this._inTable || this._autoScale && (!isInitial || !this._firstInitialSizing)) {
backgroundImage = "url('" + this._src + "')";
backgroundSize = 'contain';
backgroundRepeat = 'no-repeat';
width = '100%';
height = '100%';
backgroundPosition = this._alignment && this._alignment.val || this.getStart();
this.emit(context.constants.widgetEvents.ready);
} else {
this._img = document.createElement('img');
this._img.on('error.ImageWidget', this._onError.bind(this));
if (directApply) {
this._img.setAttribute("src", this._src);
} else {
this._setElementAttribute("src", this._src, "_img");
}
this._img.on('load.ImageWidget', this._onLoad.bind(this));
this._element.appendChild(this._img);
}
this._hasContent = true;
}
this.toggleClass('gbc_autoScale', this._autoScale);
if (this._scaleIconValue && this._img) {
this._img.style.setProperty('--scaleIconValue', this._scaleIconValue);
this.getLayoutInformation().invalidateMeasure();
}
}
if (this._standalone) {
if (!this._border) {
this._border = document.createElement('div');
this._border.addClass('gbc_ImageWidget_border');
}
this._element.appendChild(this._border);
}
this.setStyle({
'background-image': backgroundImage,
'background-size': backgroundSize,
'background-repeat': backgroundRepeat,
'background-position': backgroundPosition,
'width': width
});
if (this.__charMeasurer) {
this._element.appendChild(this.__charMeasurer);
}
},
setErrorHandler: function(errorHdl) {
this._onErrorHandler = errorHdl;
},
_onError: function() {
this._img.off('error.ImageWidget');
this._img.off('load.ImageWidget');
if (this._element) {
this._element.addClass('hidden');
}
if (this._onErrorHandler) {
this._onErrorHandler();
}
},
_onLoad: function() {
this._img.off('error.ImageWidget');
this._img.off('load.ImageWidget');
if (this._element) {
this._element.removeClass('hidden');
var w = this._img.naturalWidth,
h = this._img.naturalHeight;
if (!this.getLayoutEngine().hasNaturalSize()) {
if (!this._autoScale) {
this._layoutEngine.invalidateMeasure();
}
this.getLayoutEngine()._needMeasure = true;
}
this.getLayoutEngine().setNaturalSize(w, h);
this._element.toggleClass('gbc_ImageWidget_wider', w > h).toggleClass('gbc_ImageWidget_higher', w <= h);
this.getLayoutInformation()._sizeRatio = h / w;
var isInitial = this.getLayoutInformation().getSizePolicyConfig().isInitial();
if (isInitial && this._firstInitialSizing) {
if (this._autoScale) {
this._initialAutoscaling = true;
this.getLayoutInformation()._keepRatio = true;
} else {
if (!this.getLayoutEngine().hasNaturalSize()) {
this.getLayoutEngine()._needMeasure = true;
}
}
}
this.emit(context.constants.widgetEvents.ready, this.getLayoutEngine().hasNaturalSize());
gbc.LogService.ui.log("Image loaded", true, this.__name, this);
}
},
_whenLayouted: function() {
if (this._initialAutoscaling) {
this._initialAutoscaling = false;
this._firstInitialSizing = false;
this._updateImage();
}
},
setHidden: function(hidden) {
$super.setHidden.call(this, hidden);
if (!this._hidden && this._element.parentNode) {
this._element.parentNode.removeClass('gl_gridElementHidden');
}
},
getStyleSheetId: function() {
var windowWidget = this.getWindowWidget(),
windowWidgetId = windowWidget && windowWidget.getUniqueIdentifier();
return this._uuid || windowWidgetId || "_";
},
getNaturalDimension: function() {
return {
width: this._img.naturalWidth,
height: this._img.naturalHeight
};
}
};
});
cls.WidgetFactory.registerBuilder('Image', cls.ImageWidget);
cls.WidgetFactory.registerBuilder('ImageWidget', cls.ImageWidget);
});