123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- 'use strict';
- /**
- * Licensed Materials - Property of IBM
- * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2019
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- define(['jquery', 'doT', './StaticWidget', 'text!./NewWidget.html'], function ($, dot, StaticWidget, NewWidget) {
- var NewWidgetTemplate = dot.template(NewWidget);
- /**
- * The UrlWidget is a generic class for widgets which load some markup based on a URL resource
- */
- var F12 = 123;
- var ESCAPE = 27;
- var UrlWidget = null;
- UrlWidget = StaticWidget.extend({
- init: function init() {
- UrlWidget.inherited('init', this, arguments);
- },
- initialize: function initialize() {
- return Promise.resolve();
- },
- getId: function getId() {
- return this.id;
- },
- onContainerReady: function onContainerReady() {
- UrlWidget.inherited('onContainerReady', this, arguments);
- if (this.isInlineEditMode()) {
- this.renderInlineEditUi();
- }
- this.updateModeMarkup();
- },
- /**
- * Virtual method
- * @return boolean true iff inline edit mode should be shown (i.e. not the actual widget payload rendering)
- */
- isInlineEditMode: function isInlineEditMode() {
- return false;
- },
- onConsumeMode: function onConsumeMode() {
- UrlWidget.inherited('onConsumeMode', this, arguments);
- var $container = this.$el.find('.staticContent');
- $container.removeClass('authoring');
- $container.addClass('consume');
- },
- onAuthoringMode: function onAuthoringMode() {
- UrlWidget.inherited('onAuthoringMode', this, arguments);
- var $container = this.$el.find('.staticContent');
- $container.removeClass('consume');
- $container.addClass('authoring');
- },
- /**
- * Virtual method
- * @return The caption for the inline edit textbox
- */
- getInlineEditCaption: function getInlineEditCaption() {
- return null;
- },
- /**
- * Virtual method
- * @return The text to show in consume mode when no URL has been specified
- */
- getMissingUrlText: function getMissingUrlText() {
- return null;
- },
- /**
- * Virtual method
- * @return The text for aria label
- */
- getAriaLabelText: function getAriaLabelText() {
- return null;
- },
- /**
- * Virtual method
- * @return The content class, used to hook into default images for pinning
- */
- getContentClass: function getContentClass() {
- return null;
- },
- renderInlineEditUi: function renderInlineEditUi() {
- if (!this.$el.find('.inlineEditInput').length) {
- this.$el.find('.staticContent').replaceWith(NewWidgetTemplate({
- title: this.getInlineEditCaption(),
- missingUrlText: this.getMissingUrlText(),
- mediaAriaLabel: this.getAriaLabelText(),
- contentClass: this.getContentClass(),
- includeAuthoringMode: true
- }));
- var $input = this.$el.find('.staticContent input');
- $input.on('click touchend', function () {
- // give focus to the text input
- $input.focus();
- }.bind(this));
- $(this.el).on('keydown', '.inlineEditInput', this._inlineKeyDown.bind(this));
- $(this.el).on('keyup', '.inlineEditInput', this._inlineKeyUp.bind(this));
- $(this.el).on('input', '.inlineEditInput', this._inlineInput.bind(this));
- //Might be called multiple time so we need to cleanup
- $(this.el).off('blur.urlWidget');
- // re-register
- $(this.el).on('blur.urlWidget', '.inlineEditInput', this._onBlur.bind(this));
- }
- },
- _onBlur: function _onBlur() {
- if (this.$el.find('.inlineEditInput').val()) {
- this._uiSetUrl();
- }
- },
- getLabel: function getLabel() {
- // To be implemented by concrete class
- },
- _inlineKeyDown: function _inlineKeyDown(evt) {
- if (evt.keyCode === 13) {
- this._uiSetUrl();
- }
- evt.stopPropagation();
- },
- _inlineKeyUp: function _inlineKeyUp(evt) {
- evt.stopPropagation();
- if (evt.keyCode === ESCAPE || evt.keyCode === F12 && evt.shiftKey) {
- // esc
- this.$el.focus();
- }
- },
- _inlineInput: function _inlineInput(evt) {
- var $inlineEdit = this.$el.find('.inlineEdit');
- if ($(evt.target).val() === '' && $inlineEdit.hasClass('inputError')) {
- $inlineEdit.removeClass('inputError');
- }
- },
- _uiSetUrl: function _uiSetUrl() {
- var url = this.$el.find('.inlineEditInput').val();
- if (url !== this._lastSetURL) {
- //Suppress double executions (Enter setting the url, triggering a blur)
- this._lastSetURL = url;
- var errorData = {};
- var urlSetSuccessfully = this.setUrl(url, errorData);
- var $inlineEdit = this.$el.find('.inlineEdit');
- if (urlSetSuccessfully) {
- $inlineEdit.removeClass('inputError');
- } else {
- $inlineEdit.addClass('inputError');
- $inlineEdit.find('.errorMessage').html(errorData.message);
- }
- this.refreshPropertiesPane();
- }
- },
- /**
- * Virtual method
- * @param The URL entered by the user
- * @return true iff the URL is successfully set
- */
- setUrl: function setUrl() /*url, error data object*/{
- return false;
- },
- /**
- * Applies any mode-specific changes to the markup
- * (e.g. authoring vs consume mode).
- */
- updateModeMarkup: function updateModeMarkup() {
- if (this.isAuthoringMode) {
- this.onAuthoringMode();
- } else {
- this.onConsumeMode();
- }
- this.updateDescription(this.getLabel());
- },
- /**
- * Updates markup, derived class may do more work
- */
- updateMarkup: function updateMarkup() {
- this.updateModeMarkup();
- },
- onChromeSelected: function onChromeSelected() {
- UrlWidget.inherited('onChromeSelected', this, arguments);
- this.onFocus();
- setTimeout(function () {
- $(this.el).find('.inlineEditInput').focus();
- }.bind(this), 10);
- },
- registerEventGroup: function registerEventGroup() {
- // URL widgets are not added to event groups
- },
- encodeURL: function encodeURL(URL) {
- //Run a decode/encode to block XSS attacks while not double-encoding already encoded URLs
- //As different parts of the URI encode different characters, we need to parse the URI to encode different parts using different functions.
- var URLComponents = URL.split('?');
- var urlPath = encodeURI(decodeURI(URLComponents[0])),
- searchPath = URLComponents[1];
- URLComponents = [];
- URLComponents.push(urlPath);
- if (searchPath) {
- var searchPathComponents = searchPath.split('&'),
- encodedSearchPathComponents = [];
- for (var i = 0; i < searchPathComponents.length; i++) {
- var paramComponents = searchPathComponents[i].split('='),
- encodedParamComponents = [];
- for (var j = 0; j < paramComponents.length; j++) {
- encodedParamComponents.push(encodeURIComponent(decodeURIComponent(paramComponents[j].replace(/\+/g, ' '))));
- }
- encodedSearchPathComponents.push(encodedParamComponents.join('='));
- }
- URLComponents.push(encodedSearchPathComponents.join('&'));
- }
- return URLComponents.join('?');
- }
- });
- /**
- * Checks whether the browser will render this URL as an embedded object
- * (e.g. iframe, video, audio, embed, object, etc.)
- */
- UrlWidget._isAllowedProtocol = function (url) {
- if (!url) {
- return false;
- }
- url = url.toLowerCase();
- // https:// is always allowed - i.e. both in pages served from HTTP or
- // HTTPS
- // // is always allowed as it will copy whichever protocol the
- // containing page is using
- // http:// is only allowed if the containing page is using HTTP as well
- if (url.indexOf('https://') === 0 || url.indexOf('//') === 0) {
- return true;
- }
- return false;
- };
- /**
- * Checks whether the browser will render this URL as an embedded object
- * (e.g. iframe, video, audio, embed, object, etc.)
- */
- UrlWidget.isAllowedProtocol = function (url) {
- return UrlWidget._isAllowedProtocol(url);
- };
- UrlWidget.getDefaultConsumeMarkup = function (missingText) {
- return NewWidgetTemplate({
- missingUrlText: missingText
- });
- };
- return UrlWidget;
- });
- //# sourceMappingURL=UrlWidget.js.map
|