Permalink
Browse files

feat(utils): transpiler friendly polyfills and methods (#658)

* Add bootstrap -> bootstrap-vue migration notes

* add bFormFieldset label text alignment options

* fixes per @pi0

* add focus method proxied to element ref

* Popover dom node leak fix

* feat(mixin): Automate event registration & removal on root vm

* fix(button-toolbar): Typo on property `keyNav`

* feat(utils): create exports of Object and Array methods

* fix(utils): refactor usage of methods/polyfills

* fix(utils): using Array.from polyfill

* fix(refactor): use Object.keys shorthand

* feat(utils/object): add Object.assign polyfill

* merge(breadcrumb): merge changes

* merge(form-checkbox): merge changes

* refactor(utils): merge changes

* fix(tests): fix failing tests due to mixin references

* test: trigger CI build for re-test

* update(yarn.lock): rebuild lock file for circleci

* fix(imports): clean up trailing slash

* fix(table): reapply changes after merge
  • Loading branch information...
alexsasharegan authored and tmorehouse committed Jul 8, 2017
1 parent 8cd3ea1 commit 2ee9ed6815cd6d615a5654c7f1d207cdb8f8a2ee
@@ -18,9 +18,10 @@
<script>
import bLink from './link.vue';
import { props as linkProps } from '../mixins/link';
import {arrayIncludes} from '../utils';
import { arrayIncludes } from '../utils/array';
import { assign, keys } from '../utils/object';
const bLinkPropKeys = Object.keys(linkProps);
const bLinkPropKeys = keys(linkProps);
export default {
components: { bLink },
@@ -37,9 +38,9 @@ export default {
// nothing defined except the text
if (typeof item === 'string') {
Object.assign(normalizedItem, { text: item, link: '#', active: isLast });
assign(normalizedItem, { text: item, link: '#', active: isLast });
} else {
Object.assign(normalizedItem, item);
assign(normalizedItem, item);
}
// don't default the active state if given a boolean value,
@@ -60,7 +61,7 @@ export default {
// stuff all the bLink props into a single place
// so we can bind to the component
// for dynamic prop proxying
normalizedItem._linkProps = Object.keys(normalizedItem).reduce((memo, itemProp) => {
normalizedItem._linkProps = keys(normalizedItem).reduce((memo, itemProp) => {
if (arrayIncludes(bLinkPropKeys, itemProp)) {
memo[itemProp] = normalizedItem[itemProp];
}
@@ -17,6 +17,7 @@
</template>
<script>
import { from as arrayFrom } from '../utils/array'
const ITEM_SELECTOR = [
'.btn:not(.disabled):not([disabled])',
'.form-control:not(.disabled):not([disabled])',
@@ -99,7 +100,7 @@
}
},
getItems() {
let items = Array.prototype.slice.call(this.$el.querySelectorAll(ITEM_SELECTOR));
let items = arrayFrom(this.$el.querySelectorAll(ITEM_SELECTOR));
items.forEach(item => {
// Ensure tabfocus is -1 on any new elements
item.tabIndex = -1;
@@ -12,12 +12,13 @@
<script>
import bLink from './link.vue';
import { omitLinkProps, props as originalLinkProps, computed } from '../mixins/link';
import { assign } from '../utils/object';
// Grab a fresh object of link props (omitLinkProps does this)
// less the 'href' and 'to' props
// that we will reconstruct without any defaults
// so our computed 'componentType' functions properly
const linkProps = Object.assign(omitLinkProps('href', 'to'), {
const linkProps = assign(omitLinkProps('href', 'to'), {
href: { type: originalLinkProps.href.type },
to: { type: originalLinkProps.to.type }
});
@@ -51,14 +52,14 @@ export default {
return this.disabled ? 'disabled' : '';
},
btnType() {
return (this.href || this.to) ? null : this.type;
return (this.href || this.to) ? null : this.type;
},
conditionalLinkProps() {
return this.componentType === 'button' ? {} : this.linkProps;
}
},
// merge our prepared link props with button props
props: Object.assign(linkProps, {
props: assign(linkProps, {
block: {
type: Boolean,
default: false
@@ -76,6 +76,8 @@
</template>
<script>
import { from as arrayFrom } from '../utils/array'
const DIRECTION = {
next: {
current: 'carousel-item-left',
@@ -189,11 +191,11 @@
this.start();
}
}
},
mounted() {
// Get all slides
this.slides = Array.prototype.slice.call(this.$el.querySelectorAll('.carousel-item'));
this.slides = arrayFrom(this.$el.querySelectorAll('.carousel-item'));
// Set first slide as active
this.slides[0].classList.add('active');
@@ -20,7 +20,7 @@
</style>
<script>
import {listenOnRootMixin} from '../mixins';
import { listenOnRootMixin } from '../mixins';
export default {
mixins: [listenOnRootMixin],
@@ -58,7 +58,7 @@
type: String,
required: true
},
accordion: {
accordion: {
type: String,
default: null
},
@@ -45,7 +45,7 @@
</template>
<script>
import {dropdownMixin} from '../mixins';
import { dropdownMixin } from '../mixins';
import bButton from './button.vue';
export default {
@@ -21,8 +21,8 @@
</template>
<script>
import {formMixin, formCustomMixin, formCheckBoxMixin} from '../mixins';
import {arrayIncludes, isArray} from '../utils';
import { formMixin, formCustomMixin, formCheckBoxMixin } from '../mixins';
import { arrayIncludes, isArray } from '../utils/array';
export default {
mixins: [formMixin, formCustomMixin, formCheckBoxMixin],
@@ -84,7 +84,8 @@
</style>
<script>
import {formCustomMixin, formMixin} from '../mixins';
import { formCustomMixin, formMixin } from '../mixins';
import { from as arrayFrom } from '../utils/array';
export default {
mixins: [formMixin, formCustomMixin],
@@ -161,7 +162,7 @@
}
}
Promise.all(queue).then(filesArr => {
this.setFiles(Array.prototype.concat.apply([], filesArr));
this.setFiles(arrayFrom(filesArr));
});
return;
}
@@ -226,7 +227,7 @@
queue.push(this.traverseFileTree(entries[i], path + item.name + '/'));
}
Promise.all(queue).then(filesArr => {
resolve(Array.prototype.concat.apply([], filesArr));
resolve(arrayFrom(filesArr));
});
});
}
@@ -30,7 +30,7 @@
</template>
<script>
import {formMixin} from '../mixins';
import { formMixin } from '../mixins';
import bFormInputStatic from './form-input-static.vue';
export default {
@@ -27,7 +27,7 @@
</template>
<script>
import {formOptionsMixin, formMixin, formCustomMixin, formCheckBoxMixin} from '../mixins';
import { formOptionsMixin, formMixin, formCustomMixin, formCheckBoxMixin } from '../mixins';
export default {
mixins: [formMixin, formCustomMixin, formCheckBoxMixin, formOptionsMixin],
@@ -18,7 +18,7 @@
</template>
<script>
import {formMixin, formOptionsMixin, formCustomMixin} from '../mixins';
import { formMixin, formOptionsMixin, formCustomMixin } from '../mixins';
export default {
mixins: [formMixin, formCustomMixin, formOptionsMixin],
@@ -31,7 +31,7 @@
</template>
<script>
import {linkMixin} from '../mixins';
import { linkMixin } from '../mixins';
export default {
mixins: [linkMixin]
@@ -10,10 +10,11 @@
<script>
import bLink from './link.vue';
import { props as originalLinkProps, computed, omitLinkProps } from '../mixins/link';
import {arrayIncludes} from '../utils';
import { arrayIncludes } from '../utils/array';
import { assign } from '../utils/object';
// copy link props, but exclude defaults for 'href', 'to', & 'tag'
// to ensure proper component tag computation
const linkProps = Object.assign(omitLinkProps('href', 'to'), {
const linkProps = assign(omitLinkProps('href', 'to'), {
href: { type: originalLinkProps.href.type },
to: { type: originalLinkProps.to.type },
tag: { type: originalLinkProps.tag.type }
@@ -65,7 +66,7 @@ export default {
},
// merge the link props with list-group-item props
props: Object.assign(linkProps, {
props: assign(linkProps, {
action: {
type: Boolean,
default: null
@@ -92,7 +92,8 @@
<script>
import bBtn from './button.vue';
import {listenOnRootMixin} from '../mixins';
import { listenOnRootMixin } from '../mixins';
import { from as arrayFrom } from '../utils/array'
const FOCUS_SELECTOR = [
'button:not([disabled])',
@@ -107,13 +108,13 @@
function isVisible(el) {
return el && (el.offsetWidth > 0 || el.offsetHeight > 0);
}
// Find the first visible element contained in a given root element
function findFirstVisible(root, selector) {
if (!root || !root.querySelectorAll || !selector) {
return null;
}
let els = Array.prototype.slice.call(root.querySelectorAll(selector));
let els = arrayFrom(root.querySelectorAll(selector));
// IE 10 & 11 do not support native array.find()
// So we try native find first, then fall back to a loop
@@ -175,7 +176,7 @@
buttonSize: {
type: String,
default: 'md'
},
},
noFade: {
type: Boolean,
default: false
@@ -32,10 +32,10 @@
</template>
<script>
import dropdown from '../mixins/dropdown';
import { dropdownMixin } from '../mixins';
export default {
mixins: [dropdown],
mixins: [dropdownMixin],
computed: {
dropdownToggle() {
return this.noCaret ? '' : 'dropdown-toggle';
@@ -11,7 +11,7 @@
</template>
<script>
import {listenOnRootMixin} from '../mixins';
import { listenOnRootMixin } from '../mixins';
export default {
mixins: [listenOnRootMixin],
@@ -109,14 +109,16 @@
</template>
<script>
import { from as arrayFrom } from '../utils/array'
import range from '../utils/range'
// Determine if an HTML element is visible - Faster than CSS check
function isVisible(el) {
return el && (el.offsetWidth > 0 || el.offsetHeight > 0);
}
// Make an aray of N to N+X
// Make an array of N to N+X
function makePageArray(startNum, numPages) {
return Array.apply(null, {length: numPages}).map(function(value, index){
return range(numPages).map(function(value, index){
return { number: index + startNum, className: null };
});
}
@@ -217,7 +219,7 @@ export default {
}
}
}
return pages;
}
},
@@ -266,7 +268,7 @@ export default {
this.$emit('change', this.currentPage);
},
getButtons() {
const buttons = Array.prototype.slice.call(this.$el.querySelectorAll('a.page-link'));
const buttons = arrayFrom(this.$el.querySelectorAll('a.page-link'));
// Return only buttons that are visible
return buttons.filter(btn => isVisible(btn));
},
@@ -20,7 +20,7 @@
</template>
<script>
import {popoverMixin} from '../mixins';
import { popoverMixin } from '../mixins';
export default {
mixins: [popoverMixin],
@@ -56,7 +56,7 @@
</td>
</tr>
<tr v-if="showEmpty && (!_items || _items.length === 0)">
<td :colspan="Object.keys(fields).length">
<td :colspan="keys(fields).length">
<div v-if="filter" role="alert" aria-live="polite">
<slot name="emptyfiltered">
<div class="text-center my-2" v-html="emptyFilteredText"></div>
@@ -74,14 +74,15 @@
</template>
<script>
import {warn} from '../utils';
import { warn } from '../utils';
import { keys } from '../utils/object.js'
const toString = v => {
if (!v) {
return '';
}
if (v instanceof Object) {
return Object.keys(v).map(k => toString(v[k])).join(' ');
return keys(v).map(k => toString(v[k])).join(' ');
}
return String(v);
};
@@ -91,7 +92,7 @@
return '';
}
return toString(Object.keys(obj).reduce((o, k) => {
return toString(keys(obj).reduce((o, k) => {
// Ignore fields 'state' and ones that start with _
if (!(/^_/.test(k) || k === 'state')) {
o[k] = obj[k];
@@ -391,6 +392,7 @@
}
},
methods: {
keys,
fieldClass(field, key) {
return [
field.sortable ? 'sorting' : '',
@@ -23,7 +23,7 @@
</style>
<script>
import {popoverMixin} from '../mixins';
import { popoverMixin } from '../mixins';
export default {
mixins: [popoverMixin],
Oops, something went wrong.

0 comments on commit 2ee9ed6

Please sign in to comment.