├── .browserslistrc ├── src ├── index.js ├── main.js ├── plugin.js ├── AspectRatio.vue └── App.vue ├── cypress.json ├── jest.config.js ├── postcss.config.js ├── assets ├── screen.png └── responsive.gif ├── public ├── favicon.ico └── index.html ├── babel.config.js ├── tests ├── e2e │ ├── .eslintrc.js │ ├── support │ │ ├── index.js │ │ └── commands.js │ ├── plugins │ │ └── index.js │ └── specs │ │ └── test.js └── unit │ └── aspect-ratio.spec.js ├── .gitignore ├── .eslintrc.js ├── LICENSE ├── package.json ├── README.md └── dist ├── vue-aspect-ratio.umd.min.js ├── vue-aspect-ratio.esm.js ├── vue-aspect-ratio.common.js └── vue-aspect-ratio.umd.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./AspectRatio.vue') -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@vue/cli-plugin-unit-jest' 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /assets/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodeago/vue-aspect-ratio/HEAD/assets/screen.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodeago/vue-aspect-ratio/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /assets/responsive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodeago/vue-aspect-ratio/HEAD/assets/responsive.gif -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import './plugin' 4 | 5 | Vue.config.productionTip = false 6 | 7 | new Vue({ 8 | render: h => h(App), 9 | }).$mount('#app') 10 | -------------------------------------------------------------------------------- /tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | 'cypress' 4 | ], 5 | env: { 6 | mocha: true, 7 | 'cypress/globals': true 8 | }, 9 | rules: { 10 | strict: 'off' 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | public 4 | dist/*.gz 5 | dist/*.map 6 | coverage 7 | docs 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # related test files 14 | /tests/e2e/reports 15 | /tests/e2e/videos 16 | /tests/e2e/screenshots 17 | 18 | # editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | -------------------------------------------------------------------------------- /src/plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTE: 3 | * This file is plugin stub for main.js 4 | */ 5 | 6 | import Vue from 'vue' 7 | import VueAspectRatio from './index' 8 | 9 | Vue.component(VueAspectRatio.name, VueAspectRatio) 10 | 11 | /* 12 | * NOTE: 13 | * If you want Vue instance of main.js to import something in your plugin as a Vue option, 14 | * you need to export it here. 15 | */ 16 | // export default plugin 17 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-aspect-ratio 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | }, 17 | overrides: [ 18 | { 19 | files: [ 20 | '**/__tests__/*.{j,t}s?(x)', 21 | '**/tests/unit/**/*.spec.{j,t}s?(x)' 22 | ], 23 | env: { 24 | jest: true 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /tests/unit/aspect-ratio.spec.js: -------------------------------------------------------------------------------- 1 | // import { mount, createLocalVue } from '@vue/test-utils' 2 | // import Test from '@/components/Test.vue' 3 | 4 | // describe('VueAspectRatio', () => { 5 | // it('should render html in default slot', () => { 6 | // const localVue = createLocalVue() 7 | // const wrapper = mount(Test, { 8 | // localVue 9 | // }) 10 | // const contentWrapper = wrapper.find(".content") 11 | // expect(contentWrapper.text().indexOf("This is the content")).toEqual(0); 12 | // }); 13 | 14 | // // it('should fallback to 1:1 by default', () => { 15 | // // const localVue = createLocalVue() 16 | // // const wrapper = mount(Test, { 17 | // // localVue 18 | // // }) 19 | // // const contentWrapper = wrapper.find(".content") 20 | 21 | // // }); 22 | // }) 23 | -------------------------------------------------------------------------------- /tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | // if you need a custom webpack configuration you can uncomment the following import 4 | // and then use the `file:preprocessor` event 5 | // as explained in the cypress docs 6 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples 7 | 8 | /* eslint-disable import/no-extraneous-dependencies, global-require, arrow-body-style */ 9 | // const webpack = require('@cypress/webpack-preprocessor') 10 | 11 | module.exports = (on, config) => { 12 | // on('file:preprocessor', webpack({ 13 | // webpackOptions: require('@vue/cli-service/webpack.config'), 14 | // watchOptions: {} 15 | // })) 16 | 17 | return Object.assign({}, config, { 18 | fixturesFolder: 'tests/e2e/fixtures', 19 | integrationFolder: 'tests/e2e/specs', 20 | screenshotsFolder: 'tests/e2e/screenshots', 21 | videosFolder: 'tests/e2e/videos', 22 | supportFile: 'tests/e2e/support/index.js' 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alberto De Agostini 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe("VueAspectRatio", () => { 4 | it("should open the app root url", () => { 5 | cy.visit("localhost:8080") 6 | cy.contains("h1", "Vue Aspect Ratio") 7 | }); 8 | 9 | it("should fallback aspect-ratio 1:1 if none is proved", () => { 10 | cy.visit("localhost:8080") 11 | cy.get(".content-2").should($div => { 12 | const style = window.getComputedStyle($div[0]) 13 | expect(style.height).to.equal("150px") 14 | }) 15 | }); 16 | 17 | it("should render a correct 16:9 aspect ratio if given", () => { 18 | cy.visit("localhost:8080") 19 | cy.get(".content-3").should($div => { 20 | const style = window.getComputedStyle($div[0]) 21 | expect(style.height).to.equal("180px") 22 | }) 23 | }); 24 | 25 | it("should render a correct 1:2 aspect ratio if given", () => { 26 | cy.visit("localhost:8080") 27 | cy.get(".content-4").should($div => { 28 | const style = window.getComputedStyle($div[0]) 29 | expect(style.height).to.equal("200px") 30 | }) 31 | }); 32 | 33 | it("should not define width if not specified", () => { 34 | cy.visit("localhost:8080") 35 | cy.get(".vue-ar1 > .vue-aspect-ratio").should($div => { 36 | const height = $div[0].style.height 37 | expect(height).to.equal("") 38 | }) 39 | }); 40 | 41 | it("should set width of the element if specified", () => { 42 | cy.visit("localhost:8080") 43 | cy.get(".vue-ar2 > .vue-aspect-ratio").should($div => { 44 | const inlineStyle = $div[0].getAttribute("style"); 45 | expect(inlineStyle).to.equal("width: 150px;") 46 | }) 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "albertodeagostini.dev@gmail.com", 3 | "name": "vue-aspect-ratio", 4 | "version": "0.1.1", 5 | "scripts": { 6 | "docs": "npm run docs:serve", 7 | "docs:build": "vue-cli-service docs --mode build", 8 | "docs:serve": "vue-cli-service docs --mode serve", 9 | "dev": "vue-cli-service serve", 10 | "build": "vue-cli-service build", 11 | "lint": "vue-cli-service lint", 12 | "test:open": "npx cypress open", 13 | "test": "npx cypress run", 14 | "prepublish": "vue-cli-service lint && vue-cli-service docs --mode build && vue-cli-service build" 15 | }, 16 | "main": "dist/vue-aspect-ratio.common.js", 17 | "module": "dist/vue-aspect-ratio.esm.js", 18 | "unpkg": "dist/vue-aspect-ratio.umd.min.js", 19 | "files": [ 20 | "dist/vue-aspect-ratio.common.js", 21 | "dist/vue-aspect-ratio.umd.min.js", 22 | "dist/vue-aspect-ratio.umd.js", 23 | "dist/vue-aspect-ratio.esm.js", 24 | "src" 25 | ], 26 | "dependencies": { 27 | "core-js": "^3.3.2" 28 | }, 29 | "devDependencies": { 30 | "@vue/cli-plugin-babel": "^5.0.9", 31 | "@vue/cli-plugin-e2e-cypress": "^5.0.9", 32 | "@vue/cli-plugin-eslint": "^5.0.9", 33 | "@vue/cli-plugin-unit-jest": "^5.0.9", 34 | "@vue/cli-service": "^5.0.9", 35 | "@vue/test-utils": "1.0.0-beta.29", 36 | "babel-eslint": "^10.0.3", 37 | "eslint": "^5.16.0", 38 | "eslint-plugin-vue": "^5.0.0", 39 | "vue-cli-plugin-p11n": "^0.4.0", 40 | "vue-template-compiler": "^2.6.10", 41 | "vue": "^2.6.10" 42 | }, 43 | "repository": { 44 | "type": "git", 45 | "url": "https://github.com/albertodeago/vue-aspect-ratio.git" 46 | }, 47 | "bugs": { 48 | "url": "https://github.com/albertodeago/vue-aspect-ratio/issues" 49 | }, 50 | "homepage": "https://github.com/albertodeago/vue-aspect-ratio/blob/master/README.md", 51 | "jsdelivr": "dist/vue-aspect-ratio.umd.min.js", 52 | "license": "MIT", 53 | "sideeffects": false 54 | } -------------------------------------------------------------------------------- /src/AspectRatio.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 72 | 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![screenshot](https://raw.githubusercontent.com/albertodeago/vue-aspect-ratio/master/assets/screen.png) 2 | 3 | # vue-aspect-ratio 4 | 5 | A component to render a certain aspect ratio element without javascript computations. 6 | It exposes a default slot that will have the desided ratio. 7 | Weights 3.8kb not gzipped. No dependencies. 8 | 100% responsive 9 | 10 | ![responsiveness gif](https://raw.githubusercontent.com/albertodeago/vue-aspect-ratio/master/assets/responsive.gif) 11 | 12 | Buy Me A Coffee 13 | 14 | 15 | ## How to install and use 16 | 17 | To install the package in your application just type 18 | ``` 19 | npm install vue-aspect-ratio 20 | ``` 21 | 22 | Then, to install as a global component 23 | ``` javascript 24 | import Vue from "vue"; 25 | import VueAspectRatio from "vue-aspect-ratio"; 26 | 27 | Vue.component("vue-aspect-ratio", VueAspectRatio) 28 | ``` 29 | 30 | Or you can register locally in one of your components as follows 31 | ``` javascript 32 | import VueAspectRatio from "vue-aspect-ratio"; 33 | 34 | export default { 35 | name: "AmazingComponent", 36 | props: [myprop], 37 | components: { 38 | "vue-aspect-ratio": VueAspectRatio 39 | } 40 | } 41 | ``` 42 | 43 | Using in templates 44 | ``` html 45 |
46 | 47 |
your content goes here
48 |
49 |
50 | ``` 51 | 52 | NOTE: You may need to set in css "height: 100%" on your content that goes inside vue-aspect-ratio to fill the entire space if your content is not long enough. 53 | 54 | ## Parameters and events 55 | 56 | Component props: 57 | 58 | | Name | Type | Mandatory | Example | Description | 59 | |--------|--------|-----------|---------|------------------| 60 | | ar | String | false | "16:9" | the aspect ratio | 61 | | width | String | false | "640px" | the css value of the width to set on the element | 62 | 63 | It does not emit any event 64 | 65 | ## Contributing 66 | 67 | The project is opened to contributes, suggestions and improvements. You can use the [Issues](https://github.com/albertodeago/vue-aspect-ratio/issues) section. 68 | 69 | 70 | ### Project setup 71 | 72 | Fork the project, open it up and type 73 | ``` 74 | npm install 75 | ``` 76 | 77 | To run the example page, it will open a dev server listening to localhost:8080 (usually), type: 78 | ``` 79 | npm run dev 80 | ``` 81 | 82 | To build for production 83 | ``` 84 | npm run build 85 | ``` 86 | 87 | To lint the project 88 | ``` 89 | npm run lint 90 | ``` 91 | 92 | To prepare for pubblication 93 | ``` 94 | npm run prepublish 95 | ``` 96 | 97 | ### Test 98 | 99 | The project uses [Cypress](https://www.cypress.io/) 100 | If you want to open the interactive cypress dashboard to run and check tests 101 | ``` 102 | npm run test:open 103 | ``` 104 | 105 | If you instead just want to run the tests in headless mode 106 | ``` 107 | npm run test 108 | ``` 109 | 110 | Note: tests required dev server to be up and running 111 | 112 | ## Author and License 113 | 114 | [Alberto De Agostini](https://twitter.com/albertodeago88) 115 | 116 | Licensed under MIT 117 | -------------------------------------------------------------------------------- /dist/vue-aspect-ratio.umd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-aspect-ratio v0.1.1 3 | * (c) 2019 albertodeagostini.dev@gmail.com 4 | * Released under the MIT License. 5 | */ 6 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,e.VueAspectRatio=t())}(this,function(){"use strict";function e(e,i){return t(e)||n(e,i)||r()}function t(e){if(Array.isArray(e))return e}function n(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{r||null==s.return||s.return()}finally{if(i)throw o}}return n}}function r(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function i(e,t,n,r,i,o,a,s,d,u){"boolean"!=typeof a&&(d=s,s=a,a=!1);var c="function"==typeof n?n.options:n;e&&e.render&&(c.render=e.render,c.staticRenderFns=e.staticRenderFns,c._compiled=!0,i&&(c.functional=!0)),r&&(c._scopeId=r);var l;if(o?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,d(e)),e&&e._registeredComponents&&e._registeredComponents.add(o)},c._ssrRegister=l):t&&(l=a?function(){t.call(this,u(this.$root.$options.shadowRoot))}:function(e){t.call(this,s(e))}),l)if(c.functional){var f=c.render;c.render=function(e,t){return l.call(t),f(e,t)}}else{var p=c.beforeCreate;c.beforeCreate=p?[].concat(p,l):[l]}return n}function o(e){return function(e,t){return a(e,t)}}function a(e,t){var n=u?t.media||"default":e,r=l[n]||(l[n]={ids:new Set,styles:[]});if(!r.ids.has(e)){r.ids.add(e);var i=t.source;if(t.map&&(i+="\n/*# sourceURL="+t.map.sources[0]+" */",i+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t.map))))+" */"),r.element||(r.element=document.createElement("style"),r.element.type="text/css",t.media&&r.element.setAttribute("media",t.media),c.appendChild(r.element)),"styleSheet"in r.element)r.styles.push(i),r.element.styleSheet.cssText=r.styles.filter(Boolean).join("\n");else{var o=r.ids.size-1,a=document.createTextNode(i),s=r.element.childNodes;s[o]&&r.element.removeChild(s[o]),s.length?r.element.insertBefore(a,s[o]):r.element.appendChild(a)}}}var s={name:"VueAspectRatio",props:{ar:{type:String,default:"1:1",validator:function(t){var n=t.split(":").map(function(e){return parseInt(e)}),r=e(n,2),i=r[0],o=r[1];return!Number.isNaN(i)&&!Number.isNaN(o)}},width:String},data:function(){return{w:null,h:null}},computed:{componentStyle:function(){return this.width?{width:this.width}:{}},innerStyle:function(){return{paddingTop:this.h/this.w*100+"%"}}},created:function(){var t=this.ar.split(":").map(function(e){return parseInt(e)}),n=e(t,2),r=n[0],i=n[1];this.w=r,this.h=i}},d=i,u="undefined"!=typeof navigator&&/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()),c=document.head||document.getElementsByTagName("head")[0],l={},f=o;const p=s;var m=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"vue-aspect-ratio",style:e.componentStyle},[n("div",{staticClass:"vue-aspect-ratio__inner",style:e.innerStyle},[n("div",{staticClass:"vue-aspect-ratio__content"},[e._t("default")],2)])])},h=[];const v=function(e){e&&e("data-v-f0460d78_0",{source:".vue-aspect-ratio__inner[data-v-f0460d78]{position:relative}.vue-aspect-ratio__content[data-v-f0460d78]{position:absolute;top:0;left:0;width:100%;height:100%}",map:void 0,media:void 0})};var y=d({render:m,staticRenderFns:h},v,p,"data-v-f0460d78",!1,void 0,f,void 0),_=Object.freeze({__proto__:null,default:y});return function(e){return e&&e.default||e}(_)}); -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /dist/vue-aspect-ratio.esm.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-aspect-ratio v0.1.1 3 | * (c) 2019 albertodeagostini.dev@gmail.com 4 | * Released under the MIT License. 5 | */ 6 | function _slicedToArray(arr, i) { 7 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); 8 | } 9 | 10 | function _arrayWithHoles(arr) { 11 | if (Array.isArray(arr)) return arr; 12 | } 13 | 14 | function _iterableToArrayLimit(arr, i) { 15 | if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { 16 | return; 17 | } 18 | 19 | var _arr = []; 20 | var _n = true; 21 | var _d = false; 22 | var _e = undefined; 23 | 24 | try { 25 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 26 | _arr.push(_s.value); 27 | 28 | if (i && _arr.length === i) break; 29 | } 30 | } catch (err) { 31 | _d = true; 32 | _e = err; 33 | } finally { 34 | try { 35 | if (!_n && _i["return"] != null) _i["return"](); 36 | } finally { 37 | if (_d) throw _e; 38 | } 39 | } 40 | 41 | return _arr; 42 | } 43 | 44 | function _nonIterableRest() { 45 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 46 | } 47 | 48 | // 49 | // 50 | // 51 | // 52 | // 53 | // 54 | // 55 | // 56 | // 57 | // 58 | var script = { 59 | name: "VueAspectRatio", 60 | props: { 61 | /** 62 | * Aspect Ratio. 63 | * String with the following pattern 64 | * : 65 | * Default is "1:1" meaning that the component will be a square 66 | */ 67 | ar: { 68 | type: String, 69 | default: "1:1", 70 | validator: function validator(v) { 71 | var _v$split$map = v.split(":").map(function (v) { 72 | return parseInt(v); 73 | }), 74 | _v$split$map2 = _slicedToArray(_v$split$map, 2), 75 | w = _v$split$map2[0], 76 | h = _v$split$map2[1]; 77 | 78 | return !Number.isNaN(w) && !Number.isNaN(h); 79 | } 80 | }, 81 | 82 | /** 83 | * Width to set to the component. 84 | * Optional, if not set the width will be 100% like a normal "div" element 85 | */ 86 | width: String 87 | }, 88 | data: function data() { 89 | return { 90 | w: null, 91 | // width of the aspect ratio 92 | h: null // height of the aspect ratio 93 | 94 | }; 95 | }, 96 | computed: { 97 | /** 98 | * Style for the outer div element, this can just set the width of the component itself 99 | */ 100 | componentStyle: function componentStyle() { 101 | return this.width ? { 102 | width: this.width 103 | } : {}; 104 | }, 105 | 106 | /** 107 | * Style for the inner div element, this will define the aspect ratio 108 | */ 109 | innerStyle: function innerStyle() { 110 | // set the padding top, this is actually what gives the aspect ratio 111 | return { 112 | paddingTop: this.h / this.w * 100 + "%" 113 | }; 114 | } 115 | }, 116 | created: function created() { 117 | // set w and h data parsing the ar prop 118 | var _this$ar$split$map = this.ar.split(":").map(function (v) { 119 | return parseInt(v); 120 | }), 121 | _this$ar$split$map2 = _slicedToArray(_this$ar$split$map, 2), 122 | w = _this$ar$split$map2[0], 123 | h = _this$ar$split$map2[1]; 124 | 125 | this.w = w; 126 | this.h = h; 127 | } 128 | }; 129 | 130 | function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier 131 | /* server only */ 132 | , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { 133 | if (typeof shadowMode !== 'boolean') { 134 | createInjectorSSR = createInjector; 135 | createInjector = shadowMode; 136 | shadowMode = false; 137 | } // Vue.extend constructor export interop. 138 | 139 | 140 | var options = typeof script === 'function' ? script.options : script; // render functions 141 | 142 | if (template && template.render) { 143 | options.render = template.render; 144 | options.staticRenderFns = template.staticRenderFns; 145 | options._compiled = true; // functional template 146 | 147 | if (isFunctionalTemplate) { 148 | options.functional = true; 149 | } 150 | } // scopedId 151 | 152 | 153 | if (scopeId) { 154 | options._scopeId = scopeId; 155 | } 156 | 157 | var hook; 158 | 159 | if (moduleIdentifier) { 160 | // server build 161 | hook = function hook(context) { 162 | // 2.3 injection 163 | context = context || // cached call 164 | this.$vnode && this.$vnode.ssrContext || // stateful 165 | this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional 166 | // 2.2 with runInNewContext: true 167 | 168 | if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { 169 | context = __VUE_SSR_CONTEXT__; 170 | } // inject component styles 171 | 172 | 173 | if (style) { 174 | style.call(this, createInjectorSSR(context)); 175 | } // register component module identifier for async chunk inference 176 | 177 | 178 | if (context && context._registeredComponents) { 179 | context._registeredComponents.add(moduleIdentifier); 180 | } 181 | }; // used by ssr in case component is cached and beforeCreate 182 | // never gets called 183 | 184 | 185 | options._ssrRegister = hook; 186 | } else if (style) { 187 | hook = shadowMode ? function () { 188 | style.call(this, createInjectorShadow(this.$root.$options.shadowRoot)); 189 | } : function (context) { 190 | style.call(this, createInjector(context)); 191 | }; 192 | } 193 | 194 | if (hook) { 195 | if (options.functional) { 196 | // register for functional component in vue file 197 | var originalRender = options.render; 198 | 199 | options.render = function renderWithStyleInjection(h, context) { 200 | hook.call(context); 201 | return originalRender(h, context); 202 | }; 203 | } else { 204 | // inject component registration as beforeCreate hook 205 | var existing = options.beforeCreate; 206 | options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; 207 | } 208 | } 209 | 210 | return script; 211 | } 212 | 213 | var normalizeComponent_1 = normalizeComponent; 214 | 215 | var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); 216 | 217 | function createInjector(context) { 218 | return function (id, style) { 219 | return addStyle(id, style); 220 | }; 221 | } 222 | 223 | var HEAD = document.head || document.getElementsByTagName('head')[0]; 224 | var styles = {}; 225 | 226 | function addStyle(id, css) { 227 | var group = isOldIE ? css.media || 'default' : id; 228 | var style = styles[group] || (styles[group] = { 229 | ids: new Set(), 230 | styles: [] 231 | }); 232 | 233 | if (!style.ids.has(id)) { 234 | style.ids.add(id); 235 | var code = css.source; 236 | 237 | if (css.map) { 238 | // https://developer.chrome.com/devtools/docs/javascript-debugging 239 | // this makes source maps inside style tags work properly in Chrome 240 | code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; // http://stackoverflow.com/a/26603875 241 | 242 | code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; 243 | } 244 | 245 | if (!style.element) { 246 | style.element = document.createElement('style'); 247 | style.element.type = 'text/css'; 248 | if (css.media) style.element.setAttribute('media', css.media); 249 | HEAD.appendChild(style.element); 250 | } 251 | 252 | if ('styleSheet' in style.element) { 253 | style.styles.push(code); 254 | style.element.styleSheet.cssText = style.styles.filter(Boolean).join('\n'); 255 | } else { 256 | var index = style.ids.size - 1; 257 | var textNode = document.createTextNode(code); 258 | var nodes = style.element.childNodes; 259 | if (nodes[index]) style.element.removeChild(nodes[index]); 260 | if (nodes.length) style.element.insertBefore(textNode, nodes[index]);else style.element.appendChild(textNode); 261 | } 262 | } 263 | } 264 | 265 | var browser = createInjector; 266 | 267 | /* script */ 268 | const __vue_script__ = script; 269 | 270 | /* template */ 271 | var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-aspect-ratio",style:(_vm.componentStyle)},[_c('div',{staticClass:"vue-aspect-ratio__inner",style:(_vm.innerStyle)},[_c('div',{staticClass:"vue-aspect-ratio__content"},[_vm._t("default")],2)])])}; 272 | var __vue_staticRenderFns__ = []; 273 | 274 | /* style */ 275 | const __vue_inject_styles__ = function (inject) { 276 | if (!inject) return 277 | inject("data-v-f0460d78_0", { source: ".vue-aspect-ratio__inner[data-v-f0460d78]{position:relative}.vue-aspect-ratio__content[data-v-f0460d78]{position:absolute;top:0;left:0;width:100%;height:100%}", map: undefined, media: undefined }); 278 | 279 | }; 280 | /* scoped */ 281 | const __vue_scope_id__ = "data-v-f0460d78"; 282 | /* module identifier */ 283 | const __vue_module_identifier__ = undefined; 284 | /* functional template */ 285 | const __vue_is_functional_template__ = false; 286 | /* style inject SSR */ 287 | 288 | 289 | 290 | var AspectRatio = normalizeComponent_1( 291 | { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, 292 | __vue_inject_styles__, 293 | __vue_script__, 294 | __vue_scope_id__, 295 | __vue_is_functional_template__, 296 | __vue_module_identifier__, 297 | browser, 298 | undefined 299 | ); 300 | 301 | var AspectRatio$1 = /*#__PURE__*/Object.freeze({ 302 | __proto__: null, 303 | 'default': AspectRatio 304 | }); 305 | 306 | function getCjsExportFromNamespace (n) { 307 | return n && n['default'] || n; 308 | } 309 | 310 | var require$$0 = getCjsExportFromNamespace(AspectRatio$1); 311 | 312 | var src = require$$0; 313 | 314 | export default src; 315 | -------------------------------------------------------------------------------- /dist/vue-aspect-ratio.common.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-aspect-ratio v0.1.1 3 | * (c) 2019 albertodeagostini.dev@gmail.com 4 | * Released under the MIT License. 5 | */ 6 | 'use strict'; 7 | 8 | function _slicedToArray(arr, i) { 9 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); 10 | } 11 | 12 | function _arrayWithHoles(arr) { 13 | if (Array.isArray(arr)) return arr; 14 | } 15 | 16 | function _iterableToArrayLimit(arr, i) { 17 | if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { 18 | return; 19 | } 20 | 21 | var _arr = []; 22 | var _n = true; 23 | var _d = false; 24 | var _e = undefined; 25 | 26 | try { 27 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 28 | _arr.push(_s.value); 29 | 30 | if (i && _arr.length === i) break; 31 | } 32 | } catch (err) { 33 | _d = true; 34 | _e = err; 35 | } finally { 36 | try { 37 | if (!_n && _i["return"] != null) _i["return"](); 38 | } finally { 39 | if (_d) throw _e; 40 | } 41 | } 42 | 43 | return _arr; 44 | } 45 | 46 | function _nonIterableRest() { 47 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 48 | } 49 | 50 | // 51 | // 52 | // 53 | // 54 | // 55 | // 56 | // 57 | // 58 | // 59 | // 60 | var script = { 61 | name: "VueAspectRatio", 62 | props: { 63 | /** 64 | * Aspect Ratio. 65 | * String with the following pattern 66 | * : 67 | * Default is "1:1" meaning that the component will be a square 68 | */ 69 | ar: { 70 | type: String, 71 | default: "1:1", 72 | validator: function validator(v) { 73 | var _v$split$map = v.split(":").map(function (v) { 74 | return parseInt(v); 75 | }), 76 | _v$split$map2 = _slicedToArray(_v$split$map, 2), 77 | w = _v$split$map2[0], 78 | h = _v$split$map2[1]; 79 | 80 | return !Number.isNaN(w) && !Number.isNaN(h); 81 | } 82 | }, 83 | 84 | /** 85 | * Width to set to the component. 86 | * Optional, if not set the width will be 100% like a normal "div" element 87 | */ 88 | width: String 89 | }, 90 | data: function data() { 91 | return { 92 | w: null, 93 | // width of the aspect ratio 94 | h: null // height of the aspect ratio 95 | 96 | }; 97 | }, 98 | computed: { 99 | /** 100 | * Style for the outer div element, this can just set the width of the component itself 101 | */ 102 | componentStyle: function componentStyle() { 103 | return this.width ? { 104 | width: this.width 105 | } : {}; 106 | }, 107 | 108 | /** 109 | * Style for the inner div element, this will define the aspect ratio 110 | */ 111 | innerStyle: function innerStyle() { 112 | // set the padding top, this is actually what gives the aspect ratio 113 | return { 114 | paddingTop: this.h / this.w * 100 + "%" 115 | }; 116 | } 117 | }, 118 | created: function created() { 119 | // set w and h data parsing the ar prop 120 | var _this$ar$split$map = this.ar.split(":").map(function (v) { 121 | return parseInt(v); 122 | }), 123 | _this$ar$split$map2 = _slicedToArray(_this$ar$split$map, 2), 124 | w = _this$ar$split$map2[0], 125 | h = _this$ar$split$map2[1]; 126 | 127 | this.w = w; 128 | this.h = h; 129 | } 130 | }; 131 | 132 | function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier 133 | /* server only */ 134 | , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { 135 | if (typeof shadowMode !== 'boolean') { 136 | createInjectorSSR = createInjector; 137 | createInjector = shadowMode; 138 | shadowMode = false; 139 | } // Vue.extend constructor export interop. 140 | 141 | 142 | var options = typeof script === 'function' ? script.options : script; // render functions 143 | 144 | if (template && template.render) { 145 | options.render = template.render; 146 | options.staticRenderFns = template.staticRenderFns; 147 | options._compiled = true; // functional template 148 | 149 | if (isFunctionalTemplate) { 150 | options.functional = true; 151 | } 152 | } // scopedId 153 | 154 | 155 | if (scopeId) { 156 | options._scopeId = scopeId; 157 | } 158 | 159 | var hook; 160 | 161 | if (moduleIdentifier) { 162 | // server build 163 | hook = function hook(context) { 164 | // 2.3 injection 165 | context = context || // cached call 166 | this.$vnode && this.$vnode.ssrContext || // stateful 167 | this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional 168 | // 2.2 with runInNewContext: true 169 | 170 | if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { 171 | context = __VUE_SSR_CONTEXT__; 172 | } // inject component styles 173 | 174 | 175 | if (style) { 176 | style.call(this, createInjectorSSR(context)); 177 | } // register component module identifier for async chunk inference 178 | 179 | 180 | if (context && context._registeredComponents) { 181 | context._registeredComponents.add(moduleIdentifier); 182 | } 183 | }; // used by ssr in case component is cached and beforeCreate 184 | // never gets called 185 | 186 | 187 | options._ssrRegister = hook; 188 | } else if (style) { 189 | hook = shadowMode ? function () { 190 | style.call(this, createInjectorShadow(this.$root.$options.shadowRoot)); 191 | } : function (context) { 192 | style.call(this, createInjector(context)); 193 | }; 194 | } 195 | 196 | if (hook) { 197 | if (options.functional) { 198 | // register for functional component in vue file 199 | var originalRender = options.render; 200 | 201 | options.render = function renderWithStyleInjection(h, context) { 202 | hook.call(context); 203 | return originalRender(h, context); 204 | }; 205 | } else { 206 | // inject component registration as beforeCreate hook 207 | var existing = options.beforeCreate; 208 | options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; 209 | } 210 | } 211 | 212 | return script; 213 | } 214 | 215 | var normalizeComponent_1 = normalizeComponent; 216 | 217 | var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); 218 | 219 | function createInjector(context) { 220 | return function (id, style) { 221 | return addStyle(id, style); 222 | }; 223 | } 224 | 225 | var HEAD = document.head || document.getElementsByTagName('head')[0]; 226 | var styles = {}; 227 | 228 | function addStyle(id, css) { 229 | var group = isOldIE ? css.media || 'default' : id; 230 | var style = styles[group] || (styles[group] = { 231 | ids: new Set(), 232 | styles: [] 233 | }); 234 | 235 | if (!style.ids.has(id)) { 236 | style.ids.add(id); 237 | var code = css.source; 238 | 239 | if (css.map) { 240 | // https://developer.chrome.com/devtools/docs/javascript-debugging 241 | // this makes source maps inside style tags work properly in Chrome 242 | code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; // http://stackoverflow.com/a/26603875 243 | 244 | code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; 245 | } 246 | 247 | if (!style.element) { 248 | style.element = document.createElement('style'); 249 | style.element.type = 'text/css'; 250 | if (css.media) style.element.setAttribute('media', css.media); 251 | HEAD.appendChild(style.element); 252 | } 253 | 254 | if ('styleSheet' in style.element) { 255 | style.styles.push(code); 256 | style.element.styleSheet.cssText = style.styles.filter(Boolean).join('\n'); 257 | } else { 258 | var index = style.ids.size - 1; 259 | var textNode = document.createTextNode(code); 260 | var nodes = style.element.childNodes; 261 | if (nodes[index]) style.element.removeChild(nodes[index]); 262 | if (nodes.length) style.element.insertBefore(textNode, nodes[index]);else style.element.appendChild(textNode); 263 | } 264 | } 265 | } 266 | 267 | var browser = createInjector; 268 | 269 | /* script */ 270 | const __vue_script__ = script; 271 | 272 | /* template */ 273 | var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-aspect-ratio",style:(_vm.componentStyle)},[_c('div',{staticClass:"vue-aspect-ratio__inner",style:(_vm.innerStyle)},[_c('div',{staticClass:"vue-aspect-ratio__content"},[_vm._t("default")],2)])])}; 274 | var __vue_staticRenderFns__ = []; 275 | 276 | /* style */ 277 | const __vue_inject_styles__ = function (inject) { 278 | if (!inject) return 279 | inject("data-v-f0460d78_0", { source: ".vue-aspect-ratio__inner[data-v-f0460d78]{position:relative}.vue-aspect-ratio__content[data-v-f0460d78]{position:absolute;top:0;left:0;width:100%;height:100%}", map: undefined, media: undefined }); 280 | 281 | }; 282 | /* scoped */ 283 | const __vue_scope_id__ = "data-v-f0460d78"; 284 | /* module identifier */ 285 | const __vue_module_identifier__ = undefined; 286 | /* functional template */ 287 | const __vue_is_functional_template__ = false; 288 | /* style inject SSR */ 289 | 290 | 291 | 292 | var AspectRatio = normalizeComponent_1( 293 | { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, 294 | __vue_inject_styles__, 295 | __vue_script__, 296 | __vue_scope_id__, 297 | __vue_is_functional_template__, 298 | __vue_module_identifier__, 299 | browser, 300 | undefined 301 | ); 302 | 303 | var AspectRatio$1 = /*#__PURE__*/Object.freeze({ 304 | __proto__: null, 305 | 'default': AspectRatio 306 | }); 307 | 308 | function getCjsExportFromNamespace (n) { 309 | return n && n['default'] || n; 310 | } 311 | 312 | var require$$0 = getCjsExportFromNamespace(AspectRatio$1); 313 | 314 | var src = require$$0; 315 | 316 | module.exports = src; 317 | -------------------------------------------------------------------------------- /dist/vue-aspect-ratio.umd.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-aspect-ratio v0.1.1 3 | * (c) 2019 albertodeagostini.dev@gmail.com 4 | * Released under the MIT License. 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global = global || self, global.VueAspectRatio = factory()); 10 | }(this, (function () { 'use strict'; 11 | 12 | function _slicedToArray(arr, i) { 13 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); 14 | } 15 | 16 | function _arrayWithHoles(arr) { 17 | if (Array.isArray(arr)) return arr; 18 | } 19 | 20 | function _iterableToArrayLimit(arr, i) { 21 | if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { 22 | return; 23 | } 24 | 25 | var _arr = []; 26 | var _n = true; 27 | var _d = false; 28 | var _e = undefined; 29 | 30 | try { 31 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 32 | _arr.push(_s.value); 33 | 34 | if (i && _arr.length === i) break; 35 | } 36 | } catch (err) { 37 | _d = true; 38 | _e = err; 39 | } finally { 40 | try { 41 | if (!_n && _i["return"] != null) _i["return"](); 42 | } finally { 43 | if (_d) throw _e; 44 | } 45 | } 46 | 47 | return _arr; 48 | } 49 | 50 | function _nonIterableRest() { 51 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 52 | } 53 | 54 | // 55 | // 56 | // 57 | // 58 | // 59 | // 60 | // 61 | // 62 | // 63 | // 64 | var script = { 65 | name: "VueAspectRatio", 66 | props: { 67 | /** 68 | * Aspect Ratio. 69 | * String with the following pattern 70 | * : 71 | * Default is "1:1" meaning that the component will be a square 72 | */ 73 | ar: { 74 | type: String, 75 | default: "1:1", 76 | validator: function validator(v) { 77 | var _v$split$map = v.split(":").map(function (v) { 78 | return parseInt(v); 79 | }), 80 | _v$split$map2 = _slicedToArray(_v$split$map, 2), 81 | w = _v$split$map2[0], 82 | h = _v$split$map2[1]; 83 | 84 | return !Number.isNaN(w) && !Number.isNaN(h); 85 | } 86 | }, 87 | 88 | /** 89 | * Width to set to the component. 90 | * Optional, if not set the width will be 100% like a normal "div" element 91 | */ 92 | width: String 93 | }, 94 | data: function data() { 95 | return { 96 | w: null, 97 | // width of the aspect ratio 98 | h: null // height of the aspect ratio 99 | 100 | }; 101 | }, 102 | computed: { 103 | /** 104 | * Style for the outer div element, this can just set the width of the component itself 105 | */ 106 | componentStyle: function componentStyle() { 107 | return this.width ? { 108 | width: this.width 109 | } : {}; 110 | }, 111 | 112 | /** 113 | * Style for the inner div element, this will define the aspect ratio 114 | */ 115 | innerStyle: function innerStyle() { 116 | // set the padding top, this is actually what gives the aspect ratio 117 | return { 118 | paddingTop: this.h / this.w * 100 + "%" 119 | }; 120 | } 121 | }, 122 | created: function created() { 123 | // set w and h data parsing the ar prop 124 | var _this$ar$split$map = this.ar.split(":").map(function (v) { 125 | return parseInt(v); 126 | }), 127 | _this$ar$split$map2 = _slicedToArray(_this$ar$split$map, 2), 128 | w = _this$ar$split$map2[0], 129 | h = _this$ar$split$map2[1]; 130 | 131 | this.w = w; 132 | this.h = h; 133 | } 134 | }; 135 | 136 | function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier 137 | /* server only */ 138 | , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { 139 | if (typeof shadowMode !== 'boolean') { 140 | createInjectorSSR = createInjector; 141 | createInjector = shadowMode; 142 | shadowMode = false; 143 | } // Vue.extend constructor export interop. 144 | 145 | 146 | var options = typeof script === 'function' ? script.options : script; // render functions 147 | 148 | if (template && template.render) { 149 | options.render = template.render; 150 | options.staticRenderFns = template.staticRenderFns; 151 | options._compiled = true; // functional template 152 | 153 | if (isFunctionalTemplate) { 154 | options.functional = true; 155 | } 156 | } // scopedId 157 | 158 | 159 | if (scopeId) { 160 | options._scopeId = scopeId; 161 | } 162 | 163 | var hook; 164 | 165 | if (moduleIdentifier) { 166 | // server build 167 | hook = function hook(context) { 168 | // 2.3 injection 169 | context = context || // cached call 170 | this.$vnode && this.$vnode.ssrContext || // stateful 171 | this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional 172 | // 2.2 with runInNewContext: true 173 | 174 | if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { 175 | context = __VUE_SSR_CONTEXT__; 176 | } // inject component styles 177 | 178 | 179 | if (style) { 180 | style.call(this, createInjectorSSR(context)); 181 | } // register component module identifier for async chunk inference 182 | 183 | 184 | if (context && context._registeredComponents) { 185 | context._registeredComponents.add(moduleIdentifier); 186 | } 187 | }; // used by ssr in case component is cached and beforeCreate 188 | // never gets called 189 | 190 | 191 | options._ssrRegister = hook; 192 | } else if (style) { 193 | hook = shadowMode ? function () { 194 | style.call(this, createInjectorShadow(this.$root.$options.shadowRoot)); 195 | } : function (context) { 196 | style.call(this, createInjector(context)); 197 | }; 198 | } 199 | 200 | if (hook) { 201 | if (options.functional) { 202 | // register for functional component in vue file 203 | var originalRender = options.render; 204 | 205 | options.render = function renderWithStyleInjection(h, context) { 206 | hook.call(context); 207 | return originalRender(h, context); 208 | }; 209 | } else { 210 | // inject component registration as beforeCreate hook 211 | var existing = options.beforeCreate; 212 | options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; 213 | } 214 | } 215 | 216 | return script; 217 | } 218 | 219 | var normalizeComponent_1 = normalizeComponent; 220 | 221 | var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); 222 | 223 | function createInjector(context) { 224 | return function (id, style) { 225 | return addStyle(id, style); 226 | }; 227 | } 228 | 229 | var HEAD = document.head || document.getElementsByTagName('head')[0]; 230 | var styles = {}; 231 | 232 | function addStyle(id, css) { 233 | var group = isOldIE ? css.media || 'default' : id; 234 | var style = styles[group] || (styles[group] = { 235 | ids: new Set(), 236 | styles: [] 237 | }); 238 | 239 | if (!style.ids.has(id)) { 240 | style.ids.add(id); 241 | var code = css.source; 242 | 243 | if (css.map) { 244 | // https://developer.chrome.com/devtools/docs/javascript-debugging 245 | // this makes source maps inside style tags work properly in Chrome 246 | code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; // http://stackoverflow.com/a/26603875 247 | 248 | code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; 249 | } 250 | 251 | if (!style.element) { 252 | style.element = document.createElement('style'); 253 | style.element.type = 'text/css'; 254 | if (css.media) style.element.setAttribute('media', css.media); 255 | HEAD.appendChild(style.element); 256 | } 257 | 258 | if ('styleSheet' in style.element) { 259 | style.styles.push(code); 260 | style.element.styleSheet.cssText = style.styles.filter(Boolean).join('\n'); 261 | } else { 262 | var index = style.ids.size - 1; 263 | var textNode = document.createTextNode(code); 264 | var nodes = style.element.childNodes; 265 | if (nodes[index]) style.element.removeChild(nodes[index]); 266 | if (nodes.length) style.element.insertBefore(textNode, nodes[index]);else style.element.appendChild(textNode); 267 | } 268 | } 269 | } 270 | 271 | var browser = createInjector; 272 | 273 | /* script */ 274 | const __vue_script__ = script; 275 | 276 | /* template */ 277 | var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-aspect-ratio",style:(_vm.componentStyle)},[_c('div',{staticClass:"vue-aspect-ratio__inner",style:(_vm.innerStyle)},[_c('div',{staticClass:"vue-aspect-ratio__content"},[_vm._t("default")],2)])])}; 278 | var __vue_staticRenderFns__ = []; 279 | 280 | /* style */ 281 | const __vue_inject_styles__ = function (inject) { 282 | if (!inject) return 283 | inject("data-v-f0460d78_0", { source: ".vue-aspect-ratio__inner[data-v-f0460d78]{position:relative}.vue-aspect-ratio__content[data-v-f0460d78]{position:absolute;top:0;left:0;width:100%;height:100%}", map: undefined, media: undefined }); 284 | 285 | }; 286 | /* scoped */ 287 | const __vue_scope_id__ = "data-v-f0460d78"; 288 | /* module identifier */ 289 | const __vue_module_identifier__ = undefined; 290 | /* functional template */ 291 | const __vue_is_functional_template__ = false; 292 | /* style inject SSR */ 293 | 294 | 295 | 296 | var AspectRatio = normalizeComponent_1( 297 | { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, 298 | __vue_inject_styles__, 299 | __vue_script__, 300 | __vue_scope_id__, 301 | __vue_is_functional_template__, 302 | __vue_module_identifier__, 303 | browser, 304 | undefined 305 | ); 306 | 307 | var AspectRatio$1 = /*#__PURE__*/Object.freeze({ 308 | __proto__: null, 309 | 'default': AspectRatio 310 | }); 311 | 312 | function getCjsExportFromNamespace (n) { 313 | return n && n['default'] || n; 314 | } 315 | 316 | var require$$0 = getCjsExportFromNamespace(AspectRatio$1); 317 | 318 | var src = require$$0; 319 | 320 | return src; 321 | 322 | }))); 323 | --------------------------------------------------------------------------------