diff options
Diffstat (limited to 'horizon')
3 files changed, 60 insertions, 44 deletions
diff --git a/horizon/static/framework/widgets/load-edit/load-edit.directive.js b/horizon/static/framework/widgets/load-edit/load-edit.directive.js index 620dcbf35..902c11f1e 100644 --- a/horizon/static/framework/widgets/load-edit/load-edit.directive.js +++ b/horizon/static/framework/widgets/load-edit/load-edit.directive.js @@ -18,15 +18,18 @@ /** * @ngdoc directive - * @name horizon.framework.widgets:loadEdit + * @name horizon.framework.widgets:load-edit * @scope * @element * @description - * The 'loadEdit' directive supports and validates size of the script entered + * The 'load-edit' directive supports and validates size of the text entered * - * @param {object} config - * @param {object} userInput + * @param {object} title + * @param {object} model + * @param {object} maxBytes * @param {object} key + * @param {object} required + * @param {object} rows * * See configuration.html for example usage. */ @@ -44,9 +47,12 @@ var directive = { restrict: 'E', scope: { - config: '=', - userInput: '=', - key: '@' + title: '@', + model: '=', + maxBytes: '@', + key: '@', + required: '=', + rows: '@' }, link: link, templateUrl: basePath + 'load-edit.html' @@ -65,13 +71,13 @@ /* HTML5 file API is supported by IE10+, Chrome, FireFox and Safari (on Mac). * * If HTML5 file API is not supported by user's browser, remove the option - * to upload a script via file upload. + * to upload a text via file upload. */ - $scope.config.fileApiSupported = !!FileReader; + $scope.fileApiSupported = !!FileReader; /* Angular won't fire change events when the <textarea> is in invalid * status, so we have to use jQuery/jqLite to watch for <textarea> changes. - * If there are changes, we call the onScriptChange function to update the + * If there are changes, we call the onTextareaChange function to update the * size stats and perform validation. */ textarea.on('input propertychange', onTextareaChange); @@ -80,7 +86,7 @@ /* onchange event occurs when a control loses the input focus and * its value has been modified since gaining focus so we need to clear * up the fileInput.val() when the textContent field is modified as to - * allow reloading the same script. + * allow reloading the same text. */ var textContentWatcher = $scope.$watch(function () { return $scope.textContent; @@ -100,12 +106,12 @@ * invalid status, so we have to use jQuery or jqLite to get the length * of the <textarea> content. */ - $scope.scriptLength = textarea.val().length; - $scope.userInput[$scope.key] = $scope.textContent; - if ($scope.scriptLength > 0) { - $scope.scriptModified = true; + $scope.textBytes = getStrByte(textarea.val()); + $scope.model = $scope.textContent; + if ($scope.textBytes > 0) { + $scope.textModified = true; } else { - $scope.scriptModified = false; + $scope.textModified = false; } }); } @@ -121,18 +127,25 @@ function updateTextArea(fileContents) { $scope.textContent = fileContents; - /* Once the DOM manipulation is done, update the scriptLength, so that - * user knows the length of the script loaded into the <textarea>. + /* Once the DOM manipulation is done, update the textBytes, so that + * user knows the bytes of the text loaded into the <textarea>. */ $timeout(function () { onTextareaChange(); - $scope.scriptModified = false; + $scope.textModified = false; }, 250, false); // Focus the <textarea> element after injecting the code into it. textarea.focus(); } + /* The length property for string shows only number of character. + * If text includes multibyte string, it doesn't mean number of bytes. + * So to count bytes, convert to Blob object and get its size. + */ + function getStrByte(str) { + return (new Blob([str], {type: "text/plain"})).size; + } } } })(); diff --git a/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js b/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js index c4f45047f..b08514040 100644 --- a/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js +++ b/horizon/static/framework/widgets/load-edit/load-edit.directive.spec.js @@ -37,9 +37,10 @@ $scope = $injector.get('$rootScope').$new(); $q = $injector.get('$q'); $compile = $injector.get('$compile'); - key = 'inputKey'; + key = 'elementKey'; element = $compile( - '<load-edit config="{}" user-input="{}" key="' + key + '"></load-edit>' + '<load-edit title="{}" model="{}" max-bytes="{}" key="' + key + '" ' + + 'required="true" rows="8"></load-edit>' )($scope); $scope.$apply(); })); @@ -51,20 +52,20 @@ textarea = element.find('textarea'); }); - it('should set scriptModified to true when textarea has content', function () { + it('should set textModified to true when textarea has content', function () { textarea.val('any value'); textarea.trigger('propertychange'); $scope.$apply(); - expect(element.isolateScope().scriptModified).toBe(true); + expect(element.isolateScope().textModified).toBe(true); }); - it('should set scriptModified to false when textarea has no content', function () { + it('should set textModified to false when textarea has no content', function () { textarea.val(''); textarea.trigger('propertychange'); $scope.$apply(); - expect(element.isolateScope().scriptModified).toBe(false); + expect(element.isolateScope().textModified).toBe(false); }); it('should set userInput to the value of the textarea', function() { @@ -72,7 +73,7 @@ textarea.trigger('input'); $scope.$apply(); - expect(element.isolateScope().userInput[key]).toBe('user input'); + expect(element.isolateScope().model).toBe('user input'); }); }); diff --git a/horizon/static/framework/widgets/load-edit/load-edit.html b/horizon/static/framework/widgets/load-edit/load-edit.html index 74f88da90..4fe2cf8f7 100644 --- a/horizon/static/framework/widgets/load-edit/load-edit.html +++ b/horizon/static/framework/widgets/load-edit/load-edit.html @@ -1,30 +1,32 @@ -<div class="form-group" ng-class="{ 'has-error': scriptLength >= config.MAX_SCRIPT_SIZE }"> - <label for="customization-script" class="control-label"> - <span translate>Customization Script</span> - <span ng-show="scriptModified" +<div class="form-group" ng-show="fileApiSupported"> + <label for="load-{$ ::key $}" translate>Load {$ ::title $} from a file</label> + <input id="load-{$ ::key $}" type="file"> +</div> + +<div class="form-group" ng-class="{ 'has-error': textBytes >= maxBytes }"> + <label for="{$ ::key $}" class="control-label"> + <span>{$ ::title $}</span> + <span class="hz-icon-required fa fa-asterisk" ng-if="required"></span> + <span ng-show="textModified" translate> (Modified)</span> </label> - <span class="pull-right" ng-class="{ 'text-danger': scriptLength >= config.MAX_SCRIPT_SIZE }"> + <span class="pull-right" ng-class="{ 'text-danger': textBytes >= maxBytes }"> <span translate translate-comment="Strings between {$ and $} should be left untranslated."> - Script size: {$ (scriptLength || 0) | bytes $} of {$ config.MAX_SCRIPT_SIZE | bytes $} + Content size: {$ (textBytes || 0) | bytes $} of {$ ::maxBytes | bytes $} </span> </span> <textarea class="form-control" - rows="8" - id="customization-script" - name="customization-script" - ng-maxlength="config.MAX_SCRIPT_SIZE" - ng-model="textContent"> + id="{$ ::key $}" + name="{$ ::key $}" + ng-maxlength="::maxBytes" + ng-model="textContent" + ng-required="required" + rows="{$ ::rows $}"> </textarea> <span class="help-block" - ng-show="scriptLength >= config.MAX_SCRIPT_SIZE" + ng-show="textBytes >= maxBytes" translate> - The script is larger than the maximum size + The content is larger than the maximum byte size </span> </div> - -<div class="form-group" ng-show="config.fileApiSupported"> - <label for="load-script" translate>Load script from a file</label> - <input id="load-script" type="file"> -</div> |