ImageWidget.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. 'use strict';
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2019
  5. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. */
  7. define(['./UrlWidget', './ScalingUtil', '../../../app/nls/StringResources', 'jquery', 'underscore', 'doT', 'text!./ImageUri.html'], function (UrlWidget, ScalingUtil, resources, $, _, dot, Template) {
  8. var mediaImageRegex = /^v[1-9]\/ext\//;
  9. var ImageWidget = UrlWidget.extend({
  10. init: function init(options) {
  11. ImageWidget.inherited('init', this, arguments);
  12. this.model = this.model || {};
  13. this.model.imageLink = options && options.initialConfigJSON && options.initialConfigJSON.imageLink;
  14. this.model.altText = options && options.initialConfigJSON && options.initialConfigJSON.altText;
  15. this.model.fillColor = options && options.initialConfigJSON && options.initialConfigJSON.fillColor;
  16. this.model.borderColor = options && options.initialConfigJSON && options.initialConfigJSON.borderColor;
  17. this.propertyCallbacks = this.dashboardApi.getFeature('PropertyCallbacks');
  18. },
  19. onContainerReady: function onContainerReady() {
  20. ImageWidget.inherited('onContainerReady', this, arguments);
  21. if (this.model) {
  22. this.model.on('change:imageLink', this._onPropertyChange, this);
  23. this.model.on('change:altText', this._onPropertyChange, this);
  24. this.model.on('change:resize', this._onPropertyChange, this);
  25. this.addWhiteListAttrs('imageLink', 'altText', 'resize');
  26. }
  27. if (this.model.fillColor) {
  28. this.$el.find('div.staticContent').addClass('fill-' + this.model.fillColor);
  29. }
  30. if (this.model.borderColor) {
  31. this.$el.find('div.staticContent').addClass('border-' + this.model.borderColor);
  32. }
  33. },
  34. render: function render() {
  35. if (this.propertyCallbacks.validateImageInput(null, this.model.imageLink).isValid) {
  36. this.model.imageLink = this.encodeURL(this.model.imageLink);
  37. this.$el.append(this.getHtmlRender());
  38. } else {
  39. this.$el.append(UrlWidget.getDefaultConsumeMarkup(resources.get('imgMissingUrl')));
  40. }
  41. },
  42. setUrl: function setUrl(url) {
  43. var errorData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  44. var validateInfo = this.propertyCallbacks.validateImageInput(null, url);
  45. errorData.message = validateInfo.message;
  46. if (validateInfo.isValid) {
  47. var transactionId = _.uniqueId('_addImage_');
  48. this.set({
  49. imageLink: url
  50. }, {
  51. sender: this,
  52. payloadData: {
  53. undoRedoTransactionId: transactionId
  54. }
  55. });
  56. this._initWidthHeight(url, transactionId);
  57. return true;
  58. }
  59. return false;
  60. },
  61. _initWidthHeight: function _initWidthHeight(url, transactionId) {
  62. var _this = this;
  63. return new Promise(function (resolve, reject) {
  64. try {
  65. // eslint-disable-next-line no-undef
  66. var img = new Image();
  67. img.onload = function () {
  68. img = ScalingUtil.scale({
  69. image: img,
  70. max: {
  71. width: 500,
  72. height: 500
  73. },
  74. format: 'css'
  75. });
  76. var $chrome = _this.getWidgetStyleNode().closest('.widget');
  77. $chrome.width(img.width);
  78. $chrome.height(img.height);
  79. _this.widgetChromeEventRouter.trigger('widget:updateLayout', {
  80. sender: _this,
  81. payloadData: {
  82. undoRedoTransactionId: transactionId
  83. }
  84. });
  85. resolve();
  86. };
  87. img.src = url;
  88. } catch (error) {
  89. reject(error);
  90. }
  91. });
  92. },
  93. _urlChange: function _urlChange(options) {
  94. return this.setUrl(options.item);
  95. },
  96. onEnterContainer: function onEnterContainer() {
  97. var mediaInput = this.$el.find('.inlineEditInput');
  98. mediaInput.focus();
  99. },
  100. isInlineEditMode: function isInlineEditMode() {
  101. return !this.model.imageLink;
  102. },
  103. getInlineEditCaption: function getInlineEditCaption() {
  104. return resources.get('imageTextLabel');
  105. },
  106. getMissingUrlText: function getMissingUrlText() {
  107. return resources.get('imgMissingUrl');
  108. },
  109. getAriaLabelText: function getAriaLabelText() {
  110. return resources.get('mediaAriaLabel');
  111. },
  112. getLabel: function getLabel() {
  113. return this._getAltText() || resources.get('imageWidgetTitle');
  114. },
  115. getContentClass: function getContentClass() {
  116. return 'imageWidgetContent';
  117. },
  118. _getAltText: function _getAltText() {
  119. return this.model && this.model.get ? this.model.get('altText') : null;
  120. },
  121. _onPropertyChange: function _onPropertyChange(options) {
  122. var updatedHtml = null;
  123. if (this.model.imageLink) {
  124. this.model.imageLink = this.encodeURL(this.model.imageLink);
  125. if (this.propertyCallbacks.validateImageInput(null, this.model.imageLink).isValid) {
  126. var $node = this.getWidgetStyleNode();
  127. $node.find('input').remove();
  128. $node.removeClass('inlineEdit');
  129. var $img = $node.find('img');
  130. if (!$img.length) {
  131. $img = $('<img></img>');
  132. $node.empty();
  133. $node.append($img);
  134. }
  135. $img.attr('src', this.model.imageLink);
  136. var altText = this._getAltText();
  137. if (altText) {
  138. $img.attr('alt', altText);
  139. } else {
  140. $img.removeAttr('alt');
  141. }
  142. var heightWidth = this.model.resize === 'false' ? 'auto' : '100%';
  143. $img.css('width', heightWidth).css('height', heightWidth);
  144. }
  145. } else {
  146. this.renderInlineEditUi();
  147. updatedHtml = UrlWidget.getDefaultConsumeMarkup(resources.get('imgMissingUrl'));
  148. }
  149. this.updateMarkup();
  150. if (options.data && options.data.undoRedoTransactionId) {
  151. this.updateModelContent(updatedHtml, options.data.undoRedoTransactionId);
  152. } else {
  153. this.updateModelContent(updatedHtml);
  154. }
  155. },
  156. getPropertyList: function getPropertyList() {
  157. var _this2 = this;
  158. var propertyList = ImageWidget.inherited('getPropertyList', this, arguments) || [];
  159. // Make the image link field read-only if the image came from an image library.
  160. _.forEach(propertyList, function (property) {
  161. if (property.id === 'imageLink' && mediaImageRegex.test(_this2.model.imageLink)) {
  162. property.editor.readOnly = true;
  163. return property;
  164. }
  165. });
  166. return propertyList;
  167. },
  168. getHtmlRender: function getHtmlRender() {
  169. var renderTemplate = dot.template(Template);
  170. var props = {
  171. url: this.model.imageLink
  172. };
  173. var altText = this._getAltText();
  174. if (altText) {
  175. props.altText = altText;
  176. }
  177. if (this.model.fillColor) {
  178. props.fillColor = 'fill-' + this.model.fillColor;
  179. }
  180. if (this.model.borderColor) {
  181. props.borderColor = 'border-' + this.model.borderColor;
  182. }
  183. if (this.model.imageLink) {
  184. props.url = this.model.imageLink;
  185. }
  186. return renderTemplate(props);
  187. }
  188. });
  189. ImageWidget.getDefaultSpec = function (name, options) {
  190. options = options || {};
  191. var spec = {
  192. model: {
  193. type: 'image',
  194. 'avatarHtml': UrlWidget.getDefaultConsumeMarkup(),
  195. 'imageLink': options.imageLink,
  196. 'altText': options.altText
  197. },
  198. layoutProperties: {
  199. style: {
  200. width: '480px',
  201. height: '360px'
  202. }
  203. }
  204. };
  205. if (options.imageLink) {
  206. return new Promise(function (resolve, reject) {
  207. try {
  208. // eslint-disable-next-line no-undef
  209. var img = new Image();
  210. img.onload = function () {
  211. var dX = 480 / (img.naturalWidth || 1);
  212. var dY = 360 / (img.naturalHeight || 1);
  213. if (dX < 1 || dY < 1) {
  214. spec.layoutProperties.style = {
  215. height: Math.min(dX, dY) * img.naturalHeight + 'px',
  216. width: Math.min(dX, dY) * img.naturalWidth + 'px'
  217. };
  218. } else {
  219. spec.layoutProperties.style = {
  220. height: img.naturalHeight + 'px',
  221. width: img.naturalWidth + 'px'
  222. };
  223. }
  224. resolve(spec);
  225. };
  226. img.onerror = function () {
  227. reject();
  228. };
  229. img.src = options.imageLink;
  230. } catch (error) {
  231. reject(error);
  232. }
  233. });
  234. } else {
  235. return Promise.resolve(spec);
  236. }
  237. };
  238. return ImageWidget;
  239. });
  240. //# sourceMappingURL=ImageWidget.js.map