@srdstore/vue-style-loader 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/.circleci/config.yml +28 -0
- package/.github/ISSUE_TEMPLATE.md +15 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +18 -0
- package/CHANGELOG.md +86 -0
- package/LICENSE +20 -0
- package/README.md +47 -0
- package/index.js +101 -0
- package/lib/addStylesClient.js +222 -0
- package/lib/addStylesServer.js +80 -0
- package/lib/addStylesShadow.js +70 -0
- package/lib/listToStyles.js +27 -0
- package/package.json +28 -0
- package/test/test.js +94 -0
package/.babelrc
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
jobs:
|
|
3
|
+
build:
|
|
4
|
+
docker:
|
|
5
|
+
# https://circleci.com/docs/2.0/circleci-images/#nodejs
|
|
6
|
+
- image: circleci/node:6
|
|
7
|
+
|
|
8
|
+
working_directory: ~/vue-style-loader
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- checkout
|
|
12
|
+
|
|
13
|
+
# Download and cache dependencies
|
|
14
|
+
- restore_cache:
|
|
15
|
+
keys:
|
|
16
|
+
- v1-dependencies-{{ checksum "package.json" }}
|
|
17
|
+
# fallback to using the latest cache if no exact match is found
|
|
18
|
+
- v1-dependencies-
|
|
19
|
+
|
|
20
|
+
- run: yarn install
|
|
21
|
+
|
|
22
|
+
- save_cache:
|
|
23
|
+
paths:
|
|
24
|
+
- node_modules
|
|
25
|
+
key: v1-dependencies-{{ checksum "package.json" }}
|
|
26
|
+
|
|
27
|
+
# run tests!
|
|
28
|
+
- run: yarn test
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- Before creating an issue please make sure you are using the latest version of style-loader. -->
|
|
2
|
+
|
|
3
|
+
**Do you want to request a *feature* or report a *bug*?**
|
|
4
|
+
<!-- Please ask questions on StackOverflow or the webpack Gitter (https://gitter.im/webpack/webpack). Questions will be closed. -->
|
|
5
|
+
|
|
6
|
+
**What is the current behavior?**
|
|
7
|
+
|
|
8
|
+
**If the current behavior is a bug, please provide the steps to reproduce.**
|
|
9
|
+
<!-- A great way to do this is to provide your configuration via a GitHub gist. -->
|
|
10
|
+
|
|
11
|
+
**What is the expected behavior?**
|
|
12
|
+
|
|
13
|
+
**If this is a feature request, what is motivation or use case for changing the behavior?**
|
|
14
|
+
|
|
15
|
+
**Please mention other relevant information such as your webpack version, Node.js version and Operating System.**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->
|
|
2
|
+
|
|
3
|
+
**What kind of change does this PR introduce?**
|
|
4
|
+
<!-- E.g. a bugfix, feature, refactoring, build related change, etc… -->
|
|
5
|
+
|
|
6
|
+
**Did you add tests for your changes?**
|
|
7
|
+
|
|
8
|
+
**If relevant, did you update the README?**
|
|
9
|
+
|
|
10
|
+
**Summary**
|
|
11
|
+
|
|
12
|
+
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
|
|
13
|
+
<!-- Try to link to an open issue for more information. -->
|
|
14
|
+
|
|
15
|
+
**Does this PR introduce a breaking change?**
|
|
16
|
+
<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->
|
|
17
|
+
|
|
18
|
+
**Other information**
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<a name="4.1.3"></a>
|
|
2
|
+
## [4.1.3](https://github.com/vuejs/vue-style-loader/compare/v4.0.1...v4.1.3) (2021-03-03)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* also support passed ES modules from `css-loader` in addition to CommonJS format ([#47](https://github.com/vuejs/vue-style-loader/issues/47)) ([8b584bd](https://github.com/vuejs/vue-style-loader/commit/8b584bd))
|
|
8
|
+
* es module interop in HMR code ([8bc2fe3](https://github.com/vuejs/vue-style-loader/commit/8bc2fe3))
|
|
9
|
+
* fix addStyleShadow when same style object is inserted multiple times ([12846a6](https://github.com/vuejs/vue-style-loader/commit/12846a6))
|
|
10
|
+
* fix inconsistent hashes between Windows and POSIX systems ([#28](https://github.com/vuejs/vue-style-loader/issues/28)) ([cf8b6e8](https://github.com/vuejs/vue-style-loader/commit/cf8b6e8))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* support vue-loader 15 ([0c7ee9d](https://github.com/vuejs/vue-style-loader/commit/0c7ee9d))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
<a name="4.1.2"></a>
|
|
20
|
+
## [4.1.2](https://github.com/vuejs/vue-style-loader/compare/v4.1.1...v4.1.2) (2018-08-13)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* fix inconsistent hashes between Windows and POSIX systems ([#28](https://github.com/vuejs/vue-style-loader/issues/28)) ([cf8b6e8](https://github.com/vuejs/vue-style-loader/commit/cf8b6e8))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
<a name="4.1.1"></a>
|
|
30
|
+
## [4.1.1](https://github.com/vuejs/vue-style-loader/compare/v4.1.0...v4.1.1) (2018-07-17)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* fix addStyleShadow when same style object is inserted multiple times ([12846a6](https://github.com/vuejs/vue-style-loader/commit/12846a6))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<a name="4.1.0"></a>
|
|
40
|
+
# [4.1.0](https://github.com/vuejs/vue-style-loader/compare/v4.0.2...v4.1.0) (2018-03-20)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Features
|
|
44
|
+
|
|
45
|
+
* support vue-loader 15 ([0c7ee9d](https://github.com/vuejs/vue-style-loader/commit/0c7ee9d))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<a name="4.0.2"></a>
|
|
50
|
+
## [4.0.2](https://github.com/vuejs/vue-style-loader/compare/v4.0.1...v4.0.2) (2018-02-13)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
<a name="4.0.1"></a>
|
|
55
|
+
## [4.0.1](https://github.com/vuejs/vue-style-loader/compare/v4.0.0...v4.0.1) (2018-01-31)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
### Bug Fixes
|
|
59
|
+
|
|
60
|
+
* typo ([00087b7](https://github.com/vuejs/vue-style-loader/commit/00087b7))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
<a name="4.0.0"></a>
|
|
65
|
+
# [4.0.0](https://github.com/vuejs/vue-style-loader/compare/v3.1.1...v4.0.0) (2018-01-31)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Features
|
|
69
|
+
|
|
70
|
+
* shadowMode ([94737e5](https://github.com/vuejs/vue-style-loader/commit/94737e5))
|
|
71
|
+
* use ESM for runtime files ([18d0ae4](https://github.com/vuejs/vue-style-loader/commit/18d0ae4))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
<a name="3.1.1"></a>
|
|
76
|
+
## [3.1.1](https://github.com/vuejs/vue-style-loader/compare/v3.1.0...v3.1.1) (2018-01-24)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
<a name="3.1.0"></a>
|
|
81
|
+
# [3.1.0](https://github.com/vuejs/vue-style-loader/compare/v3.0.3...v3.1.0) (2018-01-24)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### Features
|
|
85
|
+
|
|
86
|
+
* add `ssrId` option for rendering ssr id on client ([5281305](https://github.com/vuejs/vue-style-loader/commit/5281305))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright JS Foundation and other contributors
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# vue-style-loader [](https://circleci.com/gh/vuejs/vue-loader/tree/master) [](https://www.npmjs.com/package/vue-style-loader)
|
|
2
|
+
|
|
3
|
+
This is a fork based on [style-loader](https://github.com/webpack/style-loader). Similar to `style-loader`, you can chain it after `css-loader` to dynamically inject CSS into the document as style tags. However, since this is included as a dependency and used by default in `vue-loader`, in most cases you don't need to configure this loader yourself.
|
|
4
|
+
|
|
5
|
+
## Options
|
|
6
|
+
|
|
7
|
+
- **manualInject** (3.1.0+):
|
|
8
|
+
|
|
9
|
+
Type: `boolean`. When importing the style from a non-vue-file, by default the style is injected as a side effect of the import. When `manualInject` is true, the imported style object exposes a `__inject__` method, which can then be called manually at appropriate timing. If called on the server, the method expects one argument which is the `ssrContext` to attach styles to.
|
|
10
|
+
|
|
11
|
+
``` js
|
|
12
|
+
import styles from 'styles.scss'
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
beforeCreate() { // or create a mixin for this purpose
|
|
16
|
+
if(styles.__inject__) {
|
|
17
|
+
styles.__inject__(this.$ssrContext)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
render() {
|
|
22
|
+
return <div class={styles.heading}>Hello World</div>
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Note this behavior is enabled automatically when `vue-style-loader` is used on styles imported within a `*.vue` file. The option is only exposed for advanced usage.
|
|
28
|
+
|
|
29
|
+
- **ssrId** (3.1.0+):
|
|
30
|
+
|
|
31
|
+
Type: `boolean`. Add `data-vue-ssr-id` attribute to injected `<style>` tags even when not in Node.js. This can be used with pre-rendering (instead of SSR) to avoid duplicate style injection on hydration.
|
|
32
|
+
|
|
33
|
+
## Differences from `style-loader`
|
|
34
|
+
|
|
35
|
+
### Server-Side Rendering Support
|
|
36
|
+
|
|
37
|
+
When bundling with `target: 'node'`, the styles in all rendered components are collected and exposed on the Vue render context object as `context.styles`, which you can simply inline into your markup's `<head>`. If you are building a Vue SSR app, you probably should use this loader for CSS imported from JavaScript files too.
|
|
38
|
+
|
|
39
|
+
### Misc
|
|
40
|
+
|
|
41
|
+
- Does not support url mode and reference counting mode. Also removed `singleton` and `insertAt` query options. It always automatically pick the style insertion mechanism that makes most sense. If you need these capabilities you should probably use the original `style-loader` instead.
|
|
42
|
+
|
|
43
|
+
- Fixed the issue that root-relative URLs are interpreted against chrome:// urls and make source map URLs work for injected `<style>` tags in Chrome.
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
Author Tobias Koppers @sokra
|
|
4
|
+
Modified by Evan You @yyx990803
|
|
5
|
+
*/
|
|
6
|
+
var loaderUtils = require('loader-utils')
|
|
7
|
+
var path = require('path')
|
|
8
|
+
var hash = require('hash-sum')
|
|
9
|
+
var qs = require('querystring')
|
|
10
|
+
|
|
11
|
+
module.exports = function () {}
|
|
12
|
+
|
|
13
|
+
module.exports.pitch = function (remainingRequest) {
|
|
14
|
+
var isServer = this.target === 'node'
|
|
15
|
+
var isProduction = this.minimize || process.env.NODE_ENV === 'production'
|
|
16
|
+
var addStylesClientPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesClient.js'))
|
|
17
|
+
var addStylesServerPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesServer.js'))
|
|
18
|
+
var addStylesShadowPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesShadow.js'))
|
|
19
|
+
|
|
20
|
+
var request = loaderUtils.stringifyRequest(this, '!!' + remainingRequest)
|
|
21
|
+
var relPath = path.relative(__dirname, this.resourcePath).replace(/\\/g, '/')
|
|
22
|
+
var id = JSON.stringify(hash(request + relPath))
|
|
23
|
+
var options = loaderUtils.getOptions(this) || {}
|
|
24
|
+
|
|
25
|
+
// direct css import from js --> direct, or manually call `styles.__inject__(ssrContext)` with `manualInject` option
|
|
26
|
+
// css import from vue file --> component lifecycle linked
|
|
27
|
+
// style embedded in vue file --> component lifecycle linked
|
|
28
|
+
var isVue = (
|
|
29
|
+
/"vue":true/.test(remainingRequest) ||
|
|
30
|
+
options.manualInject ||
|
|
31
|
+
qs.parse(this.resourceQuery.slice(1)).vue != null
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
var shared = [
|
|
35
|
+
'// style-loader: Adds some css to the DOM by adding a <style> tag',
|
|
36
|
+
'',
|
|
37
|
+
'// load the styles',
|
|
38
|
+
'var content = require(' + request + ');',
|
|
39
|
+
// get default export if list is an ES Module (CSS Loader v4+)
|
|
40
|
+
"if(content.__esModule) content = content.default;",
|
|
41
|
+
// content list format is [id, css, media, sourceMap]
|
|
42
|
+
"if(typeof content === 'string') content = [[module.id, content, '']];",
|
|
43
|
+
'if(content.locals) module.exports = content.locals;'
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
// shadowMode is enabled in vue-cli with vue build --target web-component.
|
|
47
|
+
// exposes the same __inject__ method like SSR
|
|
48
|
+
if (options.shadowMode) {
|
|
49
|
+
return shared.concat([
|
|
50
|
+
'// add CSS to Shadow Root',
|
|
51
|
+
'var add = require(' + addStylesShadowPath + ').default',
|
|
52
|
+
'module.exports.__inject__ = function (shadowRoot) {',
|
|
53
|
+
' add(' + id + ', content, shadowRoot)',
|
|
54
|
+
'};'
|
|
55
|
+
]).join('\n')
|
|
56
|
+
} else if (!isServer) {
|
|
57
|
+
// on the client: dynamic inject + hot-reload
|
|
58
|
+
var code = [
|
|
59
|
+
'// add the styles to the DOM',
|
|
60
|
+
'var add = require(' + addStylesClientPath + ').default',
|
|
61
|
+
'var update = add(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'
|
|
62
|
+
]
|
|
63
|
+
if (!isProduction) {
|
|
64
|
+
code = code.concat([
|
|
65
|
+
'// Hot Module Replacement',
|
|
66
|
+
'if(module.hot) {',
|
|
67
|
+
' // When the styles change, update the <style> tags',
|
|
68
|
+
' if(!content.locals) {',
|
|
69
|
+
' module.hot.accept(' + request + ', function() {',
|
|
70
|
+
' var newContent = require(' + request + ');',
|
|
71
|
+
' if(newContent.__esModule) newContent = newContent.default;',
|
|
72
|
+
" if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];",
|
|
73
|
+
' update(newContent);',
|
|
74
|
+
' });',
|
|
75
|
+
' }',
|
|
76
|
+
' // When the module is disposed, remove the <style> tags',
|
|
77
|
+
' module.hot.dispose(function() { update(); });',
|
|
78
|
+
'}'
|
|
79
|
+
])
|
|
80
|
+
}
|
|
81
|
+
return shared.concat(code).join('\n')
|
|
82
|
+
} else {
|
|
83
|
+
// on the server: attach to Vue SSR context
|
|
84
|
+
if (isVue) {
|
|
85
|
+
// inside *.vue file: expose a function so it can be called in
|
|
86
|
+
// component's lifecycle hooks
|
|
87
|
+
return shared.concat([
|
|
88
|
+
'// add CSS to SSR context',
|
|
89
|
+
'var add = require(' + addStylesServerPath + ').default',
|
|
90
|
+
'module.exports.__inject__ = function (context) {',
|
|
91
|
+
' add(' + id + ', content, ' + isProduction + ', context)',
|
|
92
|
+
'};'
|
|
93
|
+
]).join('\n')
|
|
94
|
+
} else {
|
|
95
|
+
// normal import
|
|
96
|
+
return shared.concat([
|
|
97
|
+
'require(' + addStylesServerPath + ').default(' + id + ', content, ' + isProduction + ')'
|
|
98
|
+
]).join('\n')
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
Author Tobias Koppers @sokra
|
|
4
|
+
Modified by Evan You @yyx990803
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import listToStyles from './listToStyles'
|
|
8
|
+
|
|
9
|
+
var hasDocument = typeof document !== 'undefined'
|
|
10
|
+
|
|
11
|
+
if (typeof DEBUG !== 'undefined' && DEBUG) {
|
|
12
|
+
if (!hasDocument) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
'vue-style-loader cannot be used in a non-browser environment. ' +
|
|
15
|
+
"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment."
|
|
16
|
+
) }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
type StyleObject = {
|
|
21
|
+
id: number;
|
|
22
|
+
parts: Array<StyleObjectPart>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type StyleObjectPart = {
|
|
26
|
+
css: string;
|
|
27
|
+
media: string;
|
|
28
|
+
sourceMap: ?string
|
|
29
|
+
}
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
var stylesInDom = {/*
|
|
33
|
+
[id: number]: {
|
|
34
|
+
id: number,
|
|
35
|
+
refs: number,
|
|
36
|
+
parts: Array<(obj?: StyleObjectPart) => void>
|
|
37
|
+
}
|
|
38
|
+
*/}
|
|
39
|
+
|
|
40
|
+
var head = hasDocument && (document.head || document.getElementsByTagName('head')[0])
|
|
41
|
+
var singletonElement = null
|
|
42
|
+
var singletonCounter = 0
|
|
43
|
+
var isProduction = false
|
|
44
|
+
var noop = function () {}
|
|
45
|
+
var options = null
|
|
46
|
+
var ssrIdKey = 'data-vue-ssr-id'
|
|
47
|
+
|
|
48
|
+
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
|
|
49
|
+
// tags it will allow on a page
|
|
50
|
+
var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\b/.test(navigator.userAgent.toLowerCase())
|
|
51
|
+
|
|
52
|
+
export default function addStylesClient (parentId, list, _isProduction, _options) {
|
|
53
|
+
isProduction = _isProduction
|
|
54
|
+
|
|
55
|
+
options = _options || {}
|
|
56
|
+
|
|
57
|
+
var styles = listToStyles(parentId, list)
|
|
58
|
+
addStylesToDom(styles)
|
|
59
|
+
|
|
60
|
+
return function update (newList) {
|
|
61
|
+
var mayRemove = []
|
|
62
|
+
for (var i = 0; i < styles.length; i++) {
|
|
63
|
+
var item = styles[i]
|
|
64
|
+
var domStyle = stylesInDom[item.id]
|
|
65
|
+
domStyle.refs--
|
|
66
|
+
mayRemove.push(domStyle)
|
|
67
|
+
}
|
|
68
|
+
if (newList) {
|
|
69
|
+
styles = listToStyles(parentId, newList)
|
|
70
|
+
addStylesToDom(styles)
|
|
71
|
+
} else {
|
|
72
|
+
styles = []
|
|
73
|
+
}
|
|
74
|
+
for (var i = 0; i < mayRemove.length; i++) {
|
|
75
|
+
var domStyle = mayRemove[i]
|
|
76
|
+
if (domStyle.refs === 0) {
|
|
77
|
+
for (var j = 0; j < domStyle.parts.length; j++) {
|
|
78
|
+
domStyle.parts[j]()
|
|
79
|
+
}
|
|
80
|
+
delete stylesInDom[domStyle.id]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function addStylesToDom (styles /* Array<StyleObject> */) {
|
|
87
|
+
for (var i = 0; i < styles.length; i++) {
|
|
88
|
+
var item = styles[i]
|
|
89
|
+
var domStyle = stylesInDom[item.id]
|
|
90
|
+
if (domStyle) {
|
|
91
|
+
domStyle.refs++
|
|
92
|
+
for (var j = 0; j < domStyle.parts.length; j++) {
|
|
93
|
+
domStyle.parts[j](item.parts[j])
|
|
94
|
+
}
|
|
95
|
+
for (; j < item.parts.length; j++) {
|
|
96
|
+
domStyle.parts.push(addStyle(item.parts[j]))
|
|
97
|
+
}
|
|
98
|
+
if (domStyle.parts.length > item.parts.length) {
|
|
99
|
+
domStyle.parts.length = item.parts.length
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
var parts = []
|
|
103
|
+
for (var j = 0; j < item.parts.length; j++) {
|
|
104
|
+
parts.push(addStyle(item.parts[j]))
|
|
105
|
+
}
|
|
106
|
+
stylesInDom[item.id] = { id: item.id, refs: 1, parts: parts }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function createStyleElement () {
|
|
112
|
+
var styleElement = document.createElement('style')
|
|
113
|
+
styleElement.type = 'text/css'
|
|
114
|
+
head.appendChild(styleElement)
|
|
115
|
+
return styleElement
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function addStyle (obj /* StyleObjectPart */) {
|
|
119
|
+
var update, remove
|
|
120
|
+
var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]')
|
|
121
|
+
|
|
122
|
+
if (styleElement) {
|
|
123
|
+
if (isProduction) {
|
|
124
|
+
// has SSR styles and in production mode.
|
|
125
|
+
// simply do nothing.
|
|
126
|
+
return noop
|
|
127
|
+
} else {
|
|
128
|
+
// has SSR styles but in dev mode.
|
|
129
|
+
// for some reason Chrome can't handle source map in server-rendered
|
|
130
|
+
// style tags - source maps in <style> only works if the style tag is
|
|
131
|
+
// created and inserted dynamically. So we remove the server rendered
|
|
132
|
+
// styles and inject new ones.
|
|
133
|
+
styleElement.parentNode.removeChild(styleElement)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (isOldIE) {
|
|
138
|
+
// use singleton mode for IE9.
|
|
139
|
+
var styleIndex = singletonCounter++
|
|
140
|
+
styleElement = singletonElement || (singletonElement = createStyleElement())
|
|
141
|
+
update = applyToSingletonTag.bind(null, styleElement, styleIndex, false)
|
|
142
|
+
remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true)
|
|
143
|
+
} else {
|
|
144
|
+
// use multi-style-tag mode in all other cases
|
|
145
|
+
styleElement = createStyleElement()
|
|
146
|
+
update = applyToTag.bind(null, styleElement)
|
|
147
|
+
remove = function () {
|
|
148
|
+
styleElement.parentNode.removeChild(styleElement)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
update(obj)
|
|
153
|
+
|
|
154
|
+
return function updateStyle (newObj /* StyleObjectPart */) {
|
|
155
|
+
if (newObj) {
|
|
156
|
+
if (newObj.css === obj.css &&
|
|
157
|
+
newObj.media === obj.media &&
|
|
158
|
+
newObj.sourceMap === obj.sourceMap) {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
update(obj = newObj)
|
|
162
|
+
} else {
|
|
163
|
+
remove()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
var replaceText = (function () {
|
|
169
|
+
var textStore = []
|
|
170
|
+
|
|
171
|
+
return function (index, replacement) {
|
|
172
|
+
textStore[index] = replacement
|
|
173
|
+
return textStore.filter(Boolean).join('\n')
|
|
174
|
+
}
|
|
175
|
+
})()
|
|
176
|
+
|
|
177
|
+
function applyToSingletonTag (styleElement, index, remove, obj) {
|
|
178
|
+
var css = remove ? '' : obj.css
|
|
179
|
+
|
|
180
|
+
if (styleElement.styleSheet) {
|
|
181
|
+
styleElement.styleSheet.cssText = replaceText(index, css)
|
|
182
|
+
} else {
|
|
183
|
+
var cssNode = document.createTextNode(css)
|
|
184
|
+
var childNodes = styleElement.childNodes
|
|
185
|
+
if (childNodes[index]) styleElement.removeChild(childNodes[index])
|
|
186
|
+
if (childNodes.length) {
|
|
187
|
+
styleElement.insertBefore(cssNode, childNodes[index])
|
|
188
|
+
} else {
|
|
189
|
+
styleElement.appendChild(cssNode)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function applyToTag (styleElement, obj) {
|
|
195
|
+
var css = obj.css
|
|
196
|
+
var media = obj.media
|
|
197
|
+
var sourceMap = obj.sourceMap
|
|
198
|
+
|
|
199
|
+
if (media) {
|
|
200
|
+
styleElement.setAttribute('media', media)
|
|
201
|
+
}
|
|
202
|
+
if (options.ssrId) {
|
|
203
|
+
styleElement.setAttribute(ssrIdKey, obj.id)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (sourceMap) {
|
|
207
|
+
// https://developer.chrome.com/devtools/docs/javascript-debugging
|
|
208
|
+
// this makes source maps inside style tags work properly in Chrome
|
|
209
|
+
css += '\n/*# sourceURL=' + sourceMap.sources[0] + ' */'
|
|
210
|
+
// http://stackoverflow.com/a/26603875
|
|
211
|
+
css += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */'
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (styleElement.styleSheet) {
|
|
215
|
+
styleElement.styleSheet.cssText = css
|
|
216
|
+
} else {
|
|
217
|
+
while (styleElement.firstChild) {
|
|
218
|
+
styleElement.removeChild(styleElement.firstChild)
|
|
219
|
+
}
|
|
220
|
+
styleElement.appendChild(document.createTextNode(css))
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import listToStyles from './listToStyles'
|
|
2
|
+
|
|
3
|
+
export default function addStylesServer (parentId, list, isProduction, context) {
|
|
4
|
+
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
|
|
5
|
+
context = __VUE_SSR_CONTEXT__
|
|
6
|
+
}
|
|
7
|
+
if (context) {
|
|
8
|
+
if (!context.hasOwnProperty('styles')) {
|
|
9
|
+
Object.defineProperty(context, 'styles', {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return renderStyles(context._styles)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
// expose renderStyles for vue-server-renderer (vuejs/#6353)
|
|
16
|
+
context._renderStyles = renderStyles
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var styles = context._styles || (context._styles = {})
|
|
20
|
+
list = listToStyles(parentId, list)
|
|
21
|
+
if (isProduction) {
|
|
22
|
+
addStyleProd(styles, list)
|
|
23
|
+
} else {
|
|
24
|
+
addStyleDev(styles, list)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// In production, render as few style tags as possible.
|
|
30
|
+
// (mostly because IE9 has a limit on number of style tags)
|
|
31
|
+
function addStyleProd (styles, list) {
|
|
32
|
+
for (var i = 0; i < list.length; i++) {
|
|
33
|
+
var parts = list[i].parts
|
|
34
|
+
for (var j = 0; j < parts.length; j++) {
|
|
35
|
+
var part = parts[j]
|
|
36
|
+
// group style tags by media types.
|
|
37
|
+
var id = part.media || 'default'
|
|
38
|
+
var style = styles[id]
|
|
39
|
+
if (style) {
|
|
40
|
+
if (style.ids.indexOf(part.id) < 0) {
|
|
41
|
+
style.ids.push(part.id)
|
|
42
|
+
style.css += '\n' + part.css
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
styles[id] = {
|
|
46
|
+
ids: [part.id],
|
|
47
|
+
css: part.css,
|
|
48
|
+
media: part.media
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// In dev we use individual style tag for each module for hot-reload
|
|
56
|
+
// and source maps.
|
|
57
|
+
function addStyleDev (styles, list) {
|
|
58
|
+
for (var i = 0; i < list.length; i++) {
|
|
59
|
+
var parts = list[i].parts
|
|
60
|
+
for (var j = 0; j < parts.length; j++) {
|
|
61
|
+
var part = parts[j]
|
|
62
|
+
styles[part.id] = {
|
|
63
|
+
ids: [part.id],
|
|
64
|
+
css: part.css,
|
|
65
|
+
media: part.media
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function renderStyles (styles) {
|
|
72
|
+
var css = ''
|
|
73
|
+
for (var key in styles) {
|
|
74
|
+
var style = styles[key]
|
|
75
|
+
css += '<style data-vue-ssr-id="' + style.ids.join(' ') + '"' +
|
|
76
|
+
(style.media ? ( ' media="' + style.media + '"' ) : '') + '>' +
|
|
77
|
+
style.css + '</style>'
|
|
78
|
+
}
|
|
79
|
+
return css
|
|
80
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import listToStyles from './listToStyles'
|
|
2
|
+
|
|
3
|
+
export default function addStylesToShadowDOM (parentId, list, shadowRoot) {
|
|
4
|
+
var styles = listToStyles(parentId, list)
|
|
5
|
+
addStyles(styles, shadowRoot)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
type StyleObject = {
|
|
10
|
+
id: number;
|
|
11
|
+
parts: Array<StyleObjectPart>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type StyleObjectPart = {
|
|
15
|
+
css: string;
|
|
16
|
+
media: string;
|
|
17
|
+
sourceMap: ?string
|
|
18
|
+
}
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
function addStyles (styles /* Array<StyleObject> */, shadowRoot) {
|
|
22
|
+
const injectedStyles =
|
|
23
|
+
shadowRoot._injectedStyles ||
|
|
24
|
+
(shadowRoot._injectedStyles = {})
|
|
25
|
+
for (var i = 0; i < styles.length; i++) {
|
|
26
|
+
var item = styles[i]
|
|
27
|
+
var style = injectedStyles[item.id]
|
|
28
|
+
if (!style) {
|
|
29
|
+
for (var j = 0; j < item.parts.length; j++) {
|
|
30
|
+
addStyle(item.parts[j], shadowRoot)
|
|
31
|
+
}
|
|
32
|
+
injectedStyles[item.id] = true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createStyleElement (shadowRoot) {
|
|
38
|
+
var styleElement = document.createElement('style')
|
|
39
|
+
styleElement.type = 'text/css'
|
|
40
|
+
shadowRoot.appendChild(styleElement)
|
|
41
|
+
return styleElement
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function addStyle (obj /* StyleObjectPart */, shadowRoot) {
|
|
45
|
+
var styleElement = createStyleElement(shadowRoot)
|
|
46
|
+
var css = obj.css
|
|
47
|
+
var media = obj.media
|
|
48
|
+
var sourceMap = obj.sourceMap
|
|
49
|
+
|
|
50
|
+
if (media) {
|
|
51
|
+
styleElement.setAttribute('media', media)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (sourceMap) {
|
|
55
|
+
// https://developer.chrome.com/devtools/docs/javascript-debugging
|
|
56
|
+
// this makes source maps inside style tags work properly in Chrome
|
|
57
|
+
css += '\n/*# sourceURL=' + sourceMap.sources[0] + ' */'
|
|
58
|
+
// http://stackoverflow.com/a/26603875
|
|
59
|
+
css += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (styleElement.styleSheet) {
|
|
63
|
+
styleElement.styleSheet.cssText = css
|
|
64
|
+
} else {
|
|
65
|
+
while (styleElement.firstChild) {
|
|
66
|
+
styleElement.removeChild(styleElement.firstChild)
|
|
67
|
+
}
|
|
68
|
+
styleElement.appendChild(document.createTextNode(css))
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translates the list format produced by css-loader into something
|
|
3
|
+
* easier to manipulate.
|
|
4
|
+
*/
|
|
5
|
+
export default function listToStyles (parentId, list) {
|
|
6
|
+
var styles = []
|
|
7
|
+
var newStyles = {}
|
|
8
|
+
for (var i = 0; i < list.length; i++) {
|
|
9
|
+
var item = list[i]
|
|
10
|
+
var id = item[0]
|
|
11
|
+
var css = item[1]
|
|
12
|
+
var media = item[2]
|
|
13
|
+
var sourceMap = item[3]
|
|
14
|
+
var part = {
|
|
15
|
+
id: parentId + ':' + i,
|
|
16
|
+
css: css,
|
|
17
|
+
media: media,
|
|
18
|
+
sourceMap: sourceMap
|
|
19
|
+
}
|
|
20
|
+
if (!newStyles[id]) {
|
|
21
|
+
styles.push(newStyles[id] = { id: id, parts: [part] })
|
|
22
|
+
} else {
|
|
23
|
+
newStyles[id].parts.push(part)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return styles
|
|
27
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@srdstore/vue-style-loader",
|
|
3
|
+
"version": "4.1.3",
|
|
4
|
+
"author": "Evan You",
|
|
5
|
+
"description": "Vue.js style loader module for webpack (Re-published from vue-style-loader@4.1.3)",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git@github.com:vuejs/vue-style-loader.git"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "jest"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"hash-sum": "^1.0.2",
|
|
16
|
+
"loader-utils": "^1.0.2"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"babel-core": "^6.26.0",
|
|
20
|
+
"babel-jest": "^22.1.0",
|
|
21
|
+
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
|
|
22
|
+
"conventional-changelog-cli": "^2.0.1",
|
|
23
|
+
"jest": "^22.1.4"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/test/test.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import addStylesClient from '../lib/addStylesClient'
|
|
2
|
+
import addStylesServer from '../lib/addStylesServer'
|
|
3
|
+
|
|
4
|
+
const mockedList = [
|
|
5
|
+
[1, 'h1 { color: red; }', ''],
|
|
6
|
+
[1, 'p { color: green; }', ''],
|
|
7
|
+
[2, 'span { color: blue; }', ''],
|
|
8
|
+
[2, 'span { color: blue; }', 'print']
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
test('addStylesClient (dev)', () => {
|
|
12
|
+
const update = addStylesClient('foo', mockedList, false)
|
|
13
|
+
assertStylesMatch(mockedList)
|
|
14
|
+
const mockedList2 = mockedList.slice(1, 3)
|
|
15
|
+
update(mockedList2)
|
|
16
|
+
assertStylesMatch(mockedList2)
|
|
17
|
+
update()
|
|
18
|
+
expect(document.querySelectorAll('style').length).toBe(0)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('addStylesClient (prod)', () => {
|
|
22
|
+
const update = addStylesClient('foo', mockedList, true)
|
|
23
|
+
assertStylesMatch(mockedList)
|
|
24
|
+
const mockedList2 = mockedList.slice(2)
|
|
25
|
+
update(mockedList2)
|
|
26
|
+
assertStylesMatch(mockedList2)
|
|
27
|
+
update()
|
|
28
|
+
expect(document.querySelectorAll('style').length).toBe(0)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('addStylesClient (dev + ssr)', () => {
|
|
32
|
+
mockSSRTags(mockedList, 'foo')
|
|
33
|
+
const update = addStylesClient('foo', mockedList, false)
|
|
34
|
+
assertStylesMatch(mockedList)
|
|
35
|
+
update()
|
|
36
|
+
expect(document.querySelectorAll('style').length).toBe(0)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('addStylesClient (prod + ssr)', () => {
|
|
40
|
+
mockProdSSRTags(mockedList, 'foo')
|
|
41
|
+
const update = addStylesClient('foo', mockedList, true)
|
|
42
|
+
expect(document.querySelectorAll('style').length).toBe(1)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('addStylesServer (dev)', () => {
|
|
46
|
+
const context = global.__VUE_SSR_CONTEXT__ = {}
|
|
47
|
+
addStylesServer('foo', mockedList, false)
|
|
48
|
+
expect(context.styles).toBe(
|
|
49
|
+
`<style data-vue-ssr-id="foo:0">h1 { color: red; }</style>` +
|
|
50
|
+
`<style data-vue-ssr-id="foo:1">p { color: green; }</style>` +
|
|
51
|
+
`<style data-vue-ssr-id="foo:2">span { color: blue; }</style>` +
|
|
52
|
+
`<style data-vue-ssr-id="foo:3" media="print">span { color: blue; }</style>`
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('addStylesServer (prod)', () => {
|
|
57
|
+
const context = global.__VUE_SSR_CONTEXT__ = {}
|
|
58
|
+
addStylesServer('foo', mockedList, true)
|
|
59
|
+
expect(context.styles).toBe(
|
|
60
|
+
`<style data-vue-ssr-id="foo:0 foo:1 foo:2">` +
|
|
61
|
+
`h1 { color: red; }\np { color: green; }\nspan { color: blue; }` +
|
|
62
|
+
`</style>` +
|
|
63
|
+
`<style data-vue-ssr-id="foo:3" media="print">span { color: blue; }</style>`
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// --- helpers ---
|
|
68
|
+
|
|
69
|
+
function assertStylesMatch (list) {
|
|
70
|
+
const styles = document.querySelectorAll('style')
|
|
71
|
+
expect(styles.length).toBe(list.length)
|
|
72
|
+
;[].forEach.call(styles, (style, i) => {
|
|
73
|
+
expect(style.textContent.indexOf(list[i][1]) > -1).toBe(true)
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function mockSSRTags (list, parentId) {
|
|
78
|
+
list.forEach((item, i) => {
|
|
79
|
+
const style = document.createElement('style')
|
|
80
|
+
style.setAttribute('data-vue-ssr-id', `${parentId}:${i}`)
|
|
81
|
+
style.textContent = item[1]
|
|
82
|
+
if (item[2]) {
|
|
83
|
+
style.setAttribute('media', item[2])
|
|
84
|
+
}
|
|
85
|
+
document.head.appendChild(style)
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function mockProdSSRTags (list, parentId) {
|
|
90
|
+
const style = document.createElement('style')
|
|
91
|
+
style.setAttribute('data-vue-ssr-id', list.map((item, i) => `${parentId}:${i}`).join(' '))
|
|
92
|
+
style.textContent = list.map(item => item[1]).join('\n')
|
|
93
|
+
document.head.appendChild(style)
|
|
94
|
+
}
|