diff --git a/build/css/main.css b/build/css/main.css index df0a136a..f9fa0c2e 100644 --- a/build/css/main.css +++ b/build/css/main.css @@ -6000,8 +6000,7 @@ html { .caption, .icon-caption { font-weight: bold; font-size: 11px; - margin-bottom: 0; - text-transform: uppercase; } + margin-bottom: 0; } /* * Copyright 2016 Resin.io @@ -6367,6 +6366,10 @@ body { .section-footer [os-open-external]:hover { color: #85898c; text-decoration: underline; } + .section-footer .footer-right { + position: absolute; + right: 0; + top: 50%; } .step-border, .step-border-left, .step-border-right { height: 2px; diff --git a/lib/browser/app.js b/lib/browser/app.js index 6bed737b..a8679b3a 100644 --- a/lib/browser/app.js +++ b/lib/browser/app.js @@ -55,7 +55,8 @@ const app = angular.module('Etcher', [ // Utils require('./browser/utils/if-state/if-state'), require('./browser/utils/notifier/notifier'), - require('./browser/utils/path/path') + require('./browser/utils/path/path'), + require('./browser/utils/manifest-bind/manifest-bind') ]); app.run(function(AnalyticsService) { diff --git a/lib/browser/utils/manifest-bind/directives/manifest-bind.js b/lib/browser/utils/manifest-bind/directives/manifest-bind.js new file mode 100644 index 00000000..6326c458 --- /dev/null +++ b/lib/browser/utils/manifest-bind/directives/manifest-bind.js @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const _ = require('lodash'); +const packageJSON = require('../../../../../package.json'); + +/** + * @summary ManifestBind directive + * @function + * @public + * + * @description + * This directive provides an attribute to bind the current + * element value to a property in `package.json`. + * + * @returns {Object} directive + * + * @example + * + */ +module.exports = function() { + return { + restrict: 'A', + scope: false, + link: function(scope, element, attributes) { + const value = _.get(packageJSON, attributes.manifestBind); + + if (!value) { + throw new Error('ManifestBind: Unknown property `' + attributes.manifestBind + '`'); + } + + element.html(value); + } + }; +}; diff --git a/lib/browser/utils/manifest-bind/manifest-bind.js b/lib/browser/utils/manifest-bind/manifest-bind.js new file mode 100644 index 00000000..9c097c81 --- /dev/null +++ b/lib/browser/utils/manifest-bind/manifest-bind.js @@ -0,0 +1,32 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +/** + * @module Etcher.Utils.ManifestBind + * + * The purpose of this module is to provide an attribute + * directive to bind the current element to a property + * in the application's `package.json` manifest. + */ + +const angular = require('angular'); +const MODULE_NAME = 'Etcher.Utils.ManifestBind'; +const ManifestBind = angular.module(MODULE_NAME, []); +ManifestBind.directive('manifestBind', require('./directives/manifest-bind')); + +module.exports = MODULE_NAME; diff --git a/lib/index.html b/lib/index.html index 9fdf4d24..163d23b9 100644 --- a/lib/index.html +++ b/lib/index.html @@ -48,6 +48,8 @@ width="79px" height="23px" os-open-external="https://resin.io"> + + diff --git a/lib/scss/components/_caption.scss b/lib/scss/components/_caption.scss index 8f52144d..7f055ef4 100644 --- a/lib/scss/components/_caption.scss +++ b/lib/scss/components/_caption.scss @@ -18,5 +18,4 @@ font-weight: bold; font-size: 11px; margin-bottom: 0; - text-transform: uppercase; } diff --git a/lib/scss/main.scss b/lib/scss/main.scss index eb16454b..b43c2134 100644 --- a/lib/scss/main.scss +++ b/lib/scss/main.scss @@ -107,6 +107,12 @@ body { color: lighten($color-disabled, 5%); text-decoration: underline; } + + .footer-right { + position: absolute; + right: 0; + top: 50%; + } } .step-border { diff --git a/screenshot.png b/screenshot.png index 3d985bf7..5d9b422e 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/tests/browser/utils/manifest-bind.spec.js b/tests/browser/utils/manifest-bind.spec.js new file mode 100644 index 00000000..80eeeca3 --- /dev/null +++ b/tests/browser/utils/manifest-bind.spec.js @@ -0,0 +1,60 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const m = require('mochainon'); +const angular = require('angular'); +const packageJSON = require('../../../package.json'); +require('angular-mocks'); + +describe('Browser: ManifestBind', function() { + + beforeEach(angular.mock.module( + require('../../../lib/browser/utils/manifest-bind/manifest-bind') + )); + + let $compile; + let $rootScope; + + beforeEach(angular.mock.inject(function(_$compile_, _$rootScope_) { + $compile = _$compile_; + $rootScope = _$rootScope_; + })); + + describe('manifestBind', function() { + + it('should bind to top level properties', function() { + const element = $compile('')($rootScope); + $rootScope.$digest(); + m.chai.expect(element.html()).to.equal(packageJSON.version); + }); + + it('should bind to nested properties', function() { + const element = $compile('')($rootScope); + $rootScope.$digest(); + m.chai.expect(element.html()).to.equal(packageJSON.repository.type); + }); + + it('should throw if the property does not exist', function() { + m.chai.expect(function() { + $compile('')($rootScope); + }).to.throw('ManifestBind: Unknown property `foo.bar`'); + }); + + }); + +});