diff --git a/.gitignore b/.gitignore
index beb828a..ecb68d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/node_modules
npm-debug.log
+package-lock.json
diff --git a/readme.md b/readme.md
index fc0fa53..3527427 100644
--- a/readme.md
+++ b/readme.md
@@ -20,6 +20,18 @@ $ npm install vue-moment
Vue.use(require('vue-moment'));
```
+...or add it to your component as a local filter:
+
+```js
+import {moment} from 'vue-moment'
+
+export default {
+ filters: {
+ moment
+ }
+}
+```
+
## Usage
Simply set `moment` as the filtering function and you're good to go. At least one argument is expected, which the filter assumes to be a `format` string if the argument doesn't match any of the other filtering methods.
@@ -236,7 +248,7 @@ console.log(Vue.moment().locale()) //es
## this.$moment
-`vue-moment` attaches the momentjs instance to your Vue app as `this.$moment`.
+`vue-moment` attaches the momentjs instance to your Vue app as `this.$moment`.
This allows you to call [the static methods momentjs provides](https://momentjs.com/docs/#/i18n/listing-months-weekdays/).
diff --git a/tests/vue-moment.spec.js b/tests/vue-moment.spec.js
index 9e460bd..51d35b3 100644
--- a/tests/vue-moment.spec.js
+++ b/tests/vue-moment.spec.js
@@ -33,6 +33,27 @@ const vmd = new Vue({
},
}).$mount();
+const vml = new Vue({
+ template: `
+ {{ now | moment-local(...args) }}
+ {{ period | duration-local(...args) | duration-local(...formatter) }}
+
`,
+ data() {
+ return {
+ now,
+ args: [
+ 'YYYY-MM-DD',
+ ],
+ formatter: ['humanize', true],
+ period,
+ };
+ },
+ filters: {
+ 'moment-local': VueMoment.moment,
+ 'duration-local': VueMoment.duration
+ },
+}).$mount();
+
describe('VueMoment', () => {
describe('installing plugin', () => {
it('loads prototype', () => {
@@ -290,4 +311,14 @@ describe('VueMoment', () => {
});
});
});
+
+ describe('local plugin', () => {
+ it('supports moment', () => {
+ expect(vml.$el.textContent).toContain(now.format('YYYY-MM-DD'));
+ });
+
+ it('supports duration', () => {
+ expect(vmd.$el.textContent).toContain('in a day');
+ });
+ })
});
diff --git a/vue-moment.js b/vue-moment.js
index 27a1e32..305a763 100644
--- a/vue-moment.js
+++ b/vue-moment.js
@@ -1,232 +1,240 @@
-module.exports = {
- install(Vue, options) {
- const moment = options && options.moment ? options.moment : require('moment');
+const momentLocal = require('moment');
+
+const createMomentFilter = moment => (...args) => {
+ args = Array.prototype.slice.call(args);
+ const input = args.shift();
+ let date;
+
+ if (Array.isArray(input) && typeof input[0] === 'string') {
+ // If input is array, assume we're being passed a format pattern to parse against.
+ // Format pattern will accept an array of potential formats to parse against.
+ // Date string should be at [0], format pattern(s) should be at [1]
+ date = moment(input[0], input[1], true);
+ } else if (typeof input === 'number') {
+ if (input.toString().length < 12) {
+ // If input is an integer with fewer than 12 digits, assume Unix seconds...
+ date = moment.unix(input);
+ } else {
+ // ..otherwise, assume milliseconds.
+ date = moment(input);
+ }
+ } else {
+ // Otherwise, throw the input at moment and see what happens...
+ date = moment(input);
+ }
+
+ if (!input || !date.isValid()) {
+ // Log a warning if moment couldn't reconcile the input. Better than throwing an error?
+ console.warn('Could not build a valid `moment` object from input.');
+ return input;
+ }
+
+ function parse(...args) {
+ args = Array.prototype.slice.call(args);
+ const method = args.shift();
+
+ switch (method) {
+ case 'add': {
+ /*
+ * Mutates the original moment by adding time.
+ * http://momentjs.com/docs/#/manipulating/add/
+ */
+
+ const addends = args.shift()
+ .split(',')
+ .map(Function.prototype.call, String.prototype.trim);
+ const obj = {};
+
+ for (let n = 0; n < addends.length; n++) {
+ const addend = addends[n].split(' ');
+ obj[addend[1]] = addend[0];
+ }
+ date.add(obj);
+ break;
+ }
- Object.defineProperties(Vue.prototype, {
- $moment: {
- get() {
- return moment;
- },
- },
- });
+ case 'subtract': {
+ /*
+ * Mutates the original moment by subtracting time.
+ * http://momentjs.com/docs/#/manipulating/subtract/
+ */
- Vue.moment = moment;
+ const subtrahends = args.shift()
+ .split(',')
+ .map(Function.prototype.call, String.prototype.trim);
+ const obj = {};
- Vue.filter('moment', (...args) => {
- args = Array.prototype.slice.call(args);
- const input = args.shift();
- let date;
-
- if (Array.isArray(input) && typeof input[0] === 'string') {
- // If input is array, assume we're being passed a format pattern to parse against.
- // Format pattern will accept an array of potential formats to parse against.
- // Date string should be at [0], format pattern(s) should be at [1]
- date = moment(input[0], input[1], true);
- } else if (typeof input === 'number') {
- if (input.toString().length < 12) {
- // If input is an integer with fewer than 12 digits, assume Unix seconds...
- date = moment.unix(input);
- } else {
- // ..otherwise, assume milliseconds.
- date = moment(input);
+ for (let n = 0; n < subtrahends.length; n++) {
+ const subtrahend = subtrahends[n].split(' ');
+ obj[subtrahend[1]] = subtrahend[0];
}
- } else {
- // Otherwise, throw the input at moment and see what happens...
- date = moment(input);
+ date.subtract(obj);
+ break;
}
- if (!input || !date.isValid()) {
- // Log a warning if moment couldn't reconcile the input. Better than throwing an error?
- console.warn('Could not build a valid `moment` object from input.');
- return input;
+ case 'from': {
+ /*
+ * Display a moment in relative time, either from now or from a specified date.
+ * http://momentjs.com/docs/#/displaying/fromnow/
+ */
+
+ let from = 'now';
+ let removeSuffix = false;
+
+ if (args[0] === 'now') args.shift();
+ // If valid, assume it is a date we want the output computed against.
+ if (moment(args[0]).isValid()) from = moment(args.shift());
+
+ if (args[0] === true) {
+ args.shift();
+ removeSuffix = true;
+ }
+
+ if (from !== 'now') {
+ date = date.from(from, removeSuffix);
+ } else {
+ date = date.fromNow(removeSuffix);
+ }
+ break;
}
- function parse(...args) {
- args = Array.prototype.slice.call(args);
- const method = args.shift();
-
- switch (method) {
- case 'add': {
- /*
- * Mutates the original moment by adding time.
- * http://momentjs.com/docs/#/manipulating/add/
- */
-
- const addends = args.shift()
- .split(',')
- .map(Function.prototype.call, String.prototype.trim);
- const obj = {};
-
- for (let n = 0; n < addends.length; n++) {
- const addend = addends[n].split(' ');
- obj[addend[1]] = addend[0];
- }
- date.add(obj);
- break;
- }
-
- case 'subtract': {
- /*
- * Mutates the original moment by subtracting time.
- * http://momentjs.com/docs/#/manipulating/subtract/
- */
-
- const subtrahends = args.shift()
- .split(',')
- .map(Function.prototype.call, String.prototype.trim);
- const obj = {};
-
- for (let n = 0; n < subtrahends.length; n++) {
- const subtrahend = subtrahends[n].split(' ');
- obj[subtrahend[1]] = subtrahend[0];
- }
- date.subtract(obj);
- break;
- }
-
- case 'from': {
- /*
- * Display a moment in relative time, either from now or from a specified date.
- * http://momentjs.com/docs/#/displaying/fromnow/
- */
-
- let from = 'now';
- let removeSuffix = false;
-
- if (args[0] === 'now') args.shift();
- // If valid, assume it is a date we want the output computed against.
- if (moment(args[0]).isValid()) from = moment(args.shift());
-
- if (args[0] === true) {
- args.shift();
- removeSuffix = true;
- }
-
- if (from !== 'now') {
- date = date.from(from, removeSuffix);
- } else {
- date = date.fromNow(removeSuffix);
- }
- break;
- }
-
- case 'diff': {
- /*
- * Mutates the original moment by doing a difference with another date.
- * http://momentjs.com/docs/#/displaying/difference/
- */
-
- let referenceTime = moment();
- let units = '';
- let float = false;
-
- if (moment(args[0]).isValid()) {
- // If valid, assume it is a date we want the output computed against.
- referenceTime = moment(args.shift());
- } else if (args[0] === null || args[0] === 'now') {
- // If null or 'now', remove argument and proceed with default referenceTime.
- args.shift();
- }
-
- if (args[0]) units = args.shift();
-
- if (args[0] === true) float = args.shift();
-
- date = date.diff(referenceTime, units, float);
- break;
- }
-
- case 'calendar': {
- /*
- * Formats a date with different strings depending on how close
- * to a certain date (today by default) the date is.
- * http://momentjs.com/docs/#/displaying/calendar-time/
- */
-
- let referenceTime = moment();
- let formats = {};
-
- if (moment(args[0]).isValid()) {
- // If valid, assume it is a date we want the output computed against.
- referenceTime = moment(args.shift());
- } else if (args[0] === null || args[0] === 'now') {
- // If null or 'now', remove argument and proceed with default referenceTime.
- args.shift();
- }
-
- if (typeof args[0] === 'object') formats = args.shift();
-
- date = date.calendar(referenceTime, formats);
- break;
- }
-
- case 'utc': {
- /*
- * Mutates the original moment by converting to UTC
- * https://momentjs.com/docs/#/manipulating/utc/
- */
- date.utc();
- break;
- }
-
- case 'timezone': {
- /*
- * Mutates the original moment by converting to a new timezone.
- * https://momentjs.com/timezone/docs/#/using-timezones/converting-to-zone/
- */
- date.tz(args.shift());
- break;
- }
-
- default: {
- /*
- * Formats a date by taking a string of tokens and replacing
- * them with their corresponding values.
- * http://momentjs.com/docs/#/displaying/format/
- */
-
- const format = method;
- date = date.format(format);
- }
+ case 'diff': {
+ /*
+ * Mutates the original moment by doing a difference with another date.
+ * http://momentjs.com/docs/#/displaying/difference/
+ */
+
+ let referenceTime = moment();
+ let units = '';
+ let float = false;
+
+ if (moment(args[0]).isValid()) {
+ // If valid, assume it is a date we want the output computed against.
+ referenceTime = moment(args.shift());
+ } else if (args[0] === null || args[0] === 'now') {
+ // If null or 'now', remove argument and proceed with default referenceTime.
+ args.shift();
}
- if (args.length) parse.apply(parse, args);
+ if (args[0]) units = args.shift();
+
+ if (args[0] === true) float = args.shift();
+
+ date = date.diff(referenceTime, units, float);
+ break;
}
- parse.apply(parse, args);
+ case 'calendar': {
+ /*
+ * Formats a date with different strings depending on how close
+ * to a certain date (today by default) the date is.
+ * http://momentjs.com/docs/#/displaying/calendar-time/
+ */
+
+ let referenceTime = moment();
+ let formats = {};
+
+ if (moment(args[0]).isValid()) {
+ // If valid, assume it is a date we want the output computed against.
+ referenceTime = moment(args.shift());
+ } else if (args[0] === null || args[0] === 'now') {
+ // If null or 'now', remove argument and proceed with default referenceTime.
+ args.shift();
+ }
- return date;
- });
+ if (typeof args[0] === 'object') formats = args.shift();
- Vue.filter('duration', (...args) => {
- /*
- * Basic pass-through filter for leveraging moment.js's ability
- * to manipulate and display durations.
- * https://momentjs.com/docs/#/durations/
- */
- args = Array.prototype.slice.call(args);
- const input = args.shift();
- const method = args.shift();
-
- function createDuration(time) {
- if (!Array.isArray(time)) time = [time];
- const result = moment.duration(...time);
- if (!result.isValid()) console.warn('Could not build a valid `duration` object from input.');
- return result;
+ date = date.calendar(referenceTime, formats);
+ break;
}
- let duration = createDuration(input);
-
- if (method === 'add' || method === 'subtract') {
- // Generates a duration object and either adds or subtracts it
- // from our original duration.
- const durationChange = createDuration(args);
- duration[method](durationChange);
- } else if (duration && duration[method]) {
- // This gives a full proxy to moment.duration functions.
- duration = duration[method](...args);
+
+ case 'utc': {
+ /*
+ * Mutates the original moment by converting to UTC
+ * https://momentjs.com/docs/#/manipulating/utc/
+ */
+ date.utc();
+ break;
}
- return duration;
+ case 'timezone': {
+ /*
+ * Mutates the original moment by converting to a new timezone.
+ * https://momentjs.com/timezone/docs/#/using-timezones/converting-to-zone/
+ */
+ date.tz(args.shift());
+ break;
+ }
+
+ default: {
+ /*
+ * Formats a date by taking a string of tokens and replacing
+ * them with their corresponding values.
+ * http://momentjs.com/docs/#/displaying/format/
+ */
+
+ const format = method;
+ date = date.format(format);
+ }
+ }
+
+ if (args.length) parse.apply(parse, args);
+ }
+
+ parse.apply(parse, args);
+
+ return date;
+};
+
+const createDurationFilter = moment => (...args) => {
+ /*
+ * Basic pass-through filter for leveraging moment.js's ability
+ * to manipulate and display durations.
+ * https://momentjs.com/docs/#/durations/
+ */
+ args = Array.prototype.slice.call(args);
+ const input = args.shift();
+ const method = args.shift();
+
+ function createDuration(time) {
+ if (!Array.isArray(time)) time = [time];
+ const result = moment.duration(...time);
+ if (!result.isValid()) console.warn('Could not build a valid `duration` object from input.');
+ return result;
+ }
+ let duration = createDuration(input);
+
+ if (method === 'add' || method === 'subtract') {
+ // Generates a duration object and either adds or subtracts it
+ // from our original duration.
+ const durationChange = createDuration(args);
+ duration[method](durationChange);
+ } else if (duration && duration[method]) {
+ // This gives a full proxy to moment.duration functions.
+ duration = duration[method](...args);
+ }
+
+ return duration;
+};
+
+module.exports = {
+ install(Vue, options) {
+ const moment = options && options.moment ? options.moment : momentLocal;
+
+ Object.defineProperties(Vue.prototype, {
+ $moment: {
+ get() {
+ return moment;
+ },
+ },
});
+
+ Vue.moment = moment;
+
+ Vue.filter('moment', createMomentFilter(moment));
+
+ Vue.filter('duration', createDurationFilter(moment));
},
+ moment: createMomentFilter(momentLocal),
+ duration: createDurationFilter(momentLocal),
};