Saving for posterity
@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
node_modules/
|
@ -0,0 +1,480 @@
|
||||
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||
/**
|
||||
* 1. Change the default font family in all browsers (opinionated).
|
||||
* 2. Correct the line height in all browsers.
|
||||
* 3. Prevent adjustments of font size after orientation changes in
|
||||
* IE on Windows Phone and in iOS.
|
||||
*/
|
||||
/* Document
|
||||
========================================================================== */
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
/* 1 */
|
||||
line-height: 1.15;
|
||||
/* 2 */
|
||||
-ms-text-size-adjust: 100%;
|
||||
/* 3 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* 3 */ }
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
/**
|
||||
* Remove the margin in all browsers (opinionated).
|
||||
*/
|
||||
body {
|
||||
margin: 0; }
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
article,
|
||||
aside,
|
||||
footer,
|
||||
header,
|
||||
nav,
|
||||
section {
|
||||
display: block; }
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0; }
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in IE.
|
||||
*/
|
||||
figcaption,
|
||||
figure,
|
||||
main {
|
||||
/* 1 */
|
||||
display: block; }
|
||||
|
||||
/**
|
||||
* Add the correct margin in IE 8.
|
||||
*/
|
||||
figure {
|
||||
margin: 1em 40px; }
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
/* 1 */
|
||||
height: 0;
|
||||
/* 1 */
|
||||
overflow: visible;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
/* 1 */
|
||||
font-size: 1em;
|
||||
/* 2 */ }
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
/**
|
||||
* 1. Remove the gray background on active links in IE 10.
|
||||
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||
*/
|
||||
a {
|
||||
background-color: transparent;
|
||||
/* 1 */
|
||||
-webkit-text-decoration-skip: objects;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Remove the outline on focused links when they are also active or hovered
|
||||
* in all browsers (opinionated).
|
||||
*/
|
||||
a:active,
|
||||
a:hover {
|
||||
outline-width: 0; }
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Firefox 39-.
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
/* 1 */
|
||||
text-decoration: underline;
|
||||
/* 2 */
|
||||
text-decoration: underline dotted;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
|
||||
*/
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit; }
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder; }
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
/* 1 */
|
||||
font-size: 1em;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Add the correct font style in Android 4.3-.
|
||||
*/
|
||||
dfn {
|
||||
font-style: italic; }
|
||||
|
||||
/**
|
||||
* Add the correct background and color in IE 9-.
|
||||
*/
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000; }
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
small {
|
||||
font-size: 80%; }
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline; }
|
||||
|
||||
sub {
|
||||
bottom: -0.25em; }
|
||||
|
||||
sup {
|
||||
top: -0.5em; }
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
audio,
|
||||
video {
|
||||
display: inline-block; }
|
||||
|
||||
/**
|
||||
* Add the correct display in iOS 4-7.
|
||||
*/
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0; }
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10-.
|
||||
*/
|
||||
img {
|
||||
border-style: none; }
|
||||
|
||||
/**
|
||||
* Hide the overflow in IE.
|
||||
*/
|
||||
svg:not(:root) {
|
||||
overflow: hidden; }
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
/**
|
||||
* 1. Change the font styles in all browsers (opinionated).
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: sans-serif;
|
||||
/* 1 */
|
||||
font-size: 100%;
|
||||
/* 1 */
|
||||
line-height: 1.15;
|
||||
/* 1 */
|
||||
margin: 0;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
button,
|
||||
input {
|
||||
/* 1 */
|
||||
overflow: visible; }
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
button,
|
||||
select {
|
||||
/* 1 */
|
||||
text-transform: none; }
|
||||
|
||||
/**
|
||||
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||
* controls in Android 4.
|
||||
* 2. Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0; }
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText; }
|
||||
|
||||
/**
|
||||
* Change the border, margin, and padding in all browsers (opinionated).
|
||||
*/
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em; }
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
legend {
|
||||
box-sizing: border-box;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 2 */
|
||||
display: table;
|
||||
/* 1 */
|
||||
max-width: 100%;
|
||||
/* 1 */
|
||||
padding: 0;
|
||||
/* 3 */
|
||||
white-space: normal;
|
||||
/* 1 */ }
|
||||
|
||||
/**
|
||||
* 1. Add the correct display in IE 9-.
|
||||
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
progress {
|
||||
display: inline-block;
|
||||
/* 1 */
|
||||
vertical-align: baseline;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE.
|
||||
*/
|
||||
textarea {
|
||||
overflow: auto; }
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10-.
|
||||
* 2. Remove the padding in IE 10-.
|
||||
*/
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
/* 1 */
|
||||
padding: 0;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto; }
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
/* 1 */
|
||||
outline-offset: -2px;
|
||||
/* 2 */ }
|
||||
|
||||
/**
|
||||
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||
*/
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none; }
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
font: inherit;
|
||||
/* 2 */ }
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
/*
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in Edge, IE, and Firefox.
|
||||
*/
|
||||
details,
|
||||
menu {
|
||||
display: block; }
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
summary {
|
||||
display: list-item; }
|
||||
|
||||
/* Scripting
|
||||
========================================================================== */
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
canvas {
|
||||
display: inline-block; }
|
||||
|
||||
/**
|
||||
* Add the correct display in IE.
|
||||
*/
|
||||
template {
|
||||
display: none; }
|
||||
|
||||
/* Hidden
|
||||
========================================================================== */
|
||||
/**
|
||||
* Add the correct display in IE 10-.
|
||||
*/
|
||||
[hidden] {
|
||||
display: none; }
|
||||
|
||||
/* END NORMALIZE
|
||||
========================================================================== */
|
||||
html, body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px; }
|
||||
|
||||
div#app {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column; }
|
||||
div#app .search-wrapper {
|
||||
position: relative; }
|
||||
div#app .search-wrapper label {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
top: 8px;
|
||||
left: 12px;
|
||||
z-index: -1;
|
||||
transition: .15s all ease-in-out; }
|
||||
div#app .search-wrapper input {
|
||||
padding: 4px 12px;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
transition: .15s all ease-in-out;
|
||||
background: white; }
|
||||
div#app .search-wrapper input:focus {
|
||||
outline: none;
|
||||
transform: scale(1.05); }
|
||||
div#app .search-wrapper input:focus + label {
|
||||
font-size: 10px;
|
||||
transform: translateY(-24px) translateX(-12px); }
|
||||
div#app .search-wrapper input::-webkit-input-placeholder {
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
font-weight: 100; }
|
||||
div#app .wrapper {
|
||||
display: flex;
|
||||
max-width: 444px;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 12px; }
|
||||
div#app .card {
|
||||
box-shadow: rgba(0, 0, 0, 0.11765) 0px 1px 6px, rgba(0, 0, 0, 0.11765) 0px 1px 4px;
|
||||
max-width: 124px;
|
||||
margin: 12px;
|
||||
transition: .15s all ease-in-out; }
|
||||
div#app .card:hover {
|
||||
transform: scale(1.1); }
|
||||
div#app .card a {
|
||||
text-decoration: none;
|
||||
padding: 12px;
|
||||
color: #03A9F4;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center; }
|
||||
div#app .card a img {
|
||||
height: 100px; }
|
||||
div#app .card a small {
|
||||
font-size: 10px;
|
||||
padding: 4px; }
|
||||
div#app .hotpink {
|
||||
background: hotpink; }
|
||||
div#app .green {
|
||||
background: green; }
|
||||
div#app .box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.12); }
|
||||
|
||||
/*# sourceMappingURL=app.css.map */
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "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",
|
||||
"sources": ["app.scss"],
|
||||
"names": [],
|
||||
"file": "app.css"
|
||||
}
|
@ -0,0 +1,564 @@
|
||||
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/**
|
||||
* 1. Change the default font family in all browsers (opinionated).
|
||||
* 2. Correct the line height in all browsers.
|
||||
* 3. Prevent adjustments of font size after orientation changes in
|
||||
* IE on Windows Phone and in iOS.
|
||||
*/
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
line-height: 1.15; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 3 */
|
||||
-webkit-text-size-adjust: 100%; /* 3 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers (opinionated).
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
footer,
|
||||
header,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in IE.
|
||||
*/
|
||||
|
||||
figcaption,
|
||||
figure,
|
||||
main { /* 1 */
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct margin in IE 8.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Remove the gray background on active links in IE 10.
|
||||
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent; /* 1 */
|
||||
-webkit-text-decoration-skip: objects; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the outline on focused links when they are also active or hovered
|
||||
* in all browsers (opinionated).
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Firefox 39-.
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font style in Android 4.3-.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct background and color in IE 9-.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
audio,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in iOS 4-7.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10-.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the overflow in IE.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers (opinionated).
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: sans-serif; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||
* controls in Android 4.
|
||||
* 2. Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
html [type="button"], /* 1 */
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the border, margin, and padding in all browsers (opinionated).
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct display in IE 9-.
|
||||
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10-.
|
||||
* 2. Remove the padding in IE 10-.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in Edge, IE, and Firefox.
|
||||
*/
|
||||
|
||||
details, /* 1 */
|
||||
menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Scripting
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
canvas {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hidden
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10-.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* END NORMALIZE
|
||||
========================================================================== */
|
||||
|
||||
|
||||
html, body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
div#app {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
label {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
color: rgba(0,0,0,.50);
|
||||
top: 8px;
|
||||
left: 12px;
|
||||
z-index: -1;
|
||||
transition: .15s all ease-in-out;
|
||||
}
|
||||
input {
|
||||
padding: 4px 12px;
|
||||
color: rgba(0,0,0,.70);
|
||||
border: 1px solid rgba(0,0,0,.12);
|
||||
transition: .15s all ease-in-out;
|
||||
background: white;
|
||||
&:focus {
|
||||
outline: none;
|
||||
transform: scale(1.05);
|
||||
& + label {
|
||||
font-size: 12px;
|
||||
transform: translateY(-24px) translateX(-12px);
|
||||
}
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
font-size: 12px;
|
||||
color: rgba(0,0,0,.50);
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
max-width: 444px;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: rgba(0, 0, 0, 0.117647) 0px 1px 6px, rgba(0, 0, 0, 0.117647) 0px 1px 4px;
|
||||
max-width: 124px;
|
||||
margin: 12px;
|
||||
transition: .15s all ease-in-out;
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
padding: 12px;
|
||||
color: #03A9F4;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
img {
|
||||
height: 100px;
|
||||
}
|
||||
small {
|
||||
font-size: 10px;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.hotpink {
|
||||
background: hotpink;
|
||||
}
|
||||
|
||||
.green {
|
||||
background: green;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 1px solid rgba(0,0,0,.12);
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1 @@
|
||||
<svg width="2500" height="2500" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M128 9.102c65.665 0 118.898 53.233 118.898 118.898 0 65.665-53.233 118.898-118.898 118.898C62.335 246.898 9.102 193.665 9.102 128 9.102 62.335 62.335 9.102 128 9.102M128 0C57.421 0 0 57.421 0 128c0 70.579 57.421 128 128 128 70.579 0 128-57.421 128-128C256 57.421 198.579 0 128 0m20.83 25.524c-10.43-1.896-35.651 36.409-43.994 59.734-.634 1.769-2.086 8.249-2.086 9.955 0 0 6.531 14.055 8.343 17.351-3.034-1.58-9.323-13.756-9.323-13.756-3.034 5.784-5.942 32.34-4.994 37.271 0 0 6.762 10.062 9.387 12.578-3.603-1.201-9.671-9.355-9.671-9.355-1.138 3.508-.916 10.807-.379 13.274 4.551 6.637 10.619 7.396 10.619 7.396s-6.637 66.181 3.413 71.111c6.258-1.327 7.775-73.956 7.775-73.956s7.585.569 9.292-1.327c3.856-2.655 12.826-30.224 12.958-34.202 0 0-10.41 1.952-15.487 3.924 3.826-3.8 16.049-6.352 16.049-6.352 3.315-3.979 10.291-31.047 10.994-39.391.176-2.093.583-4.657.268-8.398 0 0-9.941 2.177-12.014 1.424 2.104-.237 12.263-4.14 12.263-4.14 1.801-16.213 2.358-42.091-3.413-43.141zm-36.38 171.691c-.795 19.496-1.294 25.004-2.115 29.601-.379.857-.758.997-1.138-.095-3.477-15.992-3.224-136.438 36.409-191.241-23.05 42.092-33.535 122.861-33.156 161.735z" fill="#333"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1,24 @@
|
||||
<! Doctype HTML>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id='app'>
|
||||
<div class='search-wrapper'>
|
||||
<input type="text" v-model='keyword' placeholder="Search by title..." />
|
||||
<label>Search Title</label>
|
||||
</div>
|
||||
<div class='wrapper' >
|
||||
<div class='card' v-for='post in filteredList'>
|
||||
<a v-bind:href='post.link' target='_blank'>
|
||||
<img v-bind:src="post.logo" alt=""/>
|
||||
{{post.title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/vue.js"></script>
|
||||
<script type="text/javascript" src="js/dist/main.bundle.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
var postList = [
|
||||
new Post(
|
||||
'Vue.js',
|
||||
'https://vuejs.org/',
|
||||
'Chris',
|
||||
'https://vuejs.org//images/logo.png'
|
||||
),
|
||||
new Post(
|
||||
'React.js',
|
||||
'https://facebook.github.io/react/',
|
||||
'Tim',
|
||||
'http://daynin.github.io/clojurescript-presentation/img/react-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Angular.js',
|
||||
'https://angularjs.org/',
|
||||
'Sam',
|
||||
'https://angularjs.org/img/ng-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Ember.js',
|
||||
'http://emberjs.com/',
|
||||
'Rachel',
|
||||
'http://www.gravatar.com/avatar/0cf15665a9146ba852bf042b0652780a?s=200'
|
||||
),
|
||||
new Post(
|
||||
'Meteor.js',
|
||||
'https://www.meteor.com/',
|
||||
'Chris',
|
||||
'http://hacktivist.in/introduction-to-nodejs-mongodb-meteor/img/meteor.png'
|
||||
),
|
||||
new Post(
|
||||
'Aurelia',
|
||||
'http://aurelia.io/',
|
||||
'Tim',
|
||||
'https://cdn.auth0.com/blog/aurelia-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Node.js',
|
||||
'https://nodejs.org/en/',
|
||||
'A. A. Ron',
|
||||
'https://code-maven.com/img/node.png'
|
||||
),
|
||||
new Post(
|
||||
'Pusher',
|
||||
'https://pusher.com/',
|
||||
'Alex',
|
||||
'https://avatars1.githubusercontent.com/u/739550?v=3&s=400'
|
||||
),
|
||||
new Post(
|
||||
'Feathers.js',
|
||||
'http://feathersjs.com/',
|
||||
'Chuck',
|
||||
'https://cdn.worldvectorlogo.com/logos/feathersjs.svg'
|
||||
),
|
||||
]
|
||||
|
||||
var app = new Vue({
|
||||
el:'#app',
|
||||
data:{
|
||||
keyword: 'Javascript'
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var Post = function Post(title, link, author, logo) {
|
||||
_classCallCheck(this, Post);
|
||||
|
||||
this.title = title;
|
||||
this.link = link;
|
||||
this.author = author;
|
||||
this.logo = logo;
|
||||
};
|
||||
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
keyword: '',
|
||||
postList: [new Post('Vue.js', 'https://vuejs.org/', 'Chris', 'https://vuejs.org//images/logo.png'), new Post('React.js', 'https://facebook.github.io/react/', 'Tim', 'http://daynin.github.io/clojurescript-presentation/img/react-logo.png'), new Post('Angular.js', 'https://angularjs.org/', 'Sam', 'https://angularjs.org/img/ng-logo.png'), new Post('Ember.js', 'http://emberjs.com/', 'Rachel', 'http://www.gravatar.com/avatar/0cf15665a9146ba852bf042b0652780a?s=200'), new Post('Meteor.js', 'https://www.meteor.com/', 'Chris', 'http://hacktivist.in/introduction-to-nodejs-mongodb-meteor/img/meteor.png'), new Post('Aurelia', 'http://aurelia.io/', 'Tim', 'https://cdn.auth0.com/blog/aurelia-logo.png'), new Post('Node.js', 'https://nodejs.org/en/', 'A. A. Ron', 'https://code-maven.com/img/node.png'), new Post('Pusher', 'https://pusher.com/', 'Alex', 'https://avatars1.githubusercontent.com/u/739550?v=3&s=400'), new Post('Feathers.js', 'http://feathersjs.com/', 'Chuck', 'https://cdn.worldvectorlogo.com/logos/feathersjs.svg')]
|
||||
},
|
||||
computed: {
|
||||
filteredList: function filteredList() {
|
||||
var _this = this;
|
||||
|
||||
return this.postList.filter(function (post) {
|
||||
return post.title.toLowerCase().includes(_this.keyword.toLowerCase());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
@ -0,0 +1,79 @@
|
||||
class Post{
|
||||
constructor(title, link, author, logo){
|
||||
this.title = title
|
||||
this.link = link
|
||||
this.author = author
|
||||
this.logo = logo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
var app = new Vue({
|
||||
el:'#app',
|
||||
data:{
|
||||
keyword: '',
|
||||
postList: [
|
||||
new Post(
|
||||
'Vue.js',
|
||||
'https://vuejs.org/',
|
||||
'Chris',
|
||||
'https://vuejs.org//images/logo.png'
|
||||
),
|
||||
new Post(
|
||||
'React.js',
|
||||
'https://facebook.github.io/react/',
|
||||
'Tim',
|
||||
'http://daynin.github.io/clojurescript-presentation/img/react-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Angular.js',
|
||||
'https://angularjs.org/',
|
||||
'Sam',
|
||||
'https://angularjs.org/img/ng-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Ember.js',
|
||||
'http://emberjs.com/',
|
||||
'Rachel',
|
||||
'http://www.gravatar.com/avatar/0cf15665a9146ba852bf042b0652780a?s=200'
|
||||
),
|
||||
new Post(
|
||||
'Meteor.js',
|
||||
'https://www.meteor.com/',
|
||||
'Chris',
|
||||
'http://hacktivist.in/introduction-to-nodejs-mongodb-meteor/img/meteor.png'
|
||||
),
|
||||
new Post(
|
||||
'Aurelia',
|
||||
'http://aurelia.io/',
|
||||
'Tim',
|
||||
'https://cdn.auth0.com/blog/aurelia-logo.png'
|
||||
),
|
||||
new Post(
|
||||
'Node.js',
|
||||
'https://nodejs.org/en/',
|
||||
'A. A. Ron',
|
||||
'https://code-maven.com/img/node.png'
|
||||
),
|
||||
new Post(
|
||||
'Pusher',
|
||||
'https://pusher.com/',
|
||||
'Alex',
|
||||
'https://avatars1.githubusercontent.com/u/739550?v=3&s=400'
|
||||
),
|
||||
new Post(
|
||||
'Feathers.js',
|
||||
'http://feathersjs.com/',
|
||||
'Chuck',
|
||||
'https://cdn.worldvectorlogo.com/logos/feathersjs.svg'
|
||||
),
|
||||
]
|
||||
},
|
||||
computed:{
|
||||
filteredList(){
|
||||
return this.postList.filter((post) => {return post.title.toLowerCase().includes(this.keyword.toLowerCase());});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,809 @@
|
||||
/**
|
||||
* vuex v2.3.0
|
||||
* (c) 2017 Evan You
|
||||
* @license MIT
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Vuex = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
var applyMixin = function (Vue) {
|
||||
var version = Number(Vue.version.split('.')[0]);
|
||||
|
||||
if (version >= 2) {
|
||||
var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1;
|
||||
Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit });
|
||||
} else {
|
||||
// override init and inject vuex init procedure
|
||||
// for 1.x backwards compatibility.
|
||||
var _init = Vue.prototype._init;
|
||||
Vue.prototype._init = function (options) {
|
||||
if ( options === void 0 ) options = {};
|
||||
|
||||
options.init = options.init
|
||||
? [vuexInit].concat(options.init)
|
||||
: vuexInit;
|
||||
_init.call(this, options);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Vuex init hook, injected into each instances init hooks list.
|
||||
*/
|
||||
|
||||
function vuexInit () {
|
||||
var options = this.$options;
|
||||
// store injection
|
||||
if (options.store) {
|
||||
this.$store = options.store;
|
||||
} else if (options.parent && options.parent.$store) {
|
||||
this.$store = options.parent.$store;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var devtoolHook =
|
||||
typeof window !== 'undefined' &&
|
||||
window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||||
|
||||
function devtoolPlugin (store) {
|
||||
if (!devtoolHook) { return }
|
||||
|
||||
store._devtoolHook = devtoolHook;
|
||||
|
||||
devtoolHook.emit('vuex:init', store);
|
||||
|
||||
devtoolHook.on('vuex:travel-to-state', function (targetState) {
|
||||
store.replaceState(targetState);
|
||||
});
|
||||
|
||||
store.subscribe(function (mutation, state) {
|
||||
devtoolHook.emit('vuex:mutation', mutation, state);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item that pass the test
|
||||
* by second argument function
|
||||
*
|
||||
* @param {Array} list
|
||||
* @param {Function} f
|
||||
* @return {*}
|
||||
*/
|
||||
/**
|
||||
* Deep copy the given object considering circular structure.
|
||||
* This function caches all nested objects and its copies.
|
||||
* If it detects circular structure, use cached copy to avoid infinite loop.
|
||||
*
|
||||
* @param {*} obj
|
||||
* @param {Array<Object>} cache
|
||||
* @return {*}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* forEach for object
|
||||
*/
|
||||
function forEachValue (obj, fn) {
|
||||
Object.keys(obj).forEach(function (key) { return fn(obj[key], key); });
|
||||
}
|
||||
|
||||
function isObject (obj) {
|
||||
return obj !== null && typeof obj === 'object'
|
||||
}
|
||||
|
||||
function isPromise (val) {
|
||||
return val && typeof val.then === 'function'
|
||||
}
|
||||
|
||||
function assert (condition, msg) {
|
||||
if (!condition) { throw new Error(("[vuex] " + msg)) }
|
||||
}
|
||||
|
||||
var Module = function Module (rawModule, runtime) {
|
||||
this.runtime = runtime;
|
||||
this._children = Object.create(null);
|
||||
this._rawModule = rawModule;
|
||||
var rawState = rawModule.state;
|
||||
this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
|
||||
};
|
||||
|
||||
var prototypeAccessors$1 = { namespaced: {} };
|
||||
|
||||
prototypeAccessors$1.namespaced.get = function () {
|
||||
return !!this._rawModule.namespaced
|
||||
};
|
||||
|
||||
Module.prototype.addChild = function addChild (key, module) {
|
||||
this._children[key] = module;
|
||||
};
|
||||
|
||||
Module.prototype.removeChild = function removeChild (key) {
|
||||
delete this._children[key];
|
||||
};
|
||||
|
||||
Module.prototype.getChild = function getChild (key) {
|
||||
return this._children[key]
|
||||
};
|
||||
|
||||
Module.prototype.update = function update (rawModule) {
|
||||
this._rawModule.namespaced = rawModule.namespaced;
|
||||
if (rawModule.actions) {
|
||||
this._rawModule.actions = rawModule.actions;
|
||||
}
|
||||
if (rawModule.mutations) {
|
||||
this._rawModule.mutations = rawModule.mutations;
|
||||
}
|
||||
if (rawModule.getters) {
|
||||
this._rawModule.getters = rawModule.getters;
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachChild = function forEachChild (fn) {
|
||||
forEachValue(this._children, fn);
|
||||
};
|
||||
|
||||
Module.prototype.forEachGetter = function forEachGetter (fn) {
|
||||
if (this._rawModule.getters) {
|
||||
forEachValue(this._rawModule.getters, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachAction = function forEachAction (fn) {
|
||||
if (this._rawModule.actions) {
|
||||
forEachValue(this._rawModule.actions, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachMutation = function forEachMutation (fn) {
|
||||
if (this._rawModule.mutations) {
|
||||
forEachValue(this._rawModule.mutations, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperties( Module.prototype, prototypeAccessors$1 );
|
||||
|
||||
var ModuleCollection = function ModuleCollection (rawRootModule) {
|
||||
var this$1 = this;
|
||||
|
||||
// register root module (Vuex.Store options)
|
||||
this.root = new Module(rawRootModule, false);
|
||||
|
||||
// register all nested modules
|
||||
if (rawRootModule.modules) {
|
||||
forEachValue(rawRootModule.modules, function (rawModule, key) {
|
||||
this$1.register([key], rawModule, false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.get = function get (path) {
|
||||
return path.reduce(function (module, key) {
|
||||
return module.getChild(key)
|
||||
}, this.root)
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.getNamespace = function getNamespace (path) {
|
||||
var module = this.root;
|
||||
return path.reduce(function (namespace, key) {
|
||||
module = module.getChild(key);
|
||||
return namespace + (module.namespaced ? key + '/' : '')
|
||||
}, '')
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.update = function update$1 (rawRootModule) {
|
||||
update(this.root, rawRootModule);
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
|
||||
var this$1 = this;
|
||||
if ( runtime === void 0 ) runtime = true;
|
||||
|
||||
var parent = this.get(path.slice(0, -1));
|
||||
var newModule = new Module(rawModule, runtime);
|
||||
parent.addChild(path[path.length - 1], newModule);
|
||||
|
||||
// register nested modules
|
||||
if (rawModule.modules) {
|
||||
forEachValue(rawModule.modules, function (rawChildModule, key) {
|
||||
this$1.register(path.concat(key), rawChildModule, runtime);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.unregister = function unregister (path) {
|
||||
var parent = this.get(path.slice(0, -1));
|
||||
var key = path[path.length - 1];
|
||||
if (!parent.getChild(key).runtime) { return }
|
||||
|
||||
parent.removeChild(key);
|
||||
};
|
||||
|
||||
function update (targetModule, newModule) {
|
||||
// update target module
|
||||
targetModule.update(newModule);
|
||||
|
||||
// update nested modules
|
||||
if (newModule.modules) {
|
||||
for (var key in newModule.modules) {
|
||||
if (!targetModule.getChild(key)) {
|
||||
console.warn(
|
||||
"[vuex] trying to add a new module '" + key + "' on hot reloading, " +
|
||||
'manual reload is needed'
|
||||
);
|
||||
return
|
||||
}
|
||||
update(targetModule.getChild(key), newModule.modules[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Vue; // bind on install
|
||||
|
||||
var Store = function Store (options) {
|
||||
var this$1 = this;
|
||||
if ( options === void 0 ) options = {};
|
||||
|
||||
assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
|
||||
assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
|
||||
|
||||
var state = options.state; if ( state === void 0 ) state = {};
|
||||
var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
|
||||
var strict = options.strict; if ( strict === void 0 ) strict = false;
|
||||
|
||||
// store internal state
|
||||
this._committing = false;
|
||||
this._actions = Object.create(null);
|
||||
this._mutations = Object.create(null);
|
||||
this._wrappedGetters = Object.create(null);
|
||||
this._modules = new ModuleCollection(options);
|
||||
this._modulesNamespaceMap = Object.create(null);
|
||||
this._subscribers = [];
|
||||
this._watcherVM = new Vue();
|
||||
|
||||
// bind commit and dispatch to self
|
||||
var store = this;
|
||||
var ref = this;
|
||||
var dispatch = ref.dispatch;
|
||||
var commit = ref.commit;
|
||||
this.dispatch = function boundDispatch (type, payload) {
|
||||
return dispatch.call(store, type, payload)
|
||||
};
|
||||
this.commit = function boundCommit (type, payload, options) {
|
||||
return commit.call(store, type, payload, options)
|
||||
};
|
||||
|
||||
// strict mode
|
||||
this.strict = strict;
|
||||
|
||||
// init root module.
|
||||
// this also recursively registers all sub-modules
|
||||
// and collects all module getters inside this._wrappedGetters
|
||||
installModule(this, state, [], this._modules.root);
|
||||
|
||||
// initialize the store vm, which is responsible for the reactivity
|
||||
// (also registers _wrappedGetters as computed properties)
|
||||
resetStoreVM(this, state);
|
||||
|
||||
// apply plugins
|
||||
plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); });
|
||||
};
|
||||
|
||||
var prototypeAccessors = { state: {} };
|
||||
|
||||
prototypeAccessors.state.get = function () {
|
||||
return this._vm._data.$$state
|
||||
};
|
||||
|
||||
prototypeAccessors.state.set = function (v) {
|
||||
assert(false, "Use store.replaceState() to explicit replace store state.");
|
||||
};
|
||||
|
||||
Store.prototype.commit = function commit (_type, _payload, _options) {
|
||||
var this$1 = this;
|
||||
|
||||
// check object-style commit
|
||||
var ref = unifyObjectStyle(_type, _payload, _options);
|
||||
var type = ref.type;
|
||||
var payload = ref.payload;
|
||||
var options = ref.options;
|
||||
|
||||
var mutation = { type: type, payload: payload };
|
||||
var entry = this._mutations[type];
|
||||
if (!entry) {
|
||||
console.error(("[vuex] unknown mutation type: " + type));
|
||||
return
|
||||
}
|
||||
this._withCommit(function () {
|
||||
entry.forEach(function commitIterator (handler) {
|
||||
handler(payload);
|
||||
});
|
||||
});
|
||||
this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
|
||||
|
||||
if (options && options.silent) {
|
||||
console.warn(
|
||||
"[vuex] mutation type: " + type + ". Silent option has been removed. " +
|
||||
'Use the filter functionality in the vue-devtools'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Store.prototype.dispatch = function dispatch (_type, _payload) {
|
||||
// check object-style dispatch
|
||||
var ref = unifyObjectStyle(_type, _payload);
|
||||
var type = ref.type;
|
||||
var payload = ref.payload;
|
||||
|
||||
var entry = this._actions[type];
|
||||
if (!entry) {
|
||||
console.error(("[vuex] unknown action type: " + type));
|
||||
return
|
||||
}
|
||||
return entry.length > 1
|
||||
? Promise.all(entry.map(function (handler) { return handler(payload); }))
|
||||
: entry[0](payload)
|
||||
};
|
||||
|
||||
Store.prototype.subscribe = function subscribe (fn) {
|
||||
var subs = this._subscribers;
|
||||
if (subs.indexOf(fn) < 0) {
|
||||
subs.push(fn);
|
||||
}
|
||||
return function () {
|
||||
var i = subs.indexOf(fn);
|
||||
if (i > -1) {
|
||||
subs.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Store.prototype.watch = function watch (getter, cb, options) {
|
||||
var this$1 = this;
|
||||
|
||||
assert(typeof getter === 'function', "store.watch only accepts a function.");
|
||||
return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
|
||||
};
|
||||
|
||||
Store.prototype.replaceState = function replaceState (state) {
|
||||
var this$1 = this;
|
||||
|
||||
this._withCommit(function () {
|
||||
this$1._vm._data.$$state = state;
|
||||
});
|
||||
};
|
||||
|
||||
Store.prototype.registerModule = function registerModule (path, rawModule) {
|
||||
if (typeof path === 'string') { path = [path]; }
|
||||
assert(Array.isArray(path), "module path must be a string or an Array.");
|
||||
this._modules.register(path, rawModule);
|
||||
installModule(this, this.state, path, this._modules.get(path));
|
||||
// reset store to update getters...
|
||||
resetStoreVM(this, this.state);
|
||||
};
|
||||
|
||||
Store.prototype.unregisterModule = function unregisterModule (path) {
|
||||
var this$1 = this;
|
||||
|
||||
if (typeof path === 'string') { path = [path]; }
|
||||
assert(Array.isArray(path), "module path must be a string or an Array.");
|
||||
this._modules.unregister(path);
|
||||
this._withCommit(function () {
|
||||
var parentState = getNestedState(this$1.state, path.slice(0, -1));
|
||||
Vue.delete(parentState, path[path.length - 1]);
|
||||
});
|
||||
resetStore(this);
|
||||
};
|
||||
|
||||
Store.prototype.hotUpdate = function hotUpdate (newOptions) {
|
||||
this._modules.update(newOptions);
|
||||
resetStore(this, true);
|
||||
};
|
||||
|
||||
Store.prototype._withCommit = function _withCommit (fn) {
|
||||
var committing = this._committing;
|
||||
this._committing = true;
|
||||
fn();
|
||||
this._committing = committing;
|
||||
};
|
||||
|
||||
Object.defineProperties( Store.prototype, prototypeAccessors );
|
||||
|
||||
function resetStore (store, hot) {
|
||||
store._actions = Object.create(null);
|
||||
store._mutations = Object.create(null);
|
||||
store._wrappedGetters = Object.create(null);
|
||||
store._modulesNamespaceMap = Object.create(null);
|
||||
var state = store.state;
|
||||
// init all modules
|
||||
installModule(store, state, [], store._modules.root, true);
|
||||
// reset vm
|
||||
resetStoreVM(store, state, hot);
|
||||
}
|
||||
|
||||
function resetStoreVM (store, state, hot) {
|
||||
var oldVm = store._vm;
|
||||
|
||||
// bind store public getters
|
||||
store.getters = {};
|
||||
var wrappedGetters = store._wrappedGetters;
|
||||
var computed = {};
|
||||
forEachValue(wrappedGetters, function (fn, key) {
|
||||
// use computed to leverage its lazy-caching mechanism
|
||||
computed[key] = function () { return fn(store); };
|
||||
Object.defineProperty(store.getters, key, {
|
||||
get: function () { return store._vm[key]; },
|
||||
enumerable: true // for local getters
|
||||
});
|
||||
});
|
||||
|
||||
// use a Vue instance to store the state tree
|
||||
// suppress warnings just in case the user has added
|
||||
// some funky global mixins
|
||||
var silent = Vue.config.silent;
|
||||
Vue.config.silent = true;
|
||||
store._vm = new Vue({
|
||||
data: {
|
||||
$$state: state
|
||||
},
|
||||
computed: computed
|
||||
});
|
||||
Vue.config.silent = silent;
|
||||
|
||||
// enable strict mode for new vm
|
||||
if (store.strict) {
|
||||
enableStrictMode(store);
|
||||
}
|
||||
|
||||
if (oldVm) {
|
||||
if (hot) {
|
||||
// dispatch changes in all subscribed watchers
|
||||
// to force getter re-evaluation for hot reloading.
|
||||
store._withCommit(function () {
|
||||
oldVm._data.$$state = null;
|
||||
});
|
||||
}
|
||||
Vue.nextTick(function () { return oldVm.$destroy(); });
|
||||
}
|
||||
}
|
||||
|
||||
function installModule (store, rootState, path, module, hot) {
|
||||
var isRoot = !path.length;
|
||||
var namespace = store._modules.getNamespace(path);
|
||||
|
||||
// register in namespace map
|
||||
if (module.namespaced) {
|
||||
store._modulesNamespaceMap[namespace] = module;
|
||||
}
|
||||
|
||||
// set state
|
||||
if (!isRoot && !hot) {
|
||||
var parentState = getNestedState(rootState, path.slice(0, -1));
|
||||
var moduleName = path[path.length - 1];
|
||||
store._withCommit(function () {
|
||||
Vue.set(parentState, moduleName, module.state);
|
||||
});
|
||||
}
|
||||
|
||||
var local = module.context = makeLocalContext(store, namespace, path);
|
||||
|
||||
module.forEachMutation(function (mutation, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerMutation(store, namespacedType, mutation, local);
|
||||
});
|
||||
|
||||
module.forEachAction(function (action, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerAction(store, namespacedType, action, local);
|
||||
});
|
||||
|
||||
module.forEachGetter(function (getter, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerGetter(store, namespacedType, getter, local);
|
||||
});
|
||||
|
||||
module.forEachChild(function (child, key) {
|
||||
installModule(store, rootState, path.concat(key), child, hot);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* make localized dispatch, commit, getters and state
|
||||
* if there is no namespace, just use root ones
|
||||
*/
|
||||
function makeLocalContext (store, namespace, path) {
|
||||
var noNamespace = namespace === '';
|
||||
|
||||
var local = {
|
||||
dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) {
|
||||
var args = unifyObjectStyle(_type, _payload, _options);
|
||||
var payload = args.payload;
|
||||
var options = args.options;
|
||||
var type = args.type;
|
||||
|
||||
if (!options || !options.root) {
|
||||
type = namespace + type;
|
||||
if (!store._actions[type]) {
|
||||
console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return store.dispatch(type, payload)
|
||||
},
|
||||
|
||||
commit: noNamespace ? store.commit : function (_type, _payload, _options) {
|
||||
var args = unifyObjectStyle(_type, _payload, _options);
|
||||
var payload = args.payload;
|
||||
var options = args.options;
|
||||
var type = args.type;
|
||||
|
||||
if (!options || !options.root) {
|
||||
type = namespace + type;
|
||||
if (!store._mutations[type]) {
|
||||
console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
store.commit(type, payload, options);
|
||||
}
|
||||
};
|
||||
|
||||
// getters and state object must be gotten lazily
|
||||
// because they will be changed by vm update
|
||||
Object.defineProperties(local, {
|
||||
getters: {
|
||||
get: noNamespace
|
||||
? function () { return store.getters; }
|
||||
: function () { return makeLocalGetters(store, namespace); }
|
||||
},
|
||||
state: {
|
||||
get: function () { return getNestedState(store.state, path); }
|
||||
}
|
||||
});
|
||||
|
||||
return local
|
||||
}
|
||||
|
||||
function makeLocalGetters (store, namespace) {
|
||||
var gettersProxy = {};
|
||||
|
||||
var splitPos = namespace.length;
|
||||
Object.keys(store.getters).forEach(function (type) {
|
||||
// skip if the target getter is not match this namespace
|
||||
if (type.slice(0, splitPos) !== namespace) { return }
|
||||
|
||||
// extract local getter type
|
||||
var localType = type.slice(splitPos);
|
||||
|
||||
// Add a port to the getters proxy.
|
||||
// Define as getter property because
|
||||
// we do not want to evaluate the getters in this time.
|
||||
Object.defineProperty(gettersProxy, localType, {
|
||||
get: function () { return store.getters[type]; },
|
||||
enumerable: true
|
||||
});
|
||||
});
|
||||
|
||||
return gettersProxy
|
||||
}
|
||||
|
||||
function registerMutation (store, type, handler, local) {
|
||||
var entry = store._mutations[type] || (store._mutations[type] = []);
|
||||
entry.push(function wrappedMutationHandler (payload) {
|
||||
handler(local.state, payload);
|
||||
});
|
||||
}
|
||||
|
||||
function registerAction (store, type, handler, local) {
|
||||
var entry = store._actions[type] || (store._actions[type] = []);
|
||||
entry.push(function wrappedActionHandler (payload, cb) {
|
||||
var res = handler({
|
||||
dispatch: local.dispatch,
|
||||
commit: local.commit,
|
||||
getters: local.getters,
|
||||
state: local.state,
|
||||
rootGetters: store.getters,
|
||||
rootState: store.state
|
||||
}, payload, cb);
|
||||
if (!isPromise(res)) {
|
||||
res = Promise.resolve(res);
|
||||
}
|
||||
if (store._devtoolHook) {
|
||||
return res.catch(function (err) {
|
||||
store._devtoolHook.emit('vuex:error', err);
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function registerGetter (store, type, rawGetter, local) {
|
||||
if (store._wrappedGetters[type]) {
|
||||
console.error(("[vuex] duplicate getter key: " + type));
|
||||
return
|
||||
}
|
||||
store._wrappedGetters[type] = function wrappedGetter (store) {
|
||||
return rawGetter(
|
||||
local.state, // local state
|
||||
local.getters, // local getters
|
||||
store.state, // root state
|
||||
store.getters // root getters
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
function enableStrictMode (store) {
|
||||
store._vm.$watch(function () { return this._data.$$state }, function () {
|
||||
assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
|
||||
}, { deep: true, sync: true });
|
||||
}
|
||||
|
||||
function getNestedState (state, path) {
|
||||
return path.length
|
||||
? path.reduce(function (state, key) { return state[key]; }, state)
|
||||
: state
|
||||
}
|
||||
|
||||
function unifyObjectStyle (type, payload, options) {
|
||||
if (isObject(type) && type.type) {
|
||||
options = payload;
|
||||
payload = type;
|
||||
type = type.type;
|
||||
}
|
||||
|
||||
assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
|
||||
|
||||
return { type: type, payload: payload, options: options }
|
||||
}
|
||||
|
||||
function install (_Vue) {
|
||||
if (Vue) {
|
||||
console.error(
|
||||
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
|
||||
);
|
||||
return
|
||||
}
|
||||
Vue = _Vue;
|
||||
applyMixin(Vue);
|
||||
}
|
||||
|
||||
// auto install in dist mode
|
||||
if (typeof window !== 'undefined' && window.Vue) {
|
||||
install(window.Vue);
|
||||
}
|
||||
|
||||
var mapState = normalizeNamespace(function (namespace, states) {
|
||||
var res = {};
|
||||
normalizeMap(states).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
res[key] = function mappedState () {
|
||||
var state = this.$store.state;
|
||||
var getters = this.$store.getters;
|
||||
if (namespace) {
|
||||
var module = getModuleByNamespace(this.$store, 'mapState', namespace);
|
||||
if (!module) {
|
||||
return
|
||||
}
|
||||
state = module.context.state;
|
||||
getters = module.context.getters;
|
||||
}
|
||||
return typeof val === 'function'
|
||||
? val.call(this, state, getters)
|
||||
: state[val]
|
||||
};
|
||||
// mark vuex getter for devtools
|
||||
res[key].vuex = true;
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapMutations = normalizeNamespace(function (namespace, mutations) {
|
||||
var res = {};
|
||||
normalizeMap(mutations).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedMutation () {
|
||||
var args = [], len = arguments.length;
|
||||
while ( len-- ) args[ len ] = arguments[ len ];
|
||||
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapMutations', namespace)) {
|
||||
return
|
||||
}
|
||||
return this.$store.commit.apply(this.$store, [val].concat(args))
|
||||
};
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapGetters = normalizeNamespace(function (namespace, getters) {
|
||||
var res = {};
|
||||
normalizeMap(getters).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedGetter () {
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
|
||||
return
|
||||
}
|
||||
if (!(val in this.$store.getters)) {
|
||||
console.error(("[vuex] unknown getter: " + val));
|
||||
return
|
||||
}
|
||||
return this.$store.getters[val]
|
||||
};
|
||||
// mark vuex getter for devtools
|
||||
res[key].vuex = true;
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapActions = normalizeNamespace(function (namespace, actions) {
|
||||
var res = {};
|
||||
normalizeMap(actions).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedAction () {
|
||||
var args = [], len = arguments.length;
|
||||
while ( len-- ) args[ len ] = arguments[ len ];
|
||||
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapActions', namespace)) {
|
||||
return
|
||||
}
|
||||
return this.$store.dispatch.apply(this.$store, [val].concat(args))
|
||||
};
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
function normalizeMap (map) {
|
||||
return Array.isArray(map)
|
||||
? map.map(function (key) { return ({ key: key, val: key }); })
|
||||
: Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
|
||||
}
|
||||
|
||||
function normalizeNamespace (fn) {
|
||||
return function (namespace, map) {
|
||||
if (typeof namespace !== 'string') {
|
||||
map = namespace;
|
||||
namespace = '';
|
||||
} else if (namespace.charAt(namespace.length - 1) !== '/') {
|
||||
namespace += '/';
|
||||
}
|
||||
return fn(namespace, map)
|
||||
}
|
||||
}
|
||||
|
||||
function getModuleByNamespace (store, helper, namespace) {
|
||||
var module = store._modulesNamespaceMap[namespace];
|
||||
if (!module) {
|
||||
console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
var index = {
|
||||
Store: Store,
|
||||
install: install,
|
||||
version: '2.3.0',
|
||||
mapState: mapState,
|
||||
mapMutations: mapMutations,
|
||||
mapGetters: mapGetters,
|
||||
mapActions: mapActions
|
||||
};
|
||||
|
||||
return index;
|
||||
|
||||
})));
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "devcoffee",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "veux.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"http-serve": "^1.0.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,809 @@
|
||||
/**
|
||||
* vuex v2.3.0
|
||||
* (c) 2017 Evan You
|
||||
* @license MIT
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Vuex = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
var applyMixin = function (Vue) {
|
||||
var version = Number(Vue.version.split('.')[0]);
|
||||
|
||||
if (version >= 2) {
|
||||
var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1;
|
||||
Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit });
|
||||
} else {
|
||||
// override init and inject vuex init procedure
|
||||
// for 1.x backwards compatibility.
|
||||
var _init = Vue.prototype._init;
|
||||
Vue.prototype._init = function (options) {
|
||||
if ( options === void 0 ) options = {};
|
||||
|
||||
options.init = options.init
|
||||
? [vuexInit].concat(options.init)
|
||||
: vuexInit;
|
||||
_init.call(this, options);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Vuex init hook, injected into each instances init hooks list.
|
||||
*/
|
||||
|
||||
function vuexInit () {
|
||||
var options = this.$options;
|
||||
// store injection
|
||||
if (options.store) {
|
||||
this.$store = options.store;
|
||||
} else if (options.parent && options.parent.$store) {
|
||||
this.$store = options.parent.$store;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var devtoolHook =
|
||||
typeof window !== 'undefined' &&
|
||||
window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||||
|
||||
function devtoolPlugin (store) {
|
||||
if (!devtoolHook) { return }
|
||||
|
||||
store._devtoolHook = devtoolHook;
|
||||
|
||||
devtoolHook.emit('vuex:init', store);
|
||||
|
||||
devtoolHook.on('vuex:travel-to-state', function (targetState) {
|
||||
store.replaceState(targetState);
|
||||
});
|
||||
|
||||
store.subscribe(function (mutation, state) {
|
||||
devtoolHook.emit('vuex:mutation', mutation, state);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item that pass the test
|
||||
* by second argument function
|
||||
*
|
||||
* @param {Array} list
|
||||
* @param {Function} f
|
||||
* @return {*}
|
||||
*/
|
||||
/**
|
||||
* Deep copy the given object considering circular structure.
|
||||
* This function caches all nested objects and its copies.
|
||||
* If it detects circular structure, use cached copy to avoid infinite loop.
|
||||
*
|
||||
* @param {*} obj
|
||||
* @param {Array<Object>} cache
|
||||
* @return {*}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* forEach for object
|
||||
*/
|
||||
function forEachValue (obj, fn) {
|
||||
Object.keys(obj).forEach(function (key) { return fn(obj[key], key); });
|
||||
}
|
||||
|
||||
function isObject (obj) {
|
||||
return obj !== null && typeof obj === 'object'
|
||||
}
|
||||
|
||||
function isPromise (val) {
|
||||
return val && typeof val.then === 'function'
|
||||
}
|
||||
|
||||
function assert (condition, msg) {
|
||||
if (!condition) { throw new Error(("[vuex] " + msg)) }
|
||||
}
|
||||
|
||||
var Module = function Module (rawModule, runtime) {
|
||||
this.runtime = runtime;
|
||||
this._children = Object.create(null);
|
||||
this._rawModule = rawModule;
|
||||
var rawState = rawModule.state;
|
||||
this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
|
||||
};
|
||||
|
||||
var prototypeAccessors$1 = { namespaced: {} };
|
||||
|
||||
prototypeAccessors$1.namespaced.get = function () {
|
||||
return !!this._rawModule.namespaced
|
||||
};
|
||||
|
||||
Module.prototype.addChild = function addChild (key, module) {
|
||||
this._children[key] = module;
|
||||
};
|
||||
|
||||
Module.prototype.removeChild = function removeChild (key) {
|
||||
delete this._children[key];
|
||||
};
|
||||
|
||||
Module.prototype.getChild = function getChild (key) {
|
||||
return this._children[key]
|
||||
};
|
||||
|
||||
Module.prototype.update = function update (rawModule) {
|
||||
this._rawModule.namespaced = rawModule.namespaced;
|
||||
if (rawModule.actions) {
|
||||
this._rawModule.actions = rawModule.actions;
|
||||
}
|
||||
if (rawModule.mutations) {
|
||||
this._rawModule.mutations = rawModule.mutations;
|
||||
}
|
||||
if (rawModule.getters) {
|
||||
this._rawModule.getters = rawModule.getters;
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachChild = function forEachChild (fn) {
|
||||
forEachValue(this._children, fn);
|
||||
};
|
||||
|
||||
Module.prototype.forEachGetter = function forEachGetter (fn) {
|
||||
if (this._rawModule.getters) {
|
||||
forEachValue(this._rawModule.getters, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachAction = function forEachAction (fn) {
|
||||
if (this._rawModule.actions) {
|
||||
forEachValue(this._rawModule.actions, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Module.prototype.forEachMutation = function forEachMutation (fn) {
|
||||
if (this._rawModule.mutations) {
|
||||
forEachValue(this._rawModule.mutations, fn);
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperties( Module.prototype, prototypeAccessors$1 );
|
||||
|
||||
var ModuleCollection = function ModuleCollection (rawRootModule) {
|
||||
var this$1 = this;
|
||||
|
||||
// register root module (Vuex.Store options)
|
||||
this.root = new Module(rawRootModule, false);
|
||||
|
||||
// register all nested modules
|
||||
if (rawRootModule.modules) {
|
||||
forEachValue(rawRootModule.modules, function (rawModule, key) {
|
||||
this$1.register([key], rawModule, false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.get = function get (path) {
|
||||
return path.reduce(function (module, key) {
|
||||
return module.getChild(key)
|
||||
}, this.root)
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.getNamespace = function getNamespace (path) {
|
||||
var module = this.root;
|
||||
return path.reduce(function (namespace, key) {
|
||||
module = module.getChild(key);
|
||||
return namespace + (module.namespaced ? key + '/' : '')
|
||||
}, '')
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.update = function update$1 (rawRootModule) {
|
||||
update(this.root, rawRootModule);
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
|
||||
var this$1 = this;
|
||||
if ( runtime === void 0 ) runtime = true;
|
||||
|
||||
var parent = this.get(path.slice(0, -1));
|
||||
var newModule = new Module(rawModule, runtime);
|
||||
parent.addChild(path[path.length - 1], newModule);
|
||||
|
||||
// register nested modules
|
||||
if (rawModule.modules) {
|
||||
forEachValue(rawModule.modules, function (rawChildModule, key) {
|
||||
this$1.register(path.concat(key), rawChildModule, runtime);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ModuleCollection.prototype.unregister = function unregister (path) {
|
||||
var parent = this.get(path.slice(0, -1));
|
||||
var key = path[path.length - 1];
|
||||
if (!parent.getChild(key).runtime) { return }
|
||||
|
||||
parent.removeChild(key);
|
||||
};
|
||||
|
||||
function update (targetModule, newModule) {
|
||||
// update target module
|
||||
targetModule.update(newModule);
|
||||
|
||||
// update nested modules
|
||||
if (newModule.modules) {
|
||||
for (var key in newModule.modules) {
|
||||
if (!targetModule.getChild(key)) {
|
||||
console.warn(
|
||||
"[vuex] trying to add a new module '" + key + "' on hot reloading, " +
|
||||
'manual reload is needed'
|
||||
);
|
||||
return
|
||||
}
|
||||
update(targetModule.getChild(key), newModule.modules[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Vue; // bind on install
|
||||
|
||||
var Store = function Store (options) {
|
||||
var this$1 = this;
|
||||
if ( options === void 0 ) options = {};
|
||||
|
||||
assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
|
||||
assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
|
||||
|
||||
var state = options.state; if ( state === void 0 ) state = {};
|
||||
var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
|
||||
var strict = options.strict; if ( strict === void 0 ) strict = false;
|
||||
|
||||
// store internal state
|
||||
this._committing = false;
|
||||
this._actions = Object.create(null);
|
||||
this._mutations = Object.create(null);
|
||||
this._wrappedGetters = Object.create(null);
|
||||
this._modules = new ModuleCollection(options);
|
||||
this._modulesNamespaceMap = Object.create(null);
|
||||
this._subscribers = [];
|
||||
this._watcherVM = new Vue();
|
||||
|
||||
// bind commit and dispatch to self
|
||||
var store = this;
|
||||
var ref = this;
|
||||
var dispatch = ref.dispatch;
|
||||
var commit = ref.commit;
|
||||
this.dispatch = function boundDispatch (type, payload) {
|
||||
return dispatch.call(store, type, payload)
|
||||
};
|
||||
this.commit = function boundCommit (type, payload, options) {
|
||||
return commit.call(store, type, payload, options)
|
||||
};
|
||||
|
||||
// strict mode
|
||||
this.strict = strict;
|
||||
|
||||
// init root module.
|
||||
// this also recursively registers all sub-modules
|
||||
// and collects all module getters inside this._wrappedGetters
|
||||
installModule(this, state, [], this._modules.root);
|
||||
|
||||
// initialize the store vm, which is responsible for the reactivity
|
||||
// (also registers _wrappedGetters as computed properties)
|
||||
resetStoreVM(this, state);
|
||||
|
||||
// apply plugins
|
||||
plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); });
|
||||
};
|
||||
|
||||
var prototypeAccessors = { state: {} };
|
||||
|
||||
prototypeAccessors.state.get = function () {
|
||||
return this._vm._data.$$state
|
||||
};
|
||||
|
||||
prototypeAccessors.state.set = function (v) {
|
||||
assert(false, "Use store.replaceState() to explicit replace store state.");
|
||||
};
|
||||
|
||||
Store.prototype.commit = function commit (_type, _payload, _options) {
|
||||
var this$1 = this;
|
||||
|
||||
// check object-style commit
|
||||
var ref = unifyObjectStyle(_type, _payload, _options);
|
||||
var type = ref.type;
|
||||
var payload = ref.payload;
|
||||
var options = ref.options;
|
||||
|
||||
var mutation = { type: type, payload: payload };
|
||||
var entry = this._mutations[type];
|
||||
if (!entry) {
|
||||
console.error(("[vuex] unknown mutation type: " + type));
|
||||
return
|
||||
}
|
||||
this._withCommit(function () {
|
||||
entry.forEach(function commitIterator (handler) {
|
||||
handler(payload);
|
||||
});
|
||||
});
|
||||
this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
|
||||
|
||||
if (options && options.silent) {
|
||||
console.warn(
|
||||
"[vuex] mutation type: " + type + ". Silent option has been removed. " +
|
||||
'Use the filter functionality in the vue-devtools'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Store.prototype.dispatch = function dispatch (_type, _payload) {
|
||||
// check object-style dispatch
|
||||
var ref = unifyObjectStyle(_type, _payload);
|
||||
var type = ref.type;
|
||||
var payload = ref.payload;
|
||||
|
||||
var entry = this._actions[type];
|
||||
if (!entry) {
|
||||
console.error(("[vuex] unknown action type: " + type));
|
||||
return
|
||||
}
|
||||
return entry.length > 1
|
||||
? Promise.all(entry.map(function (handler) { return handler(payload); }))
|
||||
: entry[0](payload)
|
||||
};
|
||||
|
||||
Store.prototype.subscribe = function subscribe (fn) {
|
||||
var subs = this._subscribers;
|
||||
if (subs.indexOf(fn) < 0) {
|
||||
subs.push(fn);
|
||||
}
|
||||
return function () {
|
||||
var i = subs.indexOf(fn);
|
||||
if (i > -1) {
|
||||
subs.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Store.prototype.watch = function watch (getter, cb, options) {
|
||||
var this$1 = this;
|
||||
|
||||
assert(typeof getter === 'function', "store.watch only accepts a function.");
|
||||
return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
|
||||
};
|
||||
|
||||
Store.prototype.replaceState = function replaceState (state) {
|
||||
var this$1 = this;
|
||||
|
||||
this._withCommit(function () {
|
||||
this$1._vm._data.$$state = state;
|
||||
});
|
||||
};
|
||||
|
||||
Store.prototype.registerModule = function registerModule (path, rawModule) {
|
||||
if (typeof path === 'string') { path = [path]; }
|
||||
assert(Array.isArray(path), "module path must be a string or an Array.");
|
||||
this._modules.register(path, rawModule);
|
||||
installModule(this, this.state, path, this._modules.get(path));
|
||||
// reset store to update getters...
|
||||
resetStoreVM(this, this.state);
|
||||
};
|
||||
|
||||
Store.prototype.unregisterModule = function unregisterModule (path) {
|
||||
var this$1 = this;
|
||||
|
||||
if (typeof path === 'string') { path = [path]; }
|
||||
assert(Array.isArray(path), "module path must be a string or an Array.");
|
||||
this._modules.unregister(path);
|
||||
this._withCommit(function () {
|
||||
var parentState = getNestedState(this$1.state, path.slice(0, -1));
|
||||
Vue.delete(parentState, path[path.length - 1]);
|
||||
});
|
||||
resetStore(this);
|
||||
};
|
||||
|
||||
Store.prototype.hotUpdate = function hotUpdate (newOptions) {
|
||||
this._modules.update(newOptions);
|
||||
resetStore(this, true);
|
||||
};
|
||||
|
||||
Store.prototype._withCommit = function _withCommit (fn) {
|
||||
var committing = this._committing;
|
||||
this._committing = true;
|
||||
fn();
|
||||
this._committing = committing;
|
||||
};
|
||||
|
||||
Object.defineProperties( Store.prototype, prototypeAccessors );
|
||||
|
||||
function resetStore (store, hot) {
|
||||
store._actions = Object.create(null);
|
||||
store._mutations = Object.create(null);
|
||||
store._wrappedGetters = Object.create(null);
|
||||
store._modulesNamespaceMap = Object.create(null);
|
||||
var state = store.state;
|
||||
// init all modules
|
||||
installModule(store, state, [], store._modules.root, true);
|
||||
// reset vm
|
||||
resetStoreVM(store, state, hot);
|
||||
}
|
||||
|
||||
function resetStoreVM (store, state, hot) {
|
||||
var oldVm = store._vm;
|
||||
|
||||
// bind store public getters
|
||||
store.getters = {};
|
||||
var wrappedGetters = store._wrappedGetters;
|
||||
var computed = {};
|
||||
forEachValue(wrappedGetters, function (fn, key) {
|
||||
// use computed to leverage its lazy-caching mechanism
|
||||
computed[key] = function () { return fn(store); };
|
||||
Object.defineProperty(store.getters, key, {
|
||||
get: function () { return store._vm[key]; },
|
||||
enumerable: true // for local getters
|
||||
});
|
||||
});
|
||||
|
||||
// use a Vue instance to store the state tree
|
||||
// suppress warnings just in case the user has added
|
||||
// some funky global mixins
|
||||
var silent = Vue.config.silent;
|
||||
Vue.config.silent = true;
|
||||
store._vm = new Vue({
|
||||
data: {
|
||||
$$state: state
|
||||
},
|
||||
computed: computed
|
||||
});
|
||||
Vue.config.silent = silent;
|
||||
|
||||
// enable strict mode for new vm
|
||||
if (store.strict) {
|
||||
enableStrictMode(store);
|
||||
}
|
||||
|
||||
if (oldVm) {
|
||||
if (hot) {
|
||||
// dispatch changes in all subscribed watchers
|
||||
// to force getter re-evaluation for hot reloading.
|
||||
store._withCommit(function () {
|
||||
oldVm._data.$$state = null;
|
||||
});
|
||||
}
|
||||
Vue.nextTick(function () { return oldVm.$destroy(); });
|
||||
}
|
||||
}
|
||||
|
||||
function installModule (store, rootState, path, module, hot) {
|
||||
var isRoot = !path.length;
|
||||
var namespace = store._modules.getNamespace(path);
|
||||
|
||||
// register in namespace map
|
||||
if (module.namespaced) {
|
||||
store._modulesNamespaceMap[namespace] = module;
|
||||
}
|
||||
|
||||
// set state
|
||||
if (!isRoot && !hot) {
|
||||
var parentState = getNestedState(rootState, path.slice(0, -1));
|
||||
var moduleName = path[path.length - 1];
|
||||
store._withCommit(function () {
|
||||
Vue.set(parentState, moduleName, module.state);
|
||||
});
|
||||
}
|
||||
|
||||
var local = module.context = makeLocalContext(store, namespace, path);
|
||||
|
||||
module.forEachMutation(function (mutation, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerMutation(store, namespacedType, mutation, local);
|
||||
});
|
||||
|
||||
module.forEachAction(function (action, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerAction(store, namespacedType, action, local);
|
||||
});
|
||||
|
||||
module.forEachGetter(function (getter, key) {
|
||||
var namespacedType = namespace + key;
|
||||
registerGetter(store, namespacedType, getter, local);
|
||||
});
|
||||
|
||||
module.forEachChild(function (child, key) {
|
||||
installModule(store, rootState, path.concat(key), child, hot);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* make localized dispatch, commit, getters and state
|
||||
* if there is no namespace, just use root ones
|
||||
*/
|
||||
function makeLocalContext (store, namespace, path) {
|
||||
var noNamespace = namespace === '';
|
||||
|
||||
var local = {
|
||||
dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) {
|
||||
var args = unifyObjectStyle(_type, _payload, _options);
|
||||
var payload = args.payload;
|
||||
var options = args.options;
|
||||
var type = args.type;
|
||||
|
||||
if (!options || !options.root) {
|
||||
type = namespace + type;
|
||||
if (!store._actions[type]) {
|
||||
console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return store.dispatch(type, payload)
|
||||
},
|
||||
|
||||
commit: noNamespace ? store.commit : function (_type, _payload, _options) {
|
||||
var args = unifyObjectStyle(_type, _payload, _options);
|
||||
var payload = args.payload;
|
||||
var options = args.options;
|
||||
var type = args.type;
|
||||
|
||||
if (!options || !options.root) {
|
||||
type = namespace + type;
|
||||
if (!store._mutations[type]) {
|
||||
console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
store.commit(type, payload, options);
|
||||
}
|
||||
};
|
||||
|
||||
// getters and state object must be gotten lazily
|
||||
// because they will be changed by vm update
|
||||
Object.defineProperties(local, {
|
||||
getters: {
|
||||
get: noNamespace
|
||||
? function () { return store.getters; }
|
||||
: function () { return makeLocalGetters(store, namespace); }
|
||||
},
|
||||
state: {
|
||||
get: function () { return getNestedState(store.state, path); }
|
||||
}
|
||||
});
|
||||
|
||||
return local
|
||||
}
|
||||
|
||||
function makeLocalGetters (store, namespace) {
|
||||
var gettersProxy = {};
|
||||
|
||||
var splitPos = namespace.length;
|
||||
Object.keys(store.getters).forEach(function (type) {
|
||||
// skip if the target getter is not match this namespace
|
||||
if (type.slice(0, splitPos) !== namespace) { return }
|
||||
|
||||
// extract local getter type
|
||||
var localType = type.slice(splitPos);
|
||||
|
||||
// Add a port to the getters proxy.
|
||||
// Define as getter property because
|
||||
// we do not want to evaluate the getters in this time.
|
||||
Object.defineProperty(gettersProxy, localType, {
|
||||
get: function () { return store.getters[type]; },
|
||||
enumerable: true
|
||||
});
|
||||
});
|
||||
|
||||
return gettersProxy
|
||||
}
|
||||
|
||||
function registerMutation (store, type, handler, local) {
|
||||
var entry = store._mutations[type] || (store._mutations[type] = []);
|
||||
entry.push(function wrappedMutationHandler (payload) {
|
||||
handler(local.state, payload);
|
||||
});
|
||||
}
|
||||
|
||||
function registerAction (store, type, handler, local) {
|
||||
var entry = store._actions[type] || (store._actions[type] = []);
|
||||
entry.push(function wrappedActionHandler (payload, cb) {
|
||||
var res = handler({
|
||||
dispatch: local.dispatch,
|
||||
commit: local.commit,
|
||||
getters: local.getters,
|
||||
state: local.state,
|
||||
rootGetters: store.getters,
|
||||
rootState: store.state
|
||||
}, payload, cb);
|
||||
if (!isPromise(res)) {
|
||||
res = Promise.resolve(res);
|
||||
}
|
||||
if (store._devtoolHook) {
|
||||
return res.catch(function (err) {
|
||||
store._devtoolHook.emit('vuex:error', err);
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function registerGetter (store, type, rawGetter, local) {
|
||||
if (store._wrappedGetters[type]) {
|
||||
console.error(("[vuex] duplicate getter key: " + type));
|
||||
return
|
||||
}
|
||||
store._wrappedGetters[type] = function wrappedGetter (store) {
|
||||
return rawGetter(
|
||||
local.state, // local state
|
||||
local.getters, // local getters
|
||||
store.state, // root state
|
||||
store.getters // root getters
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
function enableStrictMode (store) {
|
||||
store._vm.$watch(function () { return this._data.$$state }, function () {
|
||||
assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
|
||||
}, { deep: true, sync: true });
|
||||
}
|
||||
|
||||
function getNestedState (state, path) {
|
||||
return path.length
|
||||
? path.reduce(function (state, key) { return state[key]; }, state)
|
||||
: state
|
||||
}
|
||||
|
||||
function unifyObjectStyle (type, payload, options) {
|
||||
if (isObject(type) && type.type) {
|
||||
options = payload;
|
||||
payload = type;
|
||||
type = type.type;
|
||||
}
|
||||
|
||||
assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
|
||||
|
||||
return { type: type, payload: payload, options: options }
|
||||
}
|
||||
|
||||
function install (_Vue) {
|
||||
if (Vue) {
|
||||
console.error(
|
||||
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
|
||||
);
|
||||
return
|
||||
}
|
||||
Vue = _Vue;
|
||||
applyMixin(Vue);
|
||||
}
|
||||
|
||||
// auto install in dist mode
|
||||
if (typeof window !== 'undefined' && window.Vue) {
|
||||
install(window.Vue);
|
||||
}
|
||||
|
||||
var mapState = normalizeNamespace(function (namespace, states) {
|
||||
var res = {};
|
||||
normalizeMap(states).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
res[key] = function mappedState () {
|
||||
var state = this.$store.state;
|
||||
var getters = this.$store.getters;
|
||||
if (namespace) {
|
||||
var module = getModuleByNamespace(this.$store, 'mapState', namespace);
|
||||
if (!module) {
|
||||
return
|
||||
}
|
||||
state = module.context.state;
|
||||
getters = module.context.getters;
|
||||
}
|
||||
return typeof val === 'function'
|
||||
? val.call(this, state, getters)
|
||||
: state[val]
|
||||
};
|
||||
// mark vuex getter for devtools
|
||||
res[key].vuex = true;
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapMutations = normalizeNamespace(function (namespace, mutations) {
|
||||
var res = {};
|
||||
normalizeMap(mutations).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedMutation () {
|
||||
var args = [], len = arguments.length;
|
||||
while ( len-- ) args[ len ] = arguments[ len ];
|
||||
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapMutations', namespace)) {
|
||||
return
|
||||
}
|
||||
return this.$store.commit.apply(this.$store, [val].concat(args))
|
||||
};
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapGetters = normalizeNamespace(function (namespace, getters) {
|
||||
var res = {};
|
||||
normalizeMap(getters).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedGetter () {
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
|
||||
return
|
||||
}
|
||||
if (!(val in this.$store.getters)) {
|
||||
console.error(("[vuex] unknown getter: " + val));
|
||||
return
|
||||
}
|
||||
return this.$store.getters[val]
|
||||
};
|
||||
// mark vuex getter for devtools
|
||||
res[key].vuex = true;
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
var mapActions = normalizeNamespace(function (namespace, actions) {
|
||||
var res = {};
|
||||
normalizeMap(actions).forEach(function (ref) {
|
||||
var key = ref.key;
|
||||
var val = ref.val;
|
||||
|
||||
val = namespace + val;
|
||||
res[key] = function mappedAction () {
|
||||
var args = [], len = arguments.length;
|
||||
while ( len-- ) args[ len ] = arguments[ len ];
|
||||
|
||||
if (namespace && !getModuleByNamespace(this.$store, 'mapActions', namespace)) {
|
||||
return
|
||||
}
|
||||
return this.$store.dispatch.apply(this.$store, [val].concat(args))
|
||||
};
|
||||
});
|
||||
return res
|
||||
});
|
||||
|
||||
function normalizeMap (map) {
|
||||
return Array.isArray(map)
|
||||
? map.map(function (key) { return ({ key: key, val: key }); })
|
||||
: Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
|
||||
}
|
||||
|
||||
function normalizeNamespace (fn) {
|
||||
return function (namespace, map) {
|
||||
if (typeof namespace !== 'string') {
|
||||
map = namespace;
|
||||
namespace = '';
|
||||
} else if (namespace.charAt(namespace.length - 1) !== '/') {
|
||||
namespace += '/';
|
||||
}
|
||||
return fn(namespace, map)
|
||||
}
|
||||
}
|
||||
|
||||
function getModuleByNamespace (store, helper, namespace) {
|
||||
var module = store._modulesNamespaceMap[namespace];
|
||||
if (!module) {
|
||||
console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
var index = {
|
||||
Store: Store,
|
||||
install: install,
|
||||
version: '2.3.0',
|
||||
mapState: mapState,
|
||||
mapMutations: mapMutations,
|
||||
mapGetters: mapGetters,
|
||||
mapActions: mapActions
|
||||
};
|
||||
|
||||
return index;
|
||||
|
||||
})));
|