Image optimization & Lazy Load by Optimole - Version 2.0.1

Version Description

Download this release

Release Info

Developer optimole
Plugin Icon 128x128 Image optimization & Lazy Load by Optimole
Version 2.0.1
Comparing to
See all releases

Code changes from version 2.0.0 to 2.0.1

CHANGELOG.md CHANGED
@@ -1,102 +1,109 @@
1
- ### [2.0.0](https://github.com/Codeinwp/optimole-wp/compare/v1.1.2...v2.0.0) (2019-01-21)
2
-
3
-
4
- #### Bug Fixes
5
-
6
- * errors on low PHP environments when PHP_INT_MIN constant is not available ([44eb4af](https://github.com/Codeinwp/optimole-wp/commit/44eb4af))
7
-
8
- * fix tag replacement on lazy load, preserve image size when found ([5c6ef70](https://github.com/Codeinwp/optimole-wp/commit/5c6ef70))
9
-
10
- * improve image size replacement mapping for custom image sizes ([d816ccb](https://github.com/Codeinwp/optimole-wp/commit/d816ccb))
11
-
12
- * improve lazyload fade in effect, fixes [#71](https://github.com/Codeinwp/optimole-wp/issues/71) ([eb0f76c](https://github.com/Codeinwp/optimole-wp/commit/eb0f76c))
13
-
14
- * possible issue with image replacement not taking place when other buffer handler is registered ([3ce600a](https://github.com/Codeinwp/optimole-wp/commit/3ce600a))
15
-
16
- * resize behaviour for WordPress defined image sizes, preserve cropping for custom sizes ([a42f830](https://github.com/Codeinwp/optimole-wp/commit/a42f830))
17
-
18
-
19
-
20
- #### Documentation
21
-
22
- * add basic faq to readme file ([2c09d26](https://github.com/Codeinwp/optimole-wp/commit/2c09d26))
23
-
24
- * adds contributor related docs and github templates ([c7bbce2](https://github.com/Codeinwp/optimole-wp/commit/c7bbce2))
25
-
26
-
27
-
28
- #### Features
29
-
30
- * adds new service schema ([330fba0](https://github.com/Codeinwp/optimole-wp/commit/330fba0))
31
-
32
- * adds watermark integration along with various options for watermark position ([6a4538a](https://github.com/Codeinwp/optimole-wp/commit/6a4538a))
33
-
34
- * deactivate plugin on lower php versions, adds notice for PHP for upgrade ([58d2607](https://github.com/Codeinwp/optimole-wp/commit/58d2607))
35
-
36
-
37
-
38
- #### Performance Improvements
39
-
40
- * improve srcset replacement, use attachement id when present ([5587221](https://github.com/Codeinwp/optimole-wp/commit/5587221))
41
-
42
- * improve type casting on size constrain ([589b046](https://github.com/Codeinwp/optimole-wp/commit/589b046))
43
-
44
- ### v1.1.2 - 2018-12-24
45
- **Changes:**
46
- * Minor fixes to Optimole dashboard page.
47
- * Fixes DNS prefetch call when lazyload is off.
48
- * Enable lazyload and javascript replacement by default for new users.
49
-
50
- ### v1.1.1 - 2018-12-10
51
- **Changes:**
52
- * Improve the lazy loading mechanism and adds compatibility with the new javascript library.
53
- * Improve sample images and quality selector integration.
54
- * Adds a notice when the Rest API is not available.
55
- * Adds notice for new users on how the plugin works.
56
- * Tested up with WordPress 5.0, all working smooth.
57
- * Fix possible issues with thumbnails when the original image is available on a different url scheme.
58
- * Ignore lazyload replacement on feed/amp pages.
59
-
60
- ### v1.1.0 - 2018-11-16
61
- **Changes:**
62
- * Integrates lazy load feature with support for low-quality placeholders ( LQIP ).
63
- * Integrates Javascript library which delivers images at the right size for each device, including Retina.
64
- * Improve image replacement algorithm.
65
- * Improves compatibility with Elementor and Gutenberg.
66
- * Adds support for Custom CNAME and Client hints.
67
- * Improves support for custom CDN.
68
- * Improves AMP support.
69
- * Improves compatibility with WordPress Multisites.
70
-
71
- ### v1.0.5 - 2018-10-05
72
- **Changes:**
73
- * Adds max width/height option.
74
- * Improves registration workflow.
75
- * Adds image comparison slider ratio.
76
- * Adds logo on link preload.
77
-
78
- ### v1.0.4 - 2018-10-03
79
- **Changes:**
80
- * Adds in-plugin service registration.
81
- * Adds image quality control.
82
- * Adds slider for image comparison.
83
- * Improvements to UX and workflow.
84
-
85
- ### v1.0.3 - 2018-09-26
86
- **Changes:**
87
- * Adds redirect on first install.
88
- * Improve elementor assets replacement.
89
-
90
- ### v1.0.2 - 2018-09-25
91
- **Changes:**
92
- * Improve compatibility with elementor external css files.
93
- * Adds generator tag.
94
- * Improve replacer handler hook register.
95
-
96
- ### v1.0.1 - 2018-09-23
97
- **Changes:**
98
- * Tag first stable version for wordpress.org.
99
-
100
- ### v1.0.0 - 2018-09-11
101
- **Changes:**
102
- * First version of the plugin
1
+ #### [2.0.1](https://github.com/Codeinwp/optimole-wp/compare/v2.0.0...v2.0.1) (2019-01-21)
2
+
3
+
4
+ **Bug Fixes**
5
+
6
+ * fix javascript library production url ([aed9433](https://github.com/Codeinwp/optimole-wp/commit/aed9433))
7
+
8
+ ### [2.0.0](https://github.com/Codeinwp/optimole-wp/compare/v1.1.2...v2.0.0) (2019-01-21)
9
+
10
+
11
+ #### Bug Fixes
12
+
13
+ * errors on low PHP environments when PHP_INT_MIN constant is not available ([44eb4af](https://github.com/Codeinwp/optimole-wp/commit/44eb4af))
14
+
15
+ * fix tag replacement on lazy load, preserve image size when found ([5c6ef70](https://github.com/Codeinwp/optimole-wp/commit/5c6ef70))
16
+
17
+ * improve image size replacement mapping for custom image sizes ([d816ccb](https://github.com/Codeinwp/optimole-wp/commit/d816ccb))
18
+
19
+ * improve lazyload fade in effect, fixes [#71](https://github.com/Codeinwp/optimole-wp/issues/71) ([eb0f76c](https://github.com/Codeinwp/optimole-wp/commit/eb0f76c))
20
+
21
+ * possible issue with image replacement not taking place when other buffer handler is registered ([3ce600a](https://github.com/Codeinwp/optimole-wp/commit/3ce600a))
22
+
23
+ * resize behaviour for WordPress defined image sizes, preserve cropping for custom sizes ([a42f830](https://github.com/Codeinwp/optimole-wp/commit/a42f830))
24
+
25
+
26
+
27
+ #### Documentation
28
+
29
+ * add basic faq to readme file ([2c09d26](https://github.com/Codeinwp/optimole-wp/commit/2c09d26))
30
+
31
+ * adds contributor related docs and github templates ([c7bbce2](https://github.com/Codeinwp/optimole-wp/commit/c7bbce2))
32
+
33
+
34
+
35
+ #### Features
36
+
37
+ * adds new service schema ([330fba0](https://github.com/Codeinwp/optimole-wp/commit/330fba0))
38
+
39
+ * adds watermark integration along with various options for watermark position ([6a4538a](https://github.com/Codeinwp/optimole-wp/commit/6a4538a))
40
+
41
+ * deactivate plugin on lower php versions, adds notice for PHP for upgrade ([58d2607](https://github.com/Codeinwp/optimole-wp/commit/58d2607))
42
+
43
+
44
+
45
+ #### Performance Improvements
46
+
47
+ * improve srcset replacement, use attachement id when present ([5587221](https://github.com/Codeinwp/optimole-wp/commit/5587221))
48
+
49
+ * improve type casting on size constrain ([589b046](https://github.com/Codeinwp/optimole-wp/commit/589b046))
50
+
51
+ ### v1.1.2 - 2018-12-24
52
+ **Changes:**
53
+ * Minor fixes to Optimole dashboard page.
54
+ * Fixes DNS prefetch call when lazyload is off.
55
+ * Enable lazyload and javascript replacement by default for new users.
56
+
57
+ ### v1.1.1 - 2018-12-10
58
+ **Changes:**
59
+ * Improve the lazy loading mechanism and adds compatibility with the new javascript library.
60
+ * Improve sample images and quality selector integration.
61
+ * Adds a notice when the Rest API is not available.
62
+ * Adds notice for new users on how the plugin works.
63
+ * Tested up with WordPress 5.0, all working smooth.
64
+ * Fix possible issues with thumbnails when the original image is available on a different url scheme.
65
+ * Ignore lazyload replacement on feed/amp pages.
66
+
67
+ ### v1.1.0 - 2018-11-16
68
+ **Changes:**
69
+ * Integrates lazy load feature with support for low-quality placeholders ( LQIP ).
70
+ * Integrates Javascript library which delivers images at the right size for each device, including Retina.
71
+ * Improve image replacement algorithm.
72
+ * Improves compatibility with Elementor and Gutenberg.
73
+ * Adds support for Custom CNAME and Client hints.
74
+ * Improves support for custom CDN.
75
+ * Improves AMP support.
76
+ * Improves compatibility with WordPress Multisites.
77
+
78
+ ### v1.0.5 - 2018-10-05
79
+ **Changes:**
80
+ * Adds max width/height option.
81
+ * Improves registration workflow.
82
+ * Adds image comparison slider ratio.
83
+ * Adds logo on link preload.
84
+
85
+ ### v1.0.4 - 2018-10-03
86
+ **Changes:**
87
+ * Adds in-plugin service registration.
88
+ * Adds image quality control.
89
+ * Adds slider for image comparison.
90
+ * Improvements to UX and workflow.
91
+
92
+ ### v1.0.3 - 2018-09-26
93
+ **Changes:**
94
+ * Adds redirect on first install.
95
+ * Improve elementor assets replacement.
96
+
97
+ ### v1.0.2 - 2018-09-25
98
+ **Changes:**
99
+ * Improve compatibility with elementor external css files.
100
+ * Adds generator tag.
101
+ * Improve replacer handler hook register.
102
+
103
+ ### v1.0.1 - 2018-09-23
104
+ **Changes:**
105
+ * Tag first stable version for wordpress.org.
106
+
107
+ ### v1.0.0 - 2018-09-11
108
+ **Changes:**
109
+ * First version of the plugin
README.md CHANGED
@@ -1,223 +1,235 @@
1
- # Image optimization service by Optimole #
2
- **Contributors:** [optimole](https://profiles.wordpress.org/optimole)
3
- **Tags:** image optmization, cdn, image compression, compress image, images, optimization, perfomance, photos
4
- **Requires at least:** 4.7
5
- **Tested up to:** 5.0
6
- **Requires PHP:** 5.4
7
- **License:** GPLv3
8
- **License URI:** https://www.gnu.org/licenses/gpl-3.0.en.html
9
-
10
- End-to-end image processing
11
- With OptiMole, your site’s images will be cropped, optimized and processed on-the-fly.
12
-
13
-
14
- ## Description ##
15
- **Image optimization & resizing**
16
- Images are processed for best results with both lossless and lossy optimization and are automatically resized for any device.
17
-
18
- **Image acceleration through CDN**
19
- If you dont use a CDN, we got you covered, we will serve the images using our default CDN. You already have one, just let us know and we can integrate yours.
20
-
21
- **On-the-fly image handling**
22
- Dynamic manipulation of images and videos (resize, compress and serve via CDN on the fly).
23
-
24
- **Easy tracking & monitoring**
25
- Check how OptiMole is improving your site from day 1. Transparent optimization stats are always available.
26
-
27
- ### How does it work? ###
28
-
29
- This plugin connects via API to OptiMole [image optimization service](https://optimole.com/) in order to send the images to its servers and crop, optimize and process them on-the-fly. The EXIF data will either be stripped and it is not stored on our servers. Optimole does not interact with the visitors on your website. We care about your privacy so check our [terms of use](https://optimole.com/terms/).
30
-
31
- The plugin will rewrite your image URLs to replace them with OptiMole URLs. Your origin images will be downloaded from your storage, processed by the OptiMole infrastructure and cached in the CDN. NO development needed. Simply set up your account and enjoy faster image loading.
32
-
33
-
34
- ## Screenshots ##
35
-
36
- 1. Welcome screen
37
- 2. Connect screen
38
- 3. Plugin dashboard
39
- 4. Plugin settings
40
-
41
- ## Changelog ##
42
-
43
- ### [2.0.0](https://github.com/Codeinwp/optimole-wp/compare/v1.1.2...v2.0.0) (2019-01-21)
44
-
45
-
46
- #### Bug Fixes
47
-
48
- * errors on low PHP environments when PHP_INT_MIN constant is not available ([44eb4af](https://github.com/Codeinwp/optimole-wp/commit/44eb4af))
49
-
50
- * fix tag replacement on lazy load, preserve image size when found ([5c6ef70](https://github.com/Codeinwp/optimole-wp/commit/5c6ef70))
51
-
52
- * improve image size replacement mapping for custom image sizes ([d816ccb](https://github.com/Codeinwp/optimole-wp/commit/d816ccb))
53
-
54
- * improve lazyload fade in effect, fixes [#71](https://github.com/Codeinwp/optimole-wp/issues/71) ([eb0f76c](https://github.com/Codeinwp/optimole-wp/commit/eb0f76c))
55
-
56
- * possible issue with image replacement not taking place when other buffer handler is registered ([3ce600a](https://github.com/Codeinwp/optimole-wp/commit/3ce600a))
57
-
58
- * resize behaviour for WordPress defined image sizes, preserve cropping for custom sizes ([a42f830](https://github.com/Codeinwp/optimole-wp/commit/a42f830))
59
-
60
-
61
-
62
- #### Documentation
63
-
64
- * add basic faq to readme file ([2c09d26](https://github.com/Codeinwp/optimole-wp/commit/2c09d26))
65
-
66
- * adds contributor related docs and github templates ([c7bbce2](https://github.com/Codeinwp/optimole-wp/commit/c7bbce2))
67
-
68
-
69
-
70
- #### Features
71
-
72
- * adds new service schema ([330fba0](https://github.com/Codeinwp/optimole-wp/commit/330fba0))
73
-
74
- * adds watermark integration along with various options for watermark position ([6a4538a](https://github.com/Codeinwp/optimole-wp/commit/6a4538a))
75
-
76
- * deactivate plugin on lower php versions, adds notice for PHP for upgrade ([58d2607](https://github.com/Codeinwp/optimole-wp/commit/58d2607))
77
-
78
-
79
-
80
- #### Performance Improvements
81
-
82
- * improve srcset replacement, use attachement id when present ([5587221](https://github.com/Codeinwp/optimole-wp/commit/5587221))
83
-
84
- * improve type casting on size constrain ([589b046](https://github.com/Codeinwp/optimole-wp/commit/589b046))
85
-
86
-
87
-
88
-
89
-
90
- ### 1.1.2 - 2018-12-24 ###
91
-
92
- * Minor fixes to Optimole dashboard page.
93
- * Fixes DNS prefetch call when lazyload is off.
94
- * Enable lazyload and javascript replacement by default for new users.
95
-
96
-
97
- ### 1.1.1 - 2018-12-10 ###
98
-
99
- * Improve the lazy loading mechanism and adds compatibility with the new javascript library.
100
- * Improve sample images and quality selector integration.
101
- * Adds a notice when the Rest API is not available.
102
- * Adds notice for new users on how the plugin works.
103
- * Tested up with WordPress 5.0, all working smooth.
104
- * Fix possible issues with thumbnails when the original image is available on a different url scheme.
105
- * Ignore lazyload replacement on feed/amp pages.
106
-
107
-
108
- ### 1.1.0 - 2018-11-16 ###
109
-
110
- * Integrates lazy load feature with support for low-quality placeholders ( LQIP ).
111
- * Integrates Javascript library which delivers images at the right size for each device, including Retina.
112
- * Improve image replacement algorithm.
113
- * Improves compatibility with Elementor and Gutenberg.
114
- * Adds support for Custom CNAME and Client hints.
115
- * Improves support for custom CDN.
116
- * Improves AMP support.
117
- * Improves compatibility with WordPress Multisites.
118
-
119
-
120
- ### 1.0.5 - 2018-10-05 ###
121
-
122
- * Adds max width/height option.
123
- * Improves registration workflow.
124
- * Adds image comparison slider ratio.
125
- * Adds logo on link preload.
126
-
127
-
128
- ### 1.0.4 - 2018-10-03 ###
129
-
130
- * Adds in-plugin service registration.
131
- * Adds image quality control.
132
- * Adds slider for image comparison.
133
- * Improvements to UX and workflow.
134
-
135
-
136
- ### 1.0.3 - 2018-09-26 ###
137
-
138
- * Adds redirect on first install.
139
- * Improve elementor assets replacement.
140
-
141
-
142
- ### 1.0.2 - 2018-09-25 ###
143
-
144
- * Improve compatibility with elementor external css files.
145
- * Adds generator tag.
146
- * Improve replacer handler hook register.
147
-
148
-
149
- ### 1.0.1 - 2018-09-23 ###
150
-
151
- * Tag first stable version for wordpress.org.
152
-
153
-
154
-
155
- ### 1.0.0 - 2018-09-22 ###
156
- * First version of the plugin
157
-
158
- ## Installation ##
159
- The following are the steps to install the OptiMole plugin
160
-
161
- 1. In your WordPress Administration Panels, click on Add New option under Plugins from the menu.
162
- Click on upload at the top.
163
- 2. Browse the location and select the OptiMole Plugin and click install now.
164
- 3. Go to Media -> OptiMole and follow in the instructions on how to enable the service.
165
-
166
- ## Frequently Asked Questions ##
167
-
168
- ### How many images I can optimize with each plan? ###
169
-
170
- The number of images that you can optimize depends on your original image size and the number of transformations you do for it. Using the Free plan you can optimize up to 1 GB of images, which means around 2000 images at an average of 500Kb per image.
171
-
172
- ### What happens if I exceed plan limits? ###
173
-
174
- Once you exceed these, we will contact you and kindly ask to upgrade to the plan that fits you best.
175
-
176
- ### What Content Delivery Network (CDN) do you use? ###
177
-
178
- Our FREE plan uses our custom made CDN built with 7 locations around the globe. For the paid plans, we have direct integration with Amazon Cloudfront, with more than 130 locations around the globe.
179
-
180
- ### I'm already using a CDN, can I use that instead of yours ? ###
181
-
182
- Short answer, YES. We can help you integrate your default CDN but it will require some additional work from our side and is available to Enterprise plans.
183
-
184
- ### I'm already using an image optimization plugin, why should I switch to OptiMole? ###
185
-
186
- You don’t need to change your existing optimization plugin, image optimization is just a small part of what we do, if you are happy with ShortPixel for e.g, feel free to continue to use it, OptiMole would then take care only of serving your image at the RIGHT size, advanced cropping and smart lazy-loading.
187
-
188
- ### Will the original images be deleted? ###
189
-
190
- Absolutely No. We use your original images as sources when deliver the optimized images.
191
-
192
- ### What is the difference between the Auto, High, Medium, Low compression levels? ###
193
-
194
- A higher compression might result in a small loss of image quality. Selecting the auto level will let Optimole choose the minimum size with no loss in the quality of your picture.
195
-
196
- ### I used Kraken, Shortpixel, Optimus, EWWW or WP Smush, Imagify will OptiMole further optimize my images? ###
197
-
198
- Yes, Optimole will also take care of serving your image at the RIGHT size for your visitors and optimize them to the best possible format for their browser.
199
-
200
- ### Which formats can be optimized ? ###
201
-
202
- For now we support jpg, png and svg format.
203
-
204
- ### Does Optimole automatically serve WebP for Chrome users ? ###
205
-
206
- Yes. We automatically detect user browser and serve WebP if is supported, otherwise we optimize the image in the original format.
207
-
208
- ### Can i disable lazyload for PNG images ? ###
209
-
210
- Yes. You need to add `define("OPTML_DISABLE_PNG_LAZYLOAD",true);` to `your wp-config.php` file.
211
-
212
- ### Can i disable optimization for a certain image ? ###
213
-
214
- Yes, you can follow this code snippet and replace the sample image with the one you need:
215
- <code>
216
- add_filter('optml_dont_replace_url', function( $old, $url ) {
217
- if ( $url === 'https://example.com/wp-content/uploads/2018/09/1.jpg' ) {
218
- return true;
219
- }
220
- return $old;
221
-
222
- }, 10, 2);
223
</code>
1
+ # Image optimization service by Optimole #
2
+ **Contributors:** [optimole](https://profiles.wordpress.org/optimole)
3
+ **Tags:** image optmization, cdn, image compression, compress image, images, optimization, perfomance, photos
4
+ **Requires at least:** 4.7
5
+ **Tested up to:** 5.0
6
+ **Requires PHP:** 5.4
7
+ **License:** GPLv3
8
+ **License URI:** https://www.gnu.org/licenses/gpl-3.0.en.html
9
+
10
+ End-to-end image processing
11
+ With OptiMole, your site’s images will be cropped, optimized and processed on-the-fly.
12
+
13
+
14
+ ## Description ##
15
+ **Image optimization & resizing**
16
+ Images are processed for best results with both lossless and lossy optimization and are automatically resized for any device.
17
+
18
+ **Image acceleration through CDN**
19
+ If you dont use a CDN, we got you covered, we will serve the images using our default CDN. You already have one, just let us know and we can integrate yours.
20
+
21
+ **On-the-fly image handling**
22
+ Dynamic manipulation of images and videos (resize, compress and serve via CDN on the fly).
23
+
24
+ **Easy tracking & monitoring**
25
+ Check how OptiMole is improving your site from day 1. Transparent optimization stats are always available.
26
+
27
+ ### How does it work? ###
28
+
29
+ This plugin connects via API to OptiMole [image optimization service](https://optimole.com/) in order to send the images to its servers and crop, optimize and process them on-the-fly. The EXIF data will either be stripped and it is not stored on our servers. Optimole does not interact with the visitors on your website. We care about your privacy so check our [terms of use](https://optimole.com/terms/).
30
+
31
+ The plugin will rewrite your image URLs to replace them with OptiMole URLs. Your origin images will be downloaded from your storage, processed by the OptiMole infrastructure and cached in the CDN. NO development needed. Simply set up your account and enjoy faster image loading.
32
+
33
+
34
+ ## Screenshots ##
35
+
36
+ 1. Welcome screen
37
+ 2. Connect screen
38
+ 3. Plugin dashboard
39
+ 4. Plugin settings
40
+
41
+ ## Changelog ##
42
+
43
+ #### [2.0.1](https://github.com/Codeinwp/optimole-wp/compare/v2.0.0...v2.0.1) (2019-01-21)
44
+
45
+
46
+ **Bug Fixes**
47
+
48
+ * fix javascript library production url ([aed9433](https://github.com/Codeinwp/optimole-wp/commit/aed9433))
49
+
50
+
51
+
52
+
53
+
54
+
55
+ ### [2.0.0](https://github.com/Codeinwp/optimole-wp/compare/v1.1.2...v2.0.0) (2019-01-21)
56
+
57
+
58
+ #### Bug Fixes
59
+
60
+ * errors on low PHP environments when PHP_INT_MIN constant is not available ([44eb4af](https://github.com/Codeinwp/optimole-wp/commit/44eb4af))
61
+
62
+ * fix tag replacement on lazy load, preserve image size when found ([5c6ef70](https://github.com/Codeinwp/optimole-wp/commit/5c6ef70))
63
+
64
+ * improve image size replacement mapping for custom image sizes ([d816ccb](https://github.com/Codeinwp/optimole-wp/commit/d816ccb))
65
+
66
+ * improve lazyload fade in effect, fixes [#71](https://github.com/Codeinwp/optimole-wp/issues/71) ([eb0f76c](https://github.com/Codeinwp/optimole-wp/commit/eb0f76c))
67
+
68
+ * possible issue with image replacement not taking place when other buffer handler is registered ([3ce600a](https://github.com/Codeinwp/optimole-wp/commit/3ce600a))
69
+
70
+ * resize behaviour for WordPress defined image sizes, preserve cropping for custom sizes ([a42f830](https://github.com/Codeinwp/optimole-wp/commit/a42f830))
71
+
72
+
73
+
74
+ #### Documentation
75
+
76
+ * add basic faq to readme file ([2c09d26](https://github.com/Codeinwp/optimole-wp/commit/2c09d26))
77
+
78
+ * adds contributor related docs and github templates ([c7bbce2](https://github.com/Codeinwp/optimole-wp/commit/c7bbce2))
79
+
80
+
81
+
82
+ #### Features
83
+
84
+ * adds new service schema ([330fba0](https://github.com/Codeinwp/optimole-wp/commit/330fba0))
85
+
86
+ * adds watermark integration along with various options for watermark position ([6a4538a](https://github.com/Codeinwp/optimole-wp/commit/6a4538a))
87
+
88
+ * deactivate plugin on lower php versions, adds notice for PHP for upgrade ([58d2607](https://github.com/Codeinwp/optimole-wp/commit/58d2607))
89
+
90
+
91
+
92
+ #### Performance Improvements
93
+
94
+ * improve srcset replacement, use attachement id when present ([5587221](https://github.com/Codeinwp/optimole-wp/commit/5587221))
95
+
96
+ * improve type casting on size constrain ([589b046](https://github.com/Codeinwp/optimole-wp/commit/589b046))
97
+
98
+
99
+
100
+
101
+
102
+ ### 1.1.2 - 2018-12-24 ###
103
+
104
+ * Minor fixes to Optimole dashboard page.
105
+ * Fixes DNS prefetch call when lazyload is off.
106
+ * Enable lazyload and javascript replacement by default for new users.
107
+
108
+
109
+ ### 1.1.1 - 2018-12-10 ###
110
+
111
+ * Improve the lazy loading mechanism and adds compatibility with the new javascript library.
112
+ * Improve sample images and quality selector integration.
113
+ * Adds a notice when the Rest API is not available.
114
+ * Adds notice for new users on how the plugin works.
115
+ * Tested up with WordPress 5.0, all working smooth.
116
+ * Fix possible issues with thumbnails when the original image is available on a different url scheme.
117
+ * Ignore lazyload replacement on feed/amp pages.
118
+
119
+
120
+ ### 1.1.0 - 2018-11-16 ###
121
+
122
+ * Integrates lazy load feature with support for low-quality placeholders ( LQIP ).
123
+ * Integrates Javascript library which delivers images at the right size for each device, including Retina.
124
+ * Improve image replacement algorithm.
125
+ * Improves compatibility with Elementor and Gutenberg.
126
+ * Adds support for Custom CNAME and Client hints.
127
+ * Improves support for custom CDN.
128
+ * Improves AMP support.
129
+ * Improves compatibility with WordPress Multisites.
130
+
131
+
132
+ ### 1.0.5 - 2018-10-05 ###
133
+
134
+ * Adds max width/height option.
135
+ * Improves registration workflow.
136
+ * Adds image comparison slider ratio.
137
+ * Adds logo on link preload.
138
+
139
+
140
+ ### 1.0.4 - 2018-10-03 ###
141
+
142
+ * Adds in-plugin service registration.
143
+ * Adds image quality control.
144
+ * Adds slider for image comparison.
145
+ * Improvements to UX and workflow.
146
+
147
+
148
+ ### 1.0.3 - 2018-09-26 ###
149
+
150
+ * Adds redirect on first install.
151
+ * Improve elementor assets replacement.
152
+
153
+
154
+ ### 1.0.2 - 2018-09-25 ###
155
+
156
+ * Improve compatibility with elementor external css files.
157
+ * Adds generator tag.
158
+ * Improve replacer handler hook register.
159
+
160
+
161
+ ### 1.0.1 - 2018-09-23 ###
162
+
163
+ * Tag first stable version for wordpress.org.
164
+
165
+
166
+
167
+ ### 1.0.0 - 2018-09-22 ###
168
+ * First version of the plugin
169
+
170
+ ## Installation ##
171
+ The following are the steps to install the OptiMole plugin
172
+
173
+ 1. In your WordPress Administration Panels, click on Add New option under Plugins from the menu.
174
+ Click on upload at the top.
175
+ 2. Browse the location and select the OptiMole Plugin and click install now.
176
+ 3. Go to Media -> OptiMole and follow in the instructions on how to enable the service.
177
+
178
+ ## Frequently Asked Questions ##
179
+
180
+ ### How many images I can optimize with each plan? ###
181
+
182
+ The number of images that you can optimize depends on your original image size and the number of transformations you do for it. Using the Free plan you can optimize up to 1 GB of images, which means around 2000 images at an average of 500Kb per image.
183
+
184
+ ### What happens if I exceed plan limits? ###
185
+
186
+ Once you exceed these, we will contact you and kindly ask to upgrade to the plan that fits you best.
187
+
188
+ ### What Content Delivery Network (CDN) do you use? ###
189
+
190
+ Our FREE plan uses our custom made CDN built with 7 locations around the globe. For the paid plans, we have direct integration with Amazon Cloudfront, with more than 130 locations around the globe.
191
+
192
+ ### I'm already using a CDN, can I use that instead of yours ? ###
193
+
194
+ Short answer, YES. We can help you integrate your default CDN but it will require some additional work from our side and is available to Enterprise plans.
195
+
196
+ ### I'm already using an image optimization plugin, why should I switch to OptiMole? ###
197
+
198
+ You don’t need to change your existing optimization plugin, image optimization is just a small part of what we do, if you are happy with ShortPixel for e.g, feel free to continue to use it, OptiMole would then take care only of serving your image at the RIGHT size, advanced cropping and smart lazy-loading.
199
+
200
+ ### Will the original images be deleted? ###
201
+
202
+ Absolutely No. We use your original images as sources when deliver the optimized images.
203
+
204
+ ### What is the difference between the Auto, High, Medium, Low compression levels? ###
205
+
206
+ A higher compression might result in a small loss of image quality. Selecting the auto level will let Optimole choose the minimum size with no loss in the quality of your picture.
207
+
208
+ ### I used Kraken, Shortpixel, Optimus, EWWW or WP Smush, Imagify will OptiMole further optimize my images? ###
209
+
210
+ Yes, Optimole will also take care of serving your image at the RIGHT size for your visitors and optimize them to the best possible format for their browser.
211
+
212
+ ### Which formats can be optimized ? ###
213
+
214
+ For now we support jpg, png and svg format.
215
+
216
+ ### Does Optimole automatically serve WebP for Chrome users ? ###
217
+
218
+ Yes. We automatically detect user browser and serve WebP if is supported, otherwise we optimize the image in the original format.
219
+
220
+ ### Can i disable lazyload for PNG images ? ###
221
+
222
+ Yes. You need to add `define("OPTML_DISABLE_PNG_LAZYLOAD",true);` to `your wp-config.php` file.
223
+
224
+ ### Can i disable optimization for a certain image ? ###
225
+
226
+ Yes, you can follow this code snippet and replace the sample image with the one you need:
227
+ <code>
228
+ add_filter('optml_dont_replace_url', function( $old, $url ) {
229
+ if ( $url === 'https://example.com/wp-content/uploads/2018/09/1.jpg' ) {
230
+ return true;
231
+ }
232
+ return $old;
233
+
234
+ }, 10, 2);
235
</code>
assets/css/style.scss CHANGED
@@ -1,189 +1,189 @@
1
-
2
- #optimole-app {
3
- padding: 0 30px 0 20px;
4
-
5
- $primary: #EF686B;
6
- $success: #34a85e;
7
- $danger: #D54222;
8
- $info: #5180C1;
9
-
10
- @import "~bulma/bulma";
11
-
12
- .card {
13
- transition: all 750ms ease-in-out;
14
- border: 0;
15
- border-radius: .1875rem;
16
- -webkit-box-shadow: 0 1px 15px 1px rgba(39, 39, 39, .1);
17
- box-shadow: 0 1px 15px 1px rgba(39, 39, 39, .1);
18
- }
19
-
20
- .logo {
21
- margin-bottom: 10px;
22
- img {
23
- max-width: 180px;
24
- margin: 0 auto;
25
- }
26
- }
27
- .vue-js-switch {
28
- align-self: center;
29
- }
30
- .api-key-control {
31
- padding: 0 15px 0 0;
32
- }
33
-
34
- .api-key-field .button.is-danger {
35
- padding-left: 20px;
36
- padding-right: 20px;
37
- }
38
-
39
- .api-key-label {
40
- align-self: center;
41
- margin: 0.5em 10px 0.5em 0;
42
- font-size: 1em;
43
- }
44
- .header {
45
- padding: 0 1.5rem 0;
46
- &.level {
47
- margin-bottom: 0;
48
- }
49
- }
50
- .account {
51
- img {
52
- border-top-right-radius: 4px;
53
- border-bottom-right-radius: 4px;
54
- }
55
- .label {
56
- margin-bottom: 0;
57
- }
58
- }
59
-
60
- //Optimized images.
61
- .optimized-images {
62
-
63
- table td, table th {
64
- vertical-align: middle;
65
- }
66
- }
67
- .media-diff {
68
- position: relative;
69
- margin: 0 auto;
70
- video, img {
71
- display: block;
72
- position: absolute;
73
- top: 0;
74
- left: 0;
75
- width: 100%;
76
- height: 100%;
77
- }
78
- }
79
-
80
- .origin-wrapper {
81
- position: absolute;
82
- left: 0;
83
- top: 0;
84
- width: 100%;
85
- height: 100%;
86
- overflow: hidden;
87
- z-index: 1;
88
- transform: translateZ(0);
89
- will-change: width;
90
- }
91
-
92
- .handle {
93
- position: absolute;
94
- top: 0;
95
- bottom: 0;
96
- color: rgba(255, 255, 255, 0.80);
97
- background-color: rgba(255, 255, 255, 0.80);;
98
- width: 2px;
99
- cursor: ew-resize;
100
- transform: translateX(-50%) translateZ(0);
101
- z-index: 2;
102
- will-change: left;
103
- left: 200px;
104
- }
105
-
106
- .cursor {
107
- position: absolute;
108
- top: 50%;
109
- left: 50%;
110
- transform: translateX(-50%) translateZ(0);
111
- .circle {
112
- background-color: rgba(255, 255, 255, 0.80);
113
- width: 24px;
114
- height: 24px;
115
- border-radius: 50%;
116
- }
117
- }
118
- .no-padding-right{
119
- padding-right:0px !important;
120
- }
121
- }
122
-
123
- //Fade animation.
124
- .fade-enter-active, .fade-leave-active {
125
- transition: opacity .5s;
126
- }
127
-
128
- .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
129
- {
130
- opacity: 0;
131
- }
132
-
133
- .media_page_optimole #wpbody-content > * {
134
- display: none !important;
135
- }
136
-
137
- .media_page_optimole #wpbody-content > #optimole-app {
138
- display: block !important;
139
- }
140
-
141
- #optimole-app img.optml-image {
142
- float: left;
143
- max-width: 100px;
144
- width: auto;
145
- margin: auto;
146
- }
147
- #optimole-app img.optml-image-watermark {
148
- width:50px;
149
- }
150
-
151
- .optml-ratio-feedback .emoji {
152
- font-size: 1.5em;
153
- }
154
-
155
-
156
- .optml-ratio-feedback {
157
- float: right;
158
- padding-right: 20px;
159
- }
160
- .optml-image-heading {
161
- text-align: left;
162
- }
163
-
164
- th.optml-image-ratio-heading {
165
- text-align: right !important;
166
- font-size: 150%;
167
- }
168
- @media screen and (max-width: 768px) {
169
- li:not(.is-active) > a > span:not(.icon) {
170
- visibility: hidden;
171
- position: absolute;
172
- }
173
-
174
- nav.tabs li:not(.is-active) {
175
- -webkit-box-flex: 0;
176
- -ms-flex-positive: 0;
177
- flex-grow: 0;
178
- -ms-flex-negative: 1;
179
- flex-shrink: 1;
180
- }
181
-
182
- .tabs .icon {
183
- margin-left: 0.5em;
184
- }
185
- }
186
-
187
- .tabs li {
188
- transition: flex-grow 1s ease;
189
- }
1
+
2
+ #optimole-app {
3
+ padding: 0 30px 0 20px;
4
+
5
+ $primary: #EF686B;
6
+ $success: #34a85e;
7
+ $danger: #D54222;
8
+ $info: #5180C1;
9
+
10
+ @import "~bulma/bulma";
11
+
12
+ .card {
13
+ transition: all 750ms ease-in-out;
14
+ border: 0;
15
+ border-radius: .1875rem;
16
+ -webkit-box-shadow: 0 1px 15px 1px rgba(39, 39, 39, .1);
17
+ box-shadow: 0 1px 15px 1px rgba(39, 39, 39, .1);
18
+ }
19
+
20
+ .logo {
21
+ margin-bottom: 10px;
22
+ img {
23
+ max-width: 180px;
24
+ margin: 0 auto;
25
+ }
26
+ }
27
+ .vue-js-switch {
28
+ align-self: center;
29
+ }
30
+ .api-key-control {
31
+ padding: 0 15px 0 0;
32
+ }
33
+
34
+ .api-key-field .button.is-danger {
35
+ padding-left: 20px;
36
+ padding-right: 20px;
37
+ }
38
+
39
+ .api-key-label {
40
+ align-self: center;
41
+ margin: 0.5em 10px 0.5em 0;
42
+ font-size: 1em;
43
+ }
44
+ .header {
45
+ padding: 0 1.5rem 0;
46
+ &.level {
47
+ margin-bottom: 0;
48
+ }
49
+ }
50
+ .account {
51
+ img {
52
+ border-top-right-radius: 4px;
53
+ border-bottom-right-radius: 4px;
54
+ }
55
+ .label {
56
+ margin-bottom: 0;
57
+ }
58
+ }
59
+
60
+ //Optimized images.
61
+ .optimized-images {
62
+
63
+ table td, table th {
64
+ vertical-align: middle;
65
+ }
66
+ }
67
+ .media-diff {
68
+ position: relative;
69
+ margin: 0 auto;
70
+ video, img {
71
+ display: block;
72
+ position: absolute;
73
+ top: 0;
74
+ left: 0;
75
+ width: 100%;
76
+ height: 100%;
77
+ }
78
+ }
79
+
80
+ .origin-wrapper {
81
+ position: absolute;
82
+ left: 0;
83
+ top: 0;
84
+ width: 100%;
85
+ height: 100%;
86
+ overflow: hidden;
87
+ z-index: 1;
88
+ transform: translateZ(0);
89
+ will-change: width;
90
+ }
91
+
92
+ .handle {
93
+ position: absolute;
94
+ top: 0;
95
+ bottom: 0;
96
+ color: rgba(255, 255, 255, 0.80);
97
+ background-color: rgba(255, 255, 255, 0.80);;
98
+ width: 2px;
99
+ cursor: ew-resize;
100
+ transform: translateX(-50%) translateZ(0);
101
+ z-index: 2;
102
+ will-change: left;
103
+ left: 200px;
104
+ }
105
+
106
+ .cursor {
107
+ position: absolute;
108
+ top: 50%;
109
+ left: 50%;
110
+ transform: translateX(-50%) translateZ(0);
111
+ .circle {
112
+ background-color: rgba(255, 255, 255, 0.80);
113
+ width: 24px;
114
+ height: 24px;
115
+ border-radius: 50%;
116
+ }
117
+ }
118
+ .no-padding-right{
119
+ padding-right:0px !important;
120
+ }
121
+ }
122
+
123
+ //Fade animation.
124
+ .fade-enter-active, .fade-leave-active {
125
+ transition: opacity .5s;
126
+ }
127
+
128
+ .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
129
+ {
130
+ opacity: 0;
131
+ }
132
+
133
+ .media_page_optimole #wpbody-content > * {
134
+ display: none !important;
135
+ }
136
+
137
+ .media_page_optimole #wpbody-content > #optimole-app {
138
+ display: block !important;
139
+ }
140
+
141
+ #optimole-app img.optml-image {
142
+ float: left;
143
+ max-width: 100px;
144
+ width: auto;
145
+ margin: auto;
146
+ }
147
+ #optimole-app img.optml-image-watermark {
148
+ width:50px;
149
+ }
150
+
151
+ .optml-ratio-feedback .emoji {
152
+ font-size: 1.5em;
153
+ }
154
+
155
+
156
+ .optml-ratio-feedback {
157
+ float: right;
158
+ padding-right: 20px;
159
+ }
160
+ .optml-image-heading {
161
+ text-align: left;
162
+ }
163
+
164
+ th.optml-image-ratio-heading {
165
+ text-align: right !important;
166
+ font-size: 150%;
167
+ }
168
+ @media screen and (max-width: 768px) {
169
+ li:not(.is-active) > a > span:not(.icon) {
170
+ visibility: hidden;
171
+ position: absolute;
172
+ }
173
+
174
+ nav.tabs li:not(.is-active) {
175
+ -webkit-box-flex: 0;
176
+ -ms-flex-positive: 0;
177
+ flex-grow: 0;
178
+ -ms-flex-negative: 1;
179
+ flex-shrink: 1;
180
+ }
181
+
182
+ .tabs .icon {
183
+ margin-left: 0.5em;
184
+ }
185
+ }
186
+
187
+ .tabs li {
188
+ transition: flex-grow 1s ease;
189
+ }
assets/js/bundle.js CHANGED
@@ -1,20297 +1,20297 @@
1
- /******/ (function(modules) { // webpackBootstrap
2
- /******/ // The module cache
3
- /******/ var installedModules = {};
4
- /******/
5
- /******/ // The require function
6
- /******/ function __webpack_require__(moduleId) {
7
- /******/
8
- /******/ // Check if module is in cache
9
- /******/ if(installedModules[moduleId]) {
10
- /******/ return installedModules[moduleId].exports;
11
- /******/ }
12
- /******/ // Create a new module (and put it into the cache)
13
- /******/ var module = installedModules[moduleId] = {
14
- /******/ i: moduleId,
15
- /******/ l: false,
16
- /******/ exports: {}
17
- /******/ };
18
- /******/
19
- /******/ // Execute the module function
20
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21
- /******/
22
- /******/ // Flag the module as loaded
23
- /******/ module.l = true;
24
- /******/
25
- /******/ // Return the exports of the module
26
- /******/ return module.exports;
27
- /******/ }
28
- /******/
29
- /******/
30
- /******/ // expose the modules object (__webpack_modules__)
31
- /******/ __webpack_require__.m = modules;
32
- /******/
33
- /******/ // expose the module cache
34
- /******/ __webpack_require__.c = installedModules;
35
- /******/
36
- /******/ // define getter function for harmony exports
37
- /******/ __webpack_require__.d = function(exports, name, getter) {
38
- /******/ if(!__webpack_require__.o(exports, name)) {
39
- /******/ Object.defineProperty(exports, name, {
40
- /******/ configurable: false,
41
- /******/ enumerable: true,
42
- /******/ get: getter
43
- /******/ });
44
- /******/ }
45
- /******/ };
46
- /******/
47
- /******/ // getDefaultExport function for compatibility with non-harmony modules
48
- /******/ __webpack_require__.n = function(module) {
49
- /******/ var getter = module && module.__esModule ?
50
- /******/ function getDefault() { return module['default']; } :
51
- /******/ function getModuleExports() { return module; };
52
- /******/ __webpack_require__.d(getter, 'a', getter);
53
- /******/ return getter;
54
- /******/ };
55
- /******/
56
- /******/ // Object.prototype.hasOwnProperty.call
57
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58
- /******/
59
- /******/ // __webpack_public_path__
60
- /******/ __webpack_require__.p = "/";
61
- /******/
62
- /******/ // Load entry module and return exports
63
- /******/ return __webpack_require__(__webpack_require__.s = 7);
64
- /******/ })
65
- /************************************************************************/
66
- /******/ ([
67
- /* 0 */
68
- /***/ (function(module, exports) {
69
-
70
- /*
71
- MIT License http://www.opensource.org/licenses/mit-license.php
72
- Author Tobias Koppers @sokra
73
- */
74
- // css base code, injected by the css-loader
75
- module.exports = function() {
76
- var list = [];
77
-
78
- // return the list of modules as css string
79
- list.toString = function toString() {
80
- var result = [];
81
- for(var i = 0; i < this.length; i++) {
82
- var item = this[i];
83
- if(item[2]) {
84
- result.push("@media " + item[2] + "{" + item[1] + "}");
85
- } else {
86
- result.push(item[1]);
87
- }
88
- }
89
- return result.join("");
90
- };
91
-
92
- // import a list of modules into the list
93
- list.i = function(modules, mediaQuery) {
94
- if(typeof modules === "string")
95
- modules = [[null, modules, ""]];
96
- var alreadyImportedModules = {};
97
- for(var i = 0; i < this.length; i++) {
98
- var id = this[i][0];
99
- if(typeof id === "number")
100
- alreadyImportedModules[id] = true;
101
- }
102
- for(i = 0; i < modules.length; i++) {
103
- var item = modules[i];
104
- // skip already imported module
105
- // this implementation is not 100% perfect for weird media query combinations
106
- // when a module is imported multiple times with different media queries.
107
- // I hope this will never occur (Hey this way we have smaller bundles)
108
- if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
109
- if(mediaQuery && !item[2]) {
110
- item[2] = mediaQuery;
111
- } else if(mediaQuery) {
112
- item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
113
- }
114
- list.push(item);
115
- }
116
- }
117
- };
118
- return list;
119
- };
120
-
121
-
122
- /***/ }),
123
- /* 1 */
124
- /***/ (function(module, exports) {
125
-
126
- /*
127
- MIT License http://www.opensource.org/licenses/mit-license.php
128
- Author Tobias Koppers @sokra
129
- */
130
- var stylesInDom = {},
131
- memoize = function(fn) {
132
- var memo;
133
- return function () {
134
- if (typeof memo === "undefined") memo = fn.apply(this, arguments);
135
- return memo;
136
- };
137
- },
138
- isOldIE = memoize(function() {
139
- return /msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase());
140
- }),
141
- getHeadElement = memoize(function () {
142
- return document.head || document.getElementsByTagName("head")[0];
143
- }),
144
- singletonElement = null,
145
- singletonCounter = 0,
146
- styleElementsInsertedAtTop = [];
147
-
148
- module.exports = function(list, options) {
149
- if(typeof DEBUG !== "undefined" && DEBUG) {
150
- if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
151
- }
152
-
153
- options = options || {};
154
- // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
155
- // tags it will allow on a page
156
- if (typeof options.singleton === "undefined") options.singleton = isOldIE();
157
-
158
- // By default, add <style> tags to the bottom of <head>.
159
- if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
160
-
161
- var styles = listToStyles(list);
162
- addStylesToDom(styles, options);
163
-
164
- return function update(newList) {
165
- var mayRemove = [];
166
- for(var i = 0; i < styles.length; i++) {
167
- var item = styles[i];
168
- var domStyle = stylesInDom[item.id];
169
- domStyle.refs--;
170
- mayRemove.push(domStyle);
171
- }
172
- if(newList) {
173
- var newStyles = listToStyles(newList);
174
- addStylesToDom(newStyles, options);
175
- }
176
- for(var i = 0; i < mayRemove.length; i++) {
177
- var domStyle = mayRemove[i];
178
- if(domStyle.refs === 0) {
179
- for(var j = 0; j < domStyle.parts.length; j++)
180
- domStyle.parts[j]();
181
- delete stylesInDom[domStyle.id];
182
- }
183
- }
184
- };
185
- }
186
-
187
- function addStylesToDom(styles, options) {
188
- for(var i = 0; i < styles.length; i++) {
189
- var item = styles[i];
190
- var domStyle = stylesInDom[item.id];
191
- if(domStyle) {
192
- domStyle.refs++;
193
- for(var j = 0; j < domStyle.parts.length; j++) {
194
- domStyle.parts[j](item.parts[j]);
195
- }
196
- for(; j < item.parts.length; j++) {
197
- domStyle.parts.push(addStyle(item.parts[j], options));
198
- }
199
- } else {
200
- var parts = [];
201
- for(var j = 0; j < item.parts.length; j++) {
202
- parts.push(addStyle(item.parts[j], options));
203
- }
204
- stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
205
- }
206
- }
207
- }
208
-
209
- function listToStyles(list) {
210
- var styles = [];
211
- var newStyles = {};
212
- for(var i = 0; i < list.length; i++) {
213
- var item = list[i];
214
- var id = item[0];
215
- var css = item[1];
216
- var media = item[2];
217
- var sourceMap = item[3];
218
- var part = {css: css, media: media, sourceMap: sourceMap};
219
- if(!newStyles[id])
220
- styles.push(newStyles[id] = {id: id, parts: [part]});
221
- else
222
- newStyles[id].parts.push(part);
223
- }
224
- return styles;
225
- }
226
-
227
- function insertStyleElement(options, styleElement) {
228
- var head = getHeadElement();
229
- var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
230
- if (options.insertAt === "top") {
231
- if(!lastStyleElementInsertedAtTop) {
232
- head.insertBefore(styleElement, head.firstChild);
233
- } else if(lastStyleElementInsertedAtTop.nextSibling) {
234
- head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
235
- } else {
236
- head.appendChild(styleElement);
237
- }
238
- styleElementsInsertedAtTop.push(styleElement);
239
- } else if (options.insertAt === "bottom") {
240
- head.appendChild(styleElement);
241
- } else {
242
- throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
243
- }
244
- }
245
-
246
- function removeStyleElement(styleElement) {
247
- styleElement.parentNode.removeChild(styleElement);
248
- var idx = styleElementsInsertedAtTop.indexOf(styleElement);
249
- if(idx >= 0) {
250
- styleElementsInsertedAtTop.splice(idx, 1);
251
- }
252
- }
253
-
254
- function createStyleElement(options) {
255
- var styleElement = document.createElement("style");
256
- styleElement.type = "text/css";
257
- insertStyleElement(options, styleElement);
258
- return styleElement;
259
- }
260
-
261
- function createLinkElement(options) {
262
- var linkElement = document.createElement("link");
263
- linkElement.rel = "stylesheet";
264
- insertStyleElement(options, linkElement);
265
- return linkElement;
266
- }
267
-
268
- function addStyle(obj, options) {
269
- var styleElement, update, remove;
270
-
271
- if (options.singleton) {
272
- var styleIndex = singletonCounter++;
273
- styleElement = singletonElement || (singletonElement = createStyleElement(options));
274
- update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
275
- remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
276
- } else if(obj.sourceMap &&
277
- typeof URL === "function" &&
278
- typeof URL.createObjectURL === "function" &&
279
- typeof URL.revokeObjectURL === "function" &&
280
- typeof Blob === "function" &&
281
- typeof btoa === "function") {
282
- styleElement = createLinkElement(options);
283
- update = updateLink.bind(null, styleElement);
284
- remove = function() {
285
- removeStyleElement(styleElement);
286
- if(styleElement.href)
287
- URL.revokeObjectURL(styleElement.href);
288
- };
289
- } else {
290
- styleElement = createStyleElement(options);
291
- update = applyToTag.bind(null, styleElement);
292
- remove = function() {
293
- removeStyleElement(styleElement);
294
- };
295
- }
296
-
297
- update(obj);
298
-
299
- return function updateStyle(newObj) {
300
- if(newObj) {
301
- if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
302
- return;
303
- update(obj = newObj);
304
- } else {
305
- remove();
306
- }
307
- };
308
- }
309
-
310
- var replaceText = (function () {
311
- var textStore = [];
312
-
313
- return function (index, replacement) {
314
- textStore[index] = replacement;
315
- return textStore.filter(Boolean).join('\n');
316
- };
317
- })();
318
-
319
- function applyToSingletonTag(styleElement, index, remove, obj) {
320
- var css = remove ? "" : obj.css;
321
-
322
- if (styleElement.styleSheet) {
323
- styleElement.styleSheet.cssText = replaceText(index, css);
324
- } else {
325
- var cssNode = document.createTextNode(css);
326
- var childNodes = styleElement.childNodes;
327
- if (childNodes[index]) styleElement.removeChild(childNodes[index]);
328
- if (childNodes.length) {
329
- styleElement.insertBefore(cssNode, childNodes[index]);
330
- } else {
331
- styleElement.appendChild(cssNode);
332
- }
333
- }
334
- }
335
-
336
- function applyToTag(styleElement, obj) {
337
- var css = obj.css;
338
- var media = obj.media;
339
-
340
- if(media) {
341
- styleElement.setAttribute("media", media)
342
- }
343
-
344
- if(styleElement.styleSheet) {
345
- styleElement.styleSheet.cssText = css;
346
- } else {
347
- while(styleElement.firstChild) {
348
- styleElement.removeChild(styleElement.firstChild);
349
- }
350
- styleElement.appendChild(document.createTextNode(css));
351
- }
352
- }
353
-
354
- function updateLink(linkElement, obj) {
355
- var css = obj.css;
356
- var sourceMap = obj.sourceMap;
357
-
358
- if(sourceMap) {
359
- // http://stackoverflow.com/a/26603875
360
- css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
361
- }
362
-
363
- var blob = new Blob([css], { type: "text/css" });
364
-
365
- var oldSrc = linkElement.href;
366
-
367
- linkElement.href = URL.createObjectURL(blob);
368
-
369
- if(oldSrc)
370
- URL.revokeObjectURL(oldSrc);
371
- }
372
-
373
-
374
- /***/ }),
375
- /* 2 */
376
- /***/ (function(module, exports) {
377
-
378
- var g;
379
-
380
- // This works in non-strict mode
381
- g = (function() {
382
- return this;
383
- })();
384
-
385
- try {
386
- // This works if eval is allowed (see CSP)
387
- g = g || Function("return this")() || (1,eval)("this");
388
- } catch(e) {
389
- // This works if the window reference is available
390
- if(typeof window === "object")
391
- g = window;
392
- }
393
-
394
- // g can still be undefined, but nothing to do about it...
395
- // We return undefined, instead of nothing here, so it's
396
- // easier to handle this case. if(!global) { ...}
397
-
398
- module.exports = g;
399
-
400
-
401
- /***/ }),
402
- /* 3 */
403
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
404
-
405
- "use strict";
406
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
407
- /* WEBPACK VAR INJECTION */(function(process, global, setImmediate) {/*!
408
- * Vue.js v2.5.21
409
- * (c) 2014-2018 Evan You
410
- * Released under the MIT License.
411
- */
412
- /* */
413
-
414
- var emptyObject = Object.freeze({});
415
-
416
- // These helpers produce better VM code in JS engines due to their
417
- // explicitness and function inlining.
418
- function isUndef (v) {
419
- return v === undefined || v === null
420
- }
421
-
422
- function isDef (v) {
423
- return v !== undefined && v !== null
424
- }
425
-
426
- function isTrue (v) {
427
- return v === true
428
- }
429
-
430
- function isFalse (v) {
431
- return v === false
432
- }
433
-
434
- /**
435
- * Check if value is primitive.
436
- */
437
- function isPrimitive (value) {
438
- return (
439
- typeof value === 'string' ||
440
- typeof value === 'number' ||
441
- // $flow-disable-line
442
- typeof value === 'symbol' ||
443
- typeof value === 'boolean'
444
- )
445
- }
446
-
447
- /**
448
- * Quick object check - this is primarily used to tell
449
- * Objects from primitive values when we know the value
450
- * is a JSON-compliant type.
451
- */
452
- function isObject (obj) {
453
- return obj !== null && typeof obj === 'object'
454
- }
455
-
456
- /**
457
- * Get the raw type string of a value, e.g., [object Object].
458
- */
459
- var _toString = Object.prototype.toString;
460
-
461
- function toRawType (value) {
462
- return _toString.call(value).slice(8, -1)
463
- }
464
-
465
- /**
466
- * Strict object type check. Only returns true
467
- * for plain JavaScript objects.
468
- */
469
- function isPlainObject (obj) {
470
- return _toString.call(obj) === '[object Object]'
471
- }
472
-
473
- function isRegExp (v) {
474
- return _toString.call(v) === '[object RegExp]'
475
- }
476
-
477
- /**
478
- * Check if val is a valid array index.
479
- */
480
- function isValidArrayIndex (val) {
481
- var n = parseFloat(String(val));
482
- return n >= 0 && Math.floor(n) === n && isFinite(val)
483
- }
484
-
485
- /**
486
- * Convert a value to a string that is actually rendered.
487
- */
488
- function toString (val) {
489
- return val == null
490
- ? ''
491
- : typeof val === 'object'
492
- ? JSON.stringify(val, null, 2)
493
- : String(val)
494
- }
495
-
496
- /**
497
- * Convert an input value to a number for persistence.
498
- * If the conversion fails, return original string.
499
- */
500
- function toNumber (val) {
501
- var n = parseFloat(val);
502
- return isNaN(n) ? val : n
503
- }
504
-
505
- /**
506
- * Make a map and return a function for checking if a key
507
- * is in that map.
508
- */
509
- function makeMap (
510
- str,
511
- expectsLowerCase
512
- ) {
513
- var map = Object.create(null);
514
- var list = str.split(',');
515
- for (var i = 0; i < list.length; i++) {
516
- map[list[i]] = true;
517
- }
518
- return expectsLowerCase
519
- ? function (val) { return map[val.toLowerCase()]; }
520
- : function (val) { return map[val]; }
521
- }
522
-
523
- /**
524
- * Check if a tag is a built-in tag.
525
- */
526
- var isBuiltInTag = makeMap('slot,component', true);
527
-
528
- /**
529
- * Check if an attribute is a reserved attribute.
530
- */
531
- var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');
532
-
533
- /**
534
- * Remove an item from an array.
535
- */
536
- function remove (arr, item) {
537
- if (arr.length) {
538
- var index = arr.indexOf(item);
539
- if (index > -1) {
540
- return arr.splice(index, 1)
541
- }
542
- }
543
- }
544
-
545
- /**
546
- * Check whether an object has the property.
547
- */
548
- var hasOwnProperty = Object.prototype.hasOwnProperty;
549
- function hasOwn (obj, key) {
550
- return hasOwnProperty.call(obj, key)
551
- }
552
-
553
- /**
554
- * Create a cached version of a pure function.
555
- */
556
- function cached (fn) {
557
- var cache = Object.create(null);
558
- return (function cachedFn (str) {
559
- var hit = cache[str];
560
- return hit || (cache[str] = fn(str))
561
- })
562
- }
563
-
564
- /**
565
- * Camelize a hyphen-delimited string.
566
- */
567
- var camelizeRE = /-(\w)/g;
568
- var camelize = cached(function (str) {
569
- return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
570
- });
571
-
572
- /**
573
- * Capitalize a string.
574
- */
575
- var capitalize = cached(function (str) {
576
- return str.charAt(0).toUpperCase() + str.slice(1)
577
- });
578
-
579
- /**
580
- * Hyphenate a camelCase string.
581
- */
582
- var hyphenateRE = /\B([A-Z])/g;
583
- var hyphenate = cached(function (str) {
584
- return str.replace(hyphenateRE, '-$1').toLowerCase()
585
- });
586
-
587
- /**
588
- * Simple bind polyfill for environments that do not support it,
589
- * e.g., PhantomJS 1.x. Technically, we don't need this anymore
590
- * since native bind is now performant enough in most browsers.
591
- * But removing it would mean breaking code that was able to run in
592
- * PhantomJS 1.x, so this must be kept for backward compatibility.
593
- */
594
-
595
- /* istanbul ignore next */
596
- function polyfillBind (fn, ctx) {
597
- function boundFn (a) {
598
- var l = arguments.length;
599
- return l
600
- ? l > 1
601
- ? fn.apply(ctx, arguments)
602
- : fn.call(ctx, a)
603
- : fn.call(ctx)
604
- }
605
-
606
- boundFn._length = fn.length;
607
- return boundFn
608
- }
609
-
610
- function nativeBind (fn, ctx) {
611
- return fn.bind(ctx)
612
- }
613
-
614
- var bind = Function.prototype.bind
615
- ? nativeBind
616
- : polyfillBind;
617
-
618
- /**
619
- * Convert an Array-like object to a real Array.
620
- */
621
- function toArray (list, start) {
622
- start = start || 0;
623
- var i = list.length - start;
624
- var ret = new Array(i);
625
- while (i--) {
626
- ret[i] = list[i + start];
627
- }
628
- return ret
629
- }
630
-
631
- /**
632
- * Mix properties into target object.
633
- */
634
- function extend (to, _from) {
635
- for (var key in _from) {
636
- to[key] = _from[key];
637
- }
638
- return to
639
- }
640
-
641
- /**
642
- * Merge an Array of Objects into a single Object.
643
- */
644
- function toObject (arr) {
645
- var res = {};
646
- for (var i = 0; i < arr.length; i++) {
647
- if (arr[i]) {
648
- extend(res, arr[i]);
649
- }
650
- }
651
- return res
652
- }
653
-
654
- /* eslint-disable no-unused-vars */
655
-
656
- /**
657
- * Perform no operation.
658
- * Stubbing args to make Flow happy without leaving useless transpiled code
659
- * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/).
660
- */
661
- function noop (a, b, c) {}
662
-
663
- /**
664
- * Always return false.
665
- */
666
- var no = function (a, b, c) { return false; };
667
-
668
- /* eslint-enable no-unused-vars */
669
-
670
- /**
671
- * Return the same value.
672
- */
673
- var identity = function (_) { return _; };
674
-
675
- /**
676
- * Generate a string containing static keys from compiler modules.
677
- */
678
- function genStaticKeys (modules) {
679
- return modules.reduce(function (keys, m) {
680
- return keys.concat(m.staticKeys || [])
681
- }, []).join(',')
682
- }
683
-
684
- /**
685
- * Check if two values are loosely equal - that is,
686
- * if they are plain objects, do they have the same shape?
687
- */
688
- function looseEqual (a, b) {
689
- if (a === b) { return true }
690
- var isObjectA = isObject(a);
691
- var isObjectB = isObject(b);
692
- if (isObjectA && isObjectB) {
693
- try {
694
- var isArrayA = Array.isArray(a);
695
- var isArrayB = Array.isArray(b);
696
- if (isArrayA && isArrayB) {
697
- return a.length === b.length && a.every(function (e, i) {
698
- return looseEqual(e, b[i])
699
- })
700
- } else if (a instanceof Date && b instanceof Date) {
701
- return a.getTime() === b.getTime()
702
- } else if (!isArrayA && !isArrayB) {
703
- var keysA = Object.keys(a);
704
- var keysB = Object.keys(b);
705
- return keysA.length === keysB.length && keysA.every(function (key) {
706
- return looseEqual(a[key], b[key])
707
- })
708
- } else {
709
- /* istanbul ignore next */
710
- return false
711
- }
712
- } catch (e) {
713
- /* istanbul ignore next */
714
- return false
715
- }
716
- } else if (!isObjectA && !isObjectB) {
717
- return String(a) === String(b)
718
- } else {
719
- return false
720
- }
721
- }
722
-
723
- /**
724
- * Return the first index at which a loosely equal value can be
725
- * found in the array (if value is a plain object, the array must
726
- * contain an object of the same shape), or -1 if it is not present.
727
- */
728
- function looseIndexOf (arr, val) {
729
- for (var i = 0; i < arr.length; i++) {
730
- if (looseEqual(arr[i], val)) { return i }
731
- }
732
- return -1
733
- }
734
-
735
- /**
736
- * Ensure a function is called only once.
737
- */
738
- function once (fn) {
739
- var called = false;
740
- return function () {
741
- if (!called) {
742
- called = true;
743
- fn.apply(this, arguments);
744
- }
745
- }
746
- }
747
-
748
- var SSR_ATTR = 'data-server-rendered';
749
-
750
- var ASSET_TYPES = [
751
- 'component',
752
- 'directive',
753
- 'filter'
754
- ];
755
-
756
- var LIFECYCLE_HOOKS = [
757
- 'beforeCreate',
758
- 'created',
759
- 'beforeMount',
760
- 'mounted',
761
- 'beforeUpdate',
762
- 'updated',
763
- 'beforeDestroy',
764
- 'destroyed',
765
- 'activated',
766
- 'deactivated',
767
- 'errorCaptured'
768
- ];
769
-
770
- /* */
771
-
772
-
773
-
774
- var config = ({
775
- /**
776
- * Option merge strategies (used in core/util/options)
777
- */
778
- // $flow-disable-line
779
- optionMergeStrategies: Object.create(null),
780
-
781
- /**
782
- * Whether to suppress warnings.
783
- */
784
- silent: false,
785
-
786
- /**
787
- * Show production mode tip message on boot?
788
- */
789
- productionTip: process.env.NODE_ENV !== 'production',
790
-
791
- /**
792
- * Whether to enable devtools
793
- */
794
- devtools: process.env.NODE_ENV !== 'production',
795
-
796
- /**
797
- * Whether to record perf
798
- */
799
- performance: false,
800
-
801
- /**
802
- * Error handler for watcher errors
803
- */
804
- errorHandler: null,
805
-
806
- /**
807
- * Warn handler for watcher warns
808
- */
809
- warnHandler: null,
810
-
811
- /**
812
- * Ignore certain custom elements
813
- */
814
- ignoredElements: [],
815
-
816
- /**
817
- * Custom user key aliases for v-on
818
- */
819
- // $flow-disable-line
820
- keyCodes: Object.create(null),
821
-
822
- /**
823
- * Check if a tag is reserved so that it cannot be registered as a
824
- * component. This is platform-dependent and may be overwritten.
825
- */
826
- isReservedTag: no,
827
-
828
- /**
829
- * Check if an attribute is reserved so that it cannot be used as a component
830
- * prop. This is platform-dependent and may be overwritten.
831
- */
832
- isReservedAttr: no,
833
-
834
- /**
835
- * Check if a tag is an unknown element.
836
- * Platform-dependent.
837
- */
838
- isUnknownElement: no,
839
-
840
- /**
841
- * Get the namespace of an element
842
- */
843
- getTagNamespace: noop,
844
-
845
- /**
846
- * Parse the real tag name for the specific platform.
847
- */
848
- parsePlatformTagName: identity,
849
-
850
- /**
851
- * Check if an attribute must be bound using property, e.g. value
852
- * Platform-dependent.
853
- */
854
- mustUseProp: no,
855
-
856
- /**
857
- * Perform updates asynchronously. Intended to be used by Vue Test Utils
858
- * This will significantly reduce performance if set to false.
859
- */
860
- async: true,
861
-
862
- /**
863
- * Exposed for legacy reasons
864
- */
865
- _lifecycleHooks: LIFECYCLE_HOOKS
866
- });
867
-
868
- /* */
869
-
870
- /**
871
- * Check if a string starts with $ or _
872
- */
873
- function isReserved (str) {
874
- var c = (str + '').charCodeAt(0);
875
- return c === 0x24 || c === 0x5F
876
- }
877
-
878
- /**
879
- * Define a property.
880
- */
881
- function def (obj, key, val, enumerable) {
882
- Object.defineProperty(obj, key, {
883
- value: val,
884
- enumerable: !!enumerable,
885
- writable: true,
886
- configurable: true
887
- });
888
- }
889
-
890
- /**
891
- * Parse simple path.
892
- */
893
- var bailRE = /[^\w.$]/;
894
- function parsePath (path) {
895
- if (bailRE.test(path)) {
896
- return
897
- }
898
- var segments = path.split('.');
899
- return function (obj) {
900
- for (var i = 0; i < segments.length; i++) {
901
- if (!obj) { return }
902
- obj = obj[segments[i]];
903
- }
904
- return obj
905
- }
906
- }
907
-
908
- /* */
909
-
910
- // can we use __proto__?
911
- var hasProto = '__proto__' in {};
912
-
913
- // Browser environment sniffing
914
- var inBrowser = typeof window !== 'undefined';
915
- var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
916
- var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
917
- var UA = inBrowser && window.navigator.userAgent.toLowerCase();
918
- var isIE = UA && /msie|trident/.test(UA);
919
- var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
920
- var isEdge = UA && UA.indexOf('edge/') > 0;
921
- var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
922
- var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
923
- var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
924
-
925
- // Firefox has a "watch" function on Object.prototype...
926
- var nativeWatch = ({}).watch;
927
-
928
- var supportsPassive = false;
929
- if (inBrowser) {
930
- try {
931
- var opts = {};
932
- Object.defineProperty(opts, 'passive', ({
933
- get: function get () {
934
- /* istanbul ignore next */
935
- supportsPassive = true;
936
- }
937
- })); // https://github.com/facebook/flow/issues/285
938
- window.addEventListener('test-passive', null, opts);
939
- } catch (e) {}
940
- }
941
-
942
- // this needs to be lazy-evaled because vue may be required before
943
- // vue-server-renderer can set VUE_ENV
944
- var _isServer;
945
- var isServerRendering = function () {
946
- if (_isServer === undefined) {
947
- /* istanbul ignore if */
948
- if (!inBrowser && !inWeex && typeof global !== 'undefined') {
949
- // detect presence of vue-server-renderer and avoid
950
- // Webpack shimming the process
951
- _isServer = global['process'] && global['process'].env.VUE_ENV === 'server';
952
- } else {
953
- _isServer = false;
954
- }
955
- }
956
- return _isServer
957
- };
958
-
959
- // detect devtools
960
- var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
961
-
962
- /* istanbul ignore next */
963
- function isNative (Ctor) {
964
- return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
965
- }
966
-
967
- var hasSymbol =
968
- typeof Symbol !== 'undefined' && isNative(Symbol) &&
969
- typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
970
-
971
- var _Set;
972
- /* istanbul ignore if */ // $flow-disable-line
973
- if (typeof Set !== 'undefined' && isNative(Set)) {
974
- // use native Set when available.
975
- _Set = Set;
976
- } else {
977
- // a non-standard Set polyfill that only works with primitive keys.
978
- _Set = /*@__PURE__*/(function () {
979
- function Set () {
980
- this.set = Object.create(null);
981
- }
982
- Set.prototype.has = function has (key) {
983
- return this.set[key] === true
984
- };
985
- Set.prototype.add = function add (key) {
986
- this.set[key] = true;
987
- };
988
- Set.prototype.clear = function clear () {
989
- this.set = Object.create(null);
990
- };
991
-
992
- return Set;
993
- }());
994
- }
995
-
996
- /* */
997
-
998
- var warn = noop;
999
- var tip = noop;
1000
- var generateComponentTrace = (noop); // work around flow check
1001
- var formatComponentName = (noop);
1002
-
1003
- if (process.env.NODE_ENV !== 'production') {
1004
- var hasConsole = typeof console !== 'undefined';
1005
- var classifyRE = /(?:^|[-_])(\w)/g;
1006
- var classify = function (str) { return str
1007
- .replace(classifyRE, function (c) { return c.toUpperCase(); })
1008
- .replace(/[-_]/g, ''); };
1009
-
1010
- warn = function (msg, vm) {
1011
- var trace = vm ? generateComponentTrace(vm) : '';
1012
-
1013
- if (config.warnHandler) {
1014
- config.warnHandler.call(null, msg, vm, trace);
1015
- } else if (hasConsole && (!config.silent)) {
1016
- console.error(("[Vue warn]: " + msg + trace));
1017
- }
1018
- };
1019
-
1020
- tip = function (msg, vm) {
1021
- if (hasConsole && (!config.silent)) {
1022
- console.warn("[Vue tip]: " + msg + (
1023
- vm ? generateComponentTrace(vm) : ''
1024
- ));
1025
- }
1026
- };
1027
-
1028
- formatComponentName = function (vm, includeFile) {
1029
- if (vm.$root === vm) {
1030
- return '<Root>'
1031
- }
1032
- var options = typeof vm === 'function' && vm.cid != null
1033
- ? vm.options
1034
- : vm._isVue
1035
- ? vm.$options || vm.constructor.options
1036
- : vm || {};
1037
- var name = options.name || options._componentTag;
1038
- var file = options.__file;
1039
- if (!name && file) {
1040
- var match = file.match(/([^/\\]+)\.vue#x2F;);
1041
- name = match && match[1];
1042
- }
1043
-
1044
- return (
1045
- (name ? ("<" + (classify(name)) + ">") : "<Anonymous>") +
1046
- (file && includeFile !== false ? (" at " + file) : '')
1047
- )
1048
- };
1049
-
1050
- var repeat = function (str, n) {
1051
- var res = '';
1052
- while (n) {
1053
- if (n % 2 === 1) { res += str; }
1054
- if (n > 1) { str += str; }
1055
- n >>= 1;
1056
- }
1057
- return res
1058
- };
1059
-
1060
- generateComponentTrace = function (vm) {
1061
- if (vm._isVue && vm.$parent) {
1062
- var tree = [];
1063
- var currentRecursiveSequence = 0;
1064
- while (vm) {
1065
- if (tree.length > 0) {
1066
- var last = tree[tree.length - 1];
1067
- if (last.constructor === vm.constructor) {
1068
- currentRecursiveSequence++;
1069
- vm = vm.$parent;
1070
- continue
1071
- } else if (currentRecursiveSequence > 0) {
1072
- tree[tree.length - 1] = [last, currentRecursiveSequence];
1073
- currentRecursiveSequence = 0;
1074
- }
1075
- }
1076
- tree.push(vm);
1077
- vm = vm.$parent;
1078
- }
1079
- return '\n\nfound in\n\n' + tree
1080
- .map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)
1081
- ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)")
1082
- : formatComponentName(vm))); })
1083
- .join('\n')
1084
- } else {
1085
- return ("\n\n(found in " + (formatComponentName(vm)) + ")")
1086
- }
1087
- };
1088
- }
1089
-
1090
- /* */
1091
-
1092
- var uid = 0;
1093
-
1094
- /**
1095
- * A dep is an observable that can have multiple
1096
- * directives subscribing to it.
1097
- */
1098
- var Dep = function Dep () {
1099
- this.id = uid++;
1100
- this.subs = [];
1101
- };
1102
-
1103
- Dep.prototype.addSub = function addSub (sub) {
1104
- this.subs.push(sub);
1105
- };
1106
-
1107
- Dep.prototype.removeSub = function removeSub (sub) {
1108
- remove(this.subs, sub);
1109
- };
1110
-
1111
- Dep.prototype.depend = function depend () {
1112
- if (Dep.target) {
1113
- Dep.target.addDep(this);
1114
- }
1115
- };
1116
-
1117
- Dep.prototype.notify = function notify () {
1118
- // stabilize the subscriber list first
1119
- var subs = this.subs.slice();
1120
- if (process.env.NODE_ENV !== 'production' && !config.async) {
1121
- // subs aren't sorted in scheduler if not running async
1122
- // we need to sort them now to make sure they fire in correct
1123
- // order
1124
- subs.sort(function (a, b) { return a.id - b.id; });
1125
- }
1126
- for (var i = 0, l = subs.length; i < l; i++) {
1127
- subs[i].update();
1128
- }
1129
- };
1130
-
1131
- // the current target watcher being evaluated.
1132
- // this is globally unique because there could be only one
1133
- // watcher being evaluated at any time.
1134
- Dep.target = null;
1135
- var targetStack = [];
1136
-
1137
- function pushTarget (target) {
1138
- targetStack.push(target);
1139
- Dep.target = target;
1140
- }
1141
-
1142
- function popTarget () {
1143
- targetStack.pop();
1144
- Dep.target = targetStack[targetStack.length - 1];
1145
- }
1146
-
1147
- /* */
1148
-
1149
- var VNode = function VNode (
1150
- tag,
1151
- data,
1152
- children,
1153
- text,
1154
- elm,
1155
- context,
1156
- componentOptions,
1157
- asyncFactory
1158
- ) {
1159
- this.tag = tag;
1160
- this.data = data;
1161
- this.children = children;
1162
- this.text = text;
1163
- this.elm = elm;
1164
- this.ns = undefined;
1165
- this.context = context;
1166
- this.fnContext = undefined;
1167
- this.fnOptions = undefined;
1168
- this.fnScopeId = undefined;
1169
- this.key = data && data.key;
1170
- this.componentOptions = componentOptions;
1171
- this.componentInstance = undefined;
1172
- this.parent = undefined;
1173
- this.raw = false;
1174
- this.isStatic = false;
1175
- this.isRootInsert = true;
1176
- this.isComment = false;
1177
- this.isCloned = false;
1178
- this.isOnce = false;
1179
- this.asyncFactory = asyncFactory;
1180
- this.asyncMeta = undefined;
1181
- this.isAsyncPlaceholder = false;
1182
- };
1183
-
1184
- var prototypeAccessors = { child: { configurable: true } };
1185
-
1186
- // DEPRECATED: alias for componentInstance for backwards compat.
1187
- /* istanbul ignore next */
1188
- prototypeAccessors.child.get = function () {
1189
- return this.componentInstance
1190
- };
1191
-
1192
- Object.defineProperties( VNode.prototype, prototypeAccessors );
1193
-
1194
- var createEmptyVNode = function (text) {
1195
- if ( text === void 0 ) text = '';
1196
-
1197
- var node = new VNode();
1198
- node.text = text;
1199
- node.isComment = true;
1200
- return node
1201
- };
1202
-
1203
- function createTextVNode (val) {
1204
- return new VNode(undefined, undefined, undefined, String(val))
1205
- }
1206
-
1207
- // optimized shallow clone
1208
- // used for static nodes and slot nodes because they may be reused across
1209
- // multiple renders, cloning them avoids errors when DOM manipulations rely
1210
- // on their elm reference.
1211
- function cloneVNode (vnode) {
1212
- var cloned = new VNode(
1213
- vnode.tag,
1214
- vnode.data,
1215
- // #7975
1216
- // clone children array to avoid mutating original in case of cloning
1217
- // a child.
1218
- vnode.children && vnode.children.slice(),
1219
- vnode.text,
1220
- vnode.elm,
1221
- vnode.context,
1222
- vnode.componentOptions,
1223
- vnode.asyncFactory
1224
- );
1225
- cloned.ns = vnode.ns;
1226
- cloned.isStatic = vnode.isStatic;
1227
- cloned.key = vnode.key;
1228
- cloned.isComment = vnode.isComment;
1229
- cloned.fnContext = vnode.fnContext;
1230
- cloned.fnOptions = vnode.fnOptions;
1231
- cloned.fnScopeId = vnode.fnScopeId;
1232
- cloned.asyncMeta = vnode.asyncMeta;
1233
- cloned.isCloned = true;
1234
- return cloned
1235
- }
1236
-
1237
- /*
1238
- * not type checking this file because flow doesn't play well with
1239
- * dynamically accessing methods on Array prototype
1240
- */
1241
-
1242
- var arrayProto = Array.prototype;
1243
- var arrayMethods = Object.create(arrayProto);
1244
-
1245
- var methodsToPatch = [
1246
- 'push',
1247
- 'pop',
1248
- 'shift',
1249
- 'unshift',
1250
- 'splice',
1251
- 'sort',
1252
- 'reverse'
1253
- ];
1254
-
1255
- /**
1256
- * Intercept mutating methods and emit events
1257
- */
1258
- methodsToPatch.forEach(function (method) {
1259
- // cache original method
1260
- var original = arrayProto[method];
1261
- def(arrayMethods, method, function mutator () {
1262
- var args = [], len = arguments.length;
1263
- while ( len-- ) args[ len ] = arguments[ len ];
1264
-
1265
- var result = original.apply(this, args);
1266
- var ob = this.__ob__;
1267
- var inserted;
1268
- switch (method) {
1269
- case 'push':
1270
- case 'unshift':
1271
- inserted = args;
1272
- break
1273
- case 'splice':
1274
- inserted = args.slice(2);
1275
- break
1276
- }
1277
- if (inserted) { ob.observeArray(inserted); }
1278
- // notify change
1279
- ob.dep.notify();
1280
- return result
1281
- });
1282
- });
1283
-
1284
- /* */
1285
-
1286
- var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
1287
-
1288
- /**
1289
- * In some cases we may want to disable observation inside a component's
1290
- * update computation.
1291
- */
1292
- var shouldObserve = true;
1293
-
1294
- function toggleObserving (value) {
1295
- shouldObserve = value;
1296
- }
1297
-
1298
- /**
1299
- * Observer class that is attached to each observed
1300
- * object. Once attached, the observer converts the target
1301
- * object's property keys into getter/setters that
1302
- * collect dependencies and dispatch updates.
1303
- */
1304
- var Observer = function Observer (value) {
1305
- this.value = value;
1306
- this.dep = new Dep();
1307
- this.vmCount = 0;
1308
- def(value, '__ob__', this);
1309
- if (Array.isArray(value)) {
1310
- if (hasProto) {
1311
- protoAugment(value, arrayMethods);
1312
- } else {
1313
- copyAugment(value, arrayMethods, arrayKeys);
1314
- }
1315
- this.observeArray(value);
1316
- } else {
1317
- this.walk(value);
1318
- }
1319
- };
1320
-
1321
- /**
1322
- * Walk through all properties and convert them into
1323
- * getter/setters. This method should only be called when
1324
- * value type is Object.
1325
- */
1326
- Observer.prototype.walk = function walk (obj) {
1327
- var keys = Object.keys(obj);
1328
- for (var i = 0; i < keys.length; i++) {
1329
- defineReactive$1(obj, keys[i]);
1330
- }
1331
- };
1332
-
1333
- /**
1334
- * Observe a list of Array items.
1335
- */
1336
- Observer.prototype.observeArray = function observeArray (items) {
1337
- for (var i = 0, l = items.length; i < l; i++) {
1338
- observe(items[i]);
1339
- }
1340
- };
1341
-
1342
- // helpers
1343
-
1344
- /**
1345
- * Augment a target Object or Array by intercepting
1346
- * the prototype chain using __proto__
1347
- */
1348
- function protoAugment (target, src) {
1349
- /* eslint-disable no-proto */
1350
- target.__proto__ = src;
1351
- /* eslint-enable no-proto */
1352
- }
1353
-
1354
- /**
1355
- * Augment a target Object or Array by defining
1356
- * hidden properties.
1357
- */
1358
- /* istanbul ignore next */
1359
- function copyAugment (target, src, keys) {
1360
- for (var i = 0, l = keys.length; i < l; i++) {
1361
- var key = keys[i];
1362
- def(target, key, src[key]);
1363
- }
1364
- }
1365
-
1366
- /**
1367
- * Attempt to create an observer instance for a value,
1368
- * returns the new observer if successfully observed,
1369
- * or the existing observer if the value already has one.
1370
- */
1371
- function observe (value, asRootData) {
1372
- if (!isObject(value) || value instanceof VNode) {
1373
- return
1374
- }
1375
- var ob;
1376
- if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
1377
- ob = value.__ob__;
1378
- } else if (
1379
- shouldObserve &&
1380
- !isServerRendering() &&
1381
- (Array.isArray(value) || isPlainObject(value)) &&
1382
- Object.isExtensible(value) &&
1383
- !value._isVue
1384
- ) {
1385
- ob = new Observer(value);
1386
- }
1387
- if (asRootData && ob) {
1388
- ob.vmCount++;
1389
- }
1390
- return ob
1391
- }
1392
-
1393
- /**
1394
- * Define a reactive property on an Object.
1395
- */
1396
- function defineReactive$1 (
1397
- obj,
1398
- key,
1399
- val,
1400
- customSetter,
1401
- shallow
1402
- ) {
1403
- var dep = new Dep();
1404
-
1405
- var property = Object.getOwnPropertyDescriptor(obj, key);
1406
- if (property && property.configurable === false) {
1407
- return
1408
- }
1409
-
1410
- // cater for pre-defined getter/setters
1411
- var getter = property && property.get;
1412
- var setter = property && property.set;
1413
- if ((!getter || setter) && arguments.length === 2) {
1414
- val = obj[key];
1415
- }
1416
-
1417
- var childOb = !shallow && observe(val);
1418
- Object.defineProperty(obj, key, {
1419
- enumerable: true,
1420
- configurable: true,
1421
- get: function reactiveGetter () {
1422
- var value = getter ? getter.call(obj) : val;
1423
- if (Dep.target) {
1424
- dep.depend();
1425
- if (childOb) {
1426
- childOb.dep.depend();
1427
- if (Array.isArray(value)) {
1428
- dependArray(value);
1429
- }
1430
- }
1431
- }
1432
- return value
1433
- },
1434
- set: function reactiveSetter (newVal) {
1435
- var value = getter ? getter.call(obj) : val;
1436
- /* eslint-disable no-self-compare */
1437
- if (newVal === value || (newVal !== newVal && value !== value)) {
1438
- return
1439
- }
1440
- /* eslint-enable no-self-compare */
1441
- if (process.env.NODE_ENV !== 'production' && customSetter) {
1442
- customSetter();
1443
- }
1444
- // #7981: for accessor properties without setter
1445
- if (getter && !setter) { return }
1446
- if (setter) {
1447
- setter.call(obj, newVal);
1448
- } else {
1449
- val = newVal;
1450
- }
1451
- childOb = !shallow && observe(newVal);
1452
- dep.notify();
1453
- }
1454
- });
1455
- }
1456
-
1457
- /**
1458
- * Set a property on an object. Adds the new property and
1459
- * triggers change notification if the property doesn't
1460
- * already exist.
1461
- */
1462
- function set (target, key, val) {
1463
- if (process.env.NODE_ENV !== 'production' &&
1464
- (isUndef(target) || isPrimitive(target))
1465
- ) {
1466
- warn(("Cannot set reactive property on undefined, null, or primitive value: " + ((target))));
1467
- }
1468
- if (Array.isArray(target) && isValidArrayIndex(key)) {
1469
- target.length = Math.max(target.length, key);
1470
- target.splice(key, 1, val);
1471
- return val
1472
- }
1473
- if (key in target && !(key in Object.prototype)) {
1474
- target[key] = val;
1475
- return val
1476
- }
1477
- var ob = (target).__ob__;
1478
- if (target._isVue || (ob && ob.vmCount)) {
1479
- process.env.NODE_ENV !== 'production' && warn(
1480
- 'Avoid adding reactive properties to a Vue instance or its root $data ' +
1481
- 'at runtime - declare it upfront in the data option.'
1482
- );
1483
- return val
1484
- }
1485
- if (!ob) {
1486
- target[key] = val;
1487
- return val
1488
- }
1489
- defineReactive$1(ob.value, key, val);
1490
- ob.dep.notify();
1491
- return val
1492
- }
1493
-
1494
- /**
1495
- * Delete a property and trigger change if necessary.
1496
- */
1497
- function del (target, key) {
1498
- if (process.env.NODE_ENV !== 'production' &&
1499
- (isUndef(target) || isPrimitive(target))
1500
- ) {
1501
- warn(("Cannot delete reactive property on undefined, null, or primitive value: " + ((target))));
1502
- }
1503
- if (Array.isArray(target) && isValidArrayIndex(key)) {
1504
- target.splice(key, 1);
1505
- return
1506
- }
1507
- var ob = (target).__ob__;
1508
- if (target._isVue || (ob && ob.vmCount)) {
1509
- process.env.NODE_ENV !== 'production' && warn(
1510
- 'Avoid deleting properties on a Vue instance or its root $data ' +
1511
- '- just set it to null.'
1512
- );
1513
- return
1514
- }
1515
- if (!hasOwn(target, key)) {
1516
- return
1517
- }
1518
- delete target[key];
1519
- if (!ob) {
1520
- return
1521
- }
1522
- ob.dep.notify();
1523
- }
1524
-
1525
- /**
1526
- * Collect dependencies on array elements when the array is touched, since
1527
- * we cannot intercept array element access like property getters.
1528
- */
1529
- function dependArray (value) {
1530
- for (var e = (void 0), i = 0, l = value.length; i < l; i++) {
1531
- e = value[i];
1532
- e && e.__ob__ && e.__ob__.dep.depend();
1533
- if (Array.isArray(e)) {
1534
- dependArray(e);
1535
- }
1536
- }
1537
- }
1538
-
1539
- /* */
1540
-
1541
- /**
1542
- * Option overwriting strategies are functions that handle
1543
- * how to merge a parent option value and a child option
1544
- * value into the final value.
1545
- */
1546
- var strats = config.optionMergeStrategies;
1547
-
1548
- /**
1549
- * Options with restrictions
1550
- */
1551
- if (process.env.NODE_ENV !== 'production') {
1552
- strats.el = strats.propsData = function (parent, child, vm, key) {
1553
- if (!vm) {
1554
- warn(
1555
- "option \"" + key + "\" can only be used during instance " +
1556
- 'creation with the `new` keyword.'
1557
- );
1558
- }
1559
- return defaultStrat(parent, child)
1560
- };
1561
- }
1562
-
1563
- /**
1564
- * Helper that recursively merges two data objects together.
1565
- */
1566
- function mergeData (to, from) {
1567
- if (!from) { return to }
1568
- var key, toVal, fromVal;
1569
- var keys = Object.keys(from);
1570
- for (var i = 0; i < keys.length; i++) {
1571
- key = keys[i];
1572
- toVal = to[key];
1573
- fromVal = from[key];
1574
- if (!hasOwn(to, key)) {
1575
- set(to, key, fromVal);
1576
- } else if (
1577
- toVal !== fromVal &&
1578
- isPlainObject(toVal) &&
1579
- isPlainObject(fromVal)
1580
- ) {
1581
- mergeData(toVal, fromVal);
1582
- }
1583
- }
1584
- return to
1585
- }
1586
-
1587
- /**
1588
- * Data
1589
- */
1590
- function mergeDataOrFn (
1591
- parentVal,
1592
- childVal,
1593
- vm
1594
- ) {
1595
- if (!vm) {
1596
- // in a Vue.extend merge, both should be functions
1597
- if (!childVal) {
1598
- return parentVal
1599
- }
1600
- if (!parentVal) {
1601
- return childVal
1602
- }
1603
- // when parentVal & childVal are both present,
1604
- // we need to return a function that returns the
1605
- // merged result of both functions... no need to
1606
- // check if parentVal is a function here because
1607
- // it has to be a function to pass previous merges.
1608
- return function mergedDataFn () {
1609
- return mergeData(
1610
- typeof childVal === 'function' ? childVal.call(this, this) : childVal,
1611
- typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
1612
- )
1613
- }
1614
- } else {
1615
- return function mergedInstanceDataFn () {
1616
- // instance merge
1617
- var instanceData = typeof childVal === 'function'
1618
- ? childVal.call(vm, vm)
1619
- : childVal;
1620
- var defaultData = typeof parentVal === 'function'
1621
- ? parentVal.call(vm, vm)
1622
- : parentVal;
1623
- if (instanceData) {
1624
- return mergeData(instanceData, defaultData)
1625
- } else {
1626
- return defaultData
1627
- }
1628
- }
1629
- }
1630
- }
1631
-
1632
- strats.data = function (
1633
- parentVal,
1634
- childVal,
1635
- vm
1636
- ) {
1637
- if (!vm) {
1638
- if (childVal && typeof childVal !== 'function') {
1639
- process.env.NODE_ENV !== 'production' && warn(
1640
- 'The "data" option should be a function ' +
1641
- 'that returns a per-instance value in component ' +
1642
- 'definitions.',
1643
- vm
1644
- );
1645
-
1646
- return parentVal
1647
- }
1648
- return mergeDataOrFn(parentVal, childVal)
1649
- }
1650
-
1651
- return mergeDataOrFn(parentVal, childVal, vm)
1652
- };
1653
-
1654
- /**
1655
- * Hooks and props are merged as arrays.
1656
- */
1657
- function mergeHook (
1658
- parentVal,
1659
- childVal
1660
- ) {
1661
- return childVal
1662
- ? parentVal
1663
- ? parentVal.concat(childVal)
1664
- : Array.isArray(childVal)
1665
- ? childVal
1666
- : [childVal]
1667
- : parentVal
1668
- }
1669
-
1670
- LIFECYCLE_HOOKS.forEach(function (hook) {
1671
- strats[hook] = mergeHook;
1672
- });
1673
-
1674
- /**
1675
- * Assets
1676
- *
1677
- * When a vm is present (instance creation), we need to do
1678
- * a three-way merge between constructor options, instance
1679
- * options and parent options.
1680
- */
1681
- function mergeAssets (
1682
- parentVal,
1683
- childVal,
1684
- vm,
1685
- key
1686
- ) {
1687
- var res = Object.create(parentVal || null);
1688
- if (childVal) {
1689
- process.env.NODE_ENV !== 'production' && assertObjectType(key, childVal, vm);
1690
- return extend(res, childVal)
1691
- } else {
1692
- return res
1693
- }
1694
- }
1695
-
1696
- ASSET_TYPES.forEach(function (type) {
1697
- strats[type + 's'] = mergeAssets;
1698
- });
1699
-
1700
- /**
1701
- * Watchers.
1702
- *
1703
- * Watchers hashes should not overwrite one
1704
- * another, so we merge them as arrays.
1705
- */
1706
- strats.watch = function (
1707
- parentVal,
1708
- childVal,
1709
- vm,
1710
- key
1711
- ) {
1712
- // work around Firefox's Object.prototype.watch...
1713
- if (parentVal === nativeWatch) { parentVal = undefined; }
1714
- if (childVal === nativeWatch) { childVal = undefined; }
1715
- /* istanbul ignore if */
1716
- if (!childVal) { return Object.create(parentVal || null) }
1717
- if (process.env.NODE_ENV !== 'production') {
1718
- assertObjectType(key, childVal, vm);
1719
- }
1720
- if (!parentVal) { return childVal }
1721
- var ret = {};
1722
- extend(ret, parentVal);
1723
- for (var key$1 in childVal) {
1724
- var parent = ret[key$1];
1725
- var child = childVal[key$1];
1726
- if (parent && !Array.isArray(parent)) {
1727
- parent = [parent];
1728
- }
1729
- ret[key$1] = parent
1730
- ? parent.concat(child)
1731
- : Array.isArray(child) ? child : [child];
1732
- }
1733
- return ret
1734
- };
1735
-
1736
- /**
1737
- * Other object hashes.
1738
- */
1739
- strats.props =
1740
- strats.methods =
1741
- strats.inject =
1742
- strats.computed = function (
1743
- parentVal,
1744
- childVal,
1745
- vm,
1746
- key
1747
- ) {
1748
- if (childVal && process.env.NODE_ENV !== 'production') {
1749
- assertObjectType(key, childVal, vm);
1750
- }
1751
- if (!parentVal) { return childVal }
1752
- var ret = Object.create(null);
1753
- extend(ret, parentVal);
1754
- if (childVal) { extend(ret, childVal); }
1755
- return ret
1756
- };
1757
- strats.provide = mergeDataOrFn;
1758
-
1759
- /**
1760
- * Default strategy.
1761
- */
1762
- var defaultStrat = function (parentVal, childVal) {
1763
- return childVal === undefined
1764
- ? parentVal
1765
- : childVal
1766
- };
1767
-
1768
- /**
1769
- * Validate component names
1770
- */
1771
- function checkComponents (options) {
1772
- for (var key in options.components) {
1773
- validateComponentName(key);
1774
- }
1775
- }
1776
-
1777
- function validateComponentName (name) {
1778
- if (!/^[a-zA-Z][\w-]*#x2F;.test(name)) {
1779
- warn(
1780
- 'Invalid component name: "' + name + '". Component names ' +
1781
- 'can only contain alphanumeric characters and the hyphen, ' +
1782
- 'and must start with a letter.'
1783
- );
1784
- }
1785
- if (isBuiltInTag(name) || config.isReservedTag(name)) {
1786
- warn(
1787
- 'Do not use built-in or reserved HTML elements as component ' +
1788
- 'id: ' + name
1789
- );
1790
- }
1791
- }
1792
-
1793
- /**
1794
- * Ensure all props option syntax are normalized into the
1795
- * Object-based format.
1796
- */
1797
- function normalizeProps (options, vm) {
1798
- var props = options.props;
1799
- if (!props) { return }
1800
- var res = {};
1801
- var i, val, name;
1802
- if (Array.isArray(props)) {
1803
- i = props.length;
1804
- while (i--) {
1805
- val = props[i];
1806
- if (typeof val === 'string') {
1807
- name = camelize(val);
1808
- res[name] = { type: null };
1809
- } else if (process.env.NODE_ENV !== 'production') {
1810
- warn('props must be strings when using array syntax.');
1811
- }
1812
- }
1813
- } else if (isPlainObject(props)) {
1814
- for (var key in props) {
1815
- val = props[key];
1816
- name = camelize(key);
1817
- res[name] = isPlainObject(val)
1818
- ? val
1819
- : { type: val };
1820
- }
1821
- } else if (process.env.NODE_ENV !== 'production') {
1822
- warn(
1823
- "Invalid value for option \"props\": expected an Array or an Object, " +
1824
- "but got " + (toRawType(props)) + ".",
1825
- vm
1826
- );
1827
- }
1828
- options.props = res;
1829
- }
1830
-
1831
- /**
1832
- * Normalize all injections into Object-based format
1833
- */
1834
- function normalizeInject (options, vm) {
1835
- var inject = options.inject;
1836
- if (!inject) { return }
1837
- var normalized = options.inject = {};
1838
- if (Array.isArray(inject)) {
1839
- for (var i = 0; i < inject.length; i++) {
1840
- normalized[inject[i]] = { from: inject[i] };
1841
- }
1842
- } else if (isPlainObject(inject)) {
1843
- for (var key in inject) {
1844
- var val = inject[key];
1845
- normalized[key] = isPlainObject(val)
1846
- ? extend({ from: key }, val)
1847
- : { from: val };
1848
- }
1849
- } else if (process.env.NODE_ENV !== 'production') {
1850
- warn(
1851
- "Invalid value for option \"inject\": expected an Array or an Object, " +
1852
- "but got " + (toRawType(inject)) + ".",
1853
- vm
1854
- );
1855
- }
1856
- }
1857
-
1858
- /**
1859
- * Normalize raw function directives into object format.
1860
- */
1861
- function normalizeDirectives (options) {
1862
- var dirs = options.directives;
1863
- if (dirs) {
1864
- for (var key in dirs) {
1865
- var def = dirs[key];
1866
- if (typeof def === 'function') {
1867
- dirs[key] = { bind: def, update: def };
1868
- }
1869
- }
1870
- }
1871
- }
1872
-
1873
- function assertObjectType (name, value, vm) {
1874
- if (!isPlainObject(value)) {
1875
- warn(
1876
- "Invalid value for option \"" + name + "\": expected an Object, " +
1877
- "but got " + (toRawType(value)) + ".",
1878
- vm
1879
- );
1880
- }
1881
- }
1882
-
1883
- /**
1884
- * Merge two option objects into a new one.
1885
- * Core utility used in both instantiation and inheritance.
1886
- */
1887
- function mergeOptions (
1888
- parent,
1889
- child,
1890
- vm
1891
- ) {
1892
- if (process.env.NODE_ENV !== 'production') {
1893
- checkComponents(child);
1894
- }
1895
-
1896
- if (typeof child === 'function') {
1897
- child = child.options;
1898
- }
1899
-
1900
- normalizeProps(child, vm);
1901
- normalizeInject(child, vm);
1902
- normalizeDirectives(child);
1903
-
1904
- // Apply extends and mixins on the child options,
1905
- // but only if it is a raw options object that isn't
1906
- // the result of another mergeOptions call.
1907
- // Only merged options has the _base property.
1908
- if (!child._base) {
1909
- if (child.extends) {
1910
- parent = mergeOptions(parent, child.extends, vm);
1911
- }
1912
- if (child.mixins) {
1913
- for (var i = 0, l = child.mixins.length; i < l; i++) {
1914
- parent = mergeOptions(parent, child.mixins[i], vm);
1915
- }
1916
- }
1917
- }
1918
-
1919
- var options = {};
1920
- var key;
1921
- for (key in parent) {
1922
- mergeField(key);
1923
- }
1924
- for (key in child) {
1925
- if (!hasOwn(parent, key)) {
1926
- mergeField(key);
1927
- }
1928
- }
1929
- function mergeField (key) {
1930
- var strat = strats[key] || defaultStrat;
1931
- options[key] = strat(parent[key], child[key], vm, key);
1932
- }
1933
- return options
1934
- }
1935
-
1936
- /**
1937
- * Resolve an asset.
1938
- * This function is used because child instances need access
1939
- * to assets defined in its ancestor chain.
1940
- */
1941
- function resolveAsset (
1942
- options,
1943
- type,
1944
- id,
1945
- warnMissing
1946
- ) {
1947
- /* istanbul ignore if */
1948
- if (typeof id !== 'string') {
1949
- return
1950
- }
1951
- var assets = options[type];
1952
- // check local registration variations first
1953
- if (hasOwn(assets, id)) { return assets[id] }
1954
- var camelizedId = camelize(id);
1955
- if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }
1956
- var PascalCaseId = capitalize(camelizedId);
1957
- if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }
1958
- // fallback to prototype chain
1959
- var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
1960
- if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {
1961
- warn(
1962
- 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
1963
- options
1964
- );
1965
- }
1966
- return res
1967
- }
1968
-
1969
- /* */
1970
-
1971
-
1972
-
1973
- function validateProp (
1974
- key,
1975
- propOptions,
1976
- propsData,
1977
- vm
1978
- ) {
1979
- var prop = propOptions[key];
1980
- var absent = !hasOwn(propsData, key);
1981
- var value = propsData[key];
1982
- // boolean casting
1983
- var booleanIndex = getTypeIndex(Boolean, prop.type);
1984
- if (booleanIndex > -1) {
1985
- if (absent && !hasOwn(prop, 'default')) {
1986
- value = false;
1987
- } else if (value === '' || value === hyphenate(key)) {
1988
- // only cast empty string / same name to boolean if
1989
- // boolean has higher priority
1990
- var stringIndex = getTypeIndex(String, prop.type);
1991
- if (stringIndex < 0 || booleanIndex < stringIndex) {
1992
- value = true;
1993
- }
1994
- }
1995
- }
1996
- // check default value
1997
- if (value === undefined) {
1998
- value = getPropDefaultValue(vm, prop, key);
1999
- // since the default value is a fresh copy,
2000
- // make sure to observe it.
2001
- var prevShouldObserve = shouldObserve;
2002
- toggleObserving(true);
2003
- observe(value);
2004
- toggleObserving(prevShouldObserve);
2005
- }
2006
- if (
2007
- process.env.NODE_ENV !== 'production' &&
2008
- // skip validation for weex recycle-list child component props
2009
- !(false)
2010
- ) {
2011
- assertProp(prop, key, value, vm, absent);
2012
- }
2013
- return value
2014
- }
2015
-
2016
- /**
2017
- * Get the default value of a prop.
2018
- */
2019
- function getPropDefaultValue (vm, prop, key) {
2020
- // no default, return undefined
2021
- if (!hasOwn(prop, 'default')) {
2022
- return undefined
2023
- }
2024
- var def = prop.default;
2025
- // warn against non-factory defaults for Object & Array
2026
- if (process.env.NODE_ENV !== 'production' && isObject(def)) {
2027
- warn(
2028
- 'Invalid default value for prop "' + key + '": ' +
2029
- 'Props with type Object/Array must use a factory function ' +
2030
- 'to return the default value.',
2031
- vm
2032
- );
2033
- }
2034
- // the raw prop value was also undefined from previous render,
2035
- // return previous default value to avoid unnecessary watcher trigger
2036
- if (vm && vm.$options.propsData &&
2037
- vm.$options.propsData[key] === undefined &&
2038
- vm._props[key] !== undefined
2039
- ) {
2040
- return vm._props[key]
2041
- }
2042
- // call factory function for non-Function types
2043
- // a value is Function if its prototype is function even across different execution context
2044
- return typeof def === 'function' && getType(prop.type) !== 'Function'
2045
- ? def.call(vm)
2046
- : def
2047
- }
2048
-
2049
- /**
2050
- * Assert whether a prop is valid.
2051
- */
2052
- function assertProp (
2053
- prop,
2054
- name,
2055
- value,
2056
- vm,
2057
- absent
2058
- ) {
2059
- if (prop.required && absent) {
2060
- warn(
2061
- 'Missing required prop: "' + name + '"',
2062
- vm
2063
- );
2064
- return
2065
- }
2066
- if (value == null && !prop.required) {
2067
- return
2068
- }
2069
- var type = prop.type;
2070
- var valid = !type || type === true;
2071
- var expectedTypes = [];
2072
- if (type) {
2073
- if (!Array.isArray(type)) {
2074
- type = [type];
2075
- }
2076
- for (var i = 0; i < type.length && !valid; i++) {
2077
- var assertedType = assertType(value, type[i]);
2078
- expectedTypes.push(assertedType.expectedType || '');
2079
- valid = assertedType.valid;
2080
- }
2081
- }
2082
-
2083
- if (!valid) {
2084
- warn(
2085
- getInvalidTypeMessage(name, value, expectedTypes),
2086
- vm
2087
- );
2088
- return
2089
- }
2090
- var validator = prop.validator;
2091