Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F101468993
lazy-result.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Feb 10, 18:29
Size
13 KB
Mime Type
text/x-c++
Expires
Wed, Feb 12, 18:29 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
24154905
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
lazy-result.js
View Options
'use strict'
let
{
isClean
,
my
}
=
require
(
'./symbols'
)
let
MapGenerator
=
require
(
'./map-generator'
)
let
stringify
=
require
(
'./stringify'
)
let
Container
=
require
(
'./container'
)
let
Document
=
require
(
'./document'
)
let
warnOnce
=
require
(
'./warn-once'
)
let
Result
=
require
(
'./result'
)
let
parse
=
require
(
'./parse'
)
let
Root
=
require
(
'./root'
)
const
TYPE_TO_CLASS_NAME
=
{
document
:
'Document'
,
root
:
'Root'
,
atrule
:
'AtRule'
,
rule
:
'Rule'
,
decl
:
'Declaration'
,
comment
:
'Comment'
}
const
PLUGIN_PROPS
=
{
postcssPlugin
:
true
,
prepare
:
true
,
Once
:
true
,
Document
:
true
,
Root
:
true
,
Declaration
:
true
,
Rule
:
true
,
AtRule
:
true
,
Comment
:
true
,
DeclarationExit
:
true
,
RuleExit
:
true
,
AtRuleExit
:
true
,
CommentExit
:
true
,
RootExit
:
true
,
DocumentExit
:
true
,
OnceExit
:
true
}
const
NOT_VISITORS
=
{
postcssPlugin
:
true
,
prepare
:
true
,
Once
:
true
}
const
CHILDREN
=
0
function
isPromise
(
obj
)
{
return
typeof
obj
===
'object'
&&
typeof
obj
.
then
===
'function'
}
function
getEvents
(
node
)
{
let
key
=
false
let
type
=
TYPE_TO_CLASS_NAME
[
node
.
type
]
if
(
node
.
type
===
'decl'
)
{
key
=
node
.
prop
.
toLowerCase
()
}
else
if
(
node
.
type
===
'atrule'
)
{
key
=
node
.
name
.
toLowerCase
()
}
if
(
key
&&
node
.
append
)
{
return
[
type
,
type
+
'-'
+
key
,
CHILDREN
,
type
+
'Exit'
,
type
+
'Exit-'
+
key
]
}
else
if
(
key
)
{
return
[
type
,
type
+
'-'
+
key
,
type
+
'Exit'
,
type
+
'Exit-'
+
key
]
}
else
if
(
node
.
append
)
{
return
[
type
,
CHILDREN
,
type
+
'Exit'
]
}
else
{
return
[
type
,
type
+
'Exit'
]
}
}
function
toStack
(
node
)
{
let
events
if
(
node
.
type
===
'document'
)
{
events
=
[
'Document'
,
CHILDREN
,
'DocumentExit'
]
}
else
if
(
node
.
type
===
'root'
)
{
events
=
[
'Root'
,
CHILDREN
,
'RootExit'
]
}
else
{
events
=
getEvents
(
node
)
}
return
{
node
,
events
,
eventIndex
:
0
,
visitors
:
[],
visitorIndex
:
0
,
iterator
:
0
}
}
function
cleanMarks
(
node
)
{
node
[
isClean
]
=
false
if
(
node
.
nodes
)
node
.
nodes
.
forEach
(
i
=>
cleanMarks
(
i
))
return
node
}
let
postcss
=
{}
class
LazyResult
{
constructor
(
processor
,
css
,
opts
)
{
this
.
stringified
=
false
this
.
processed
=
false
let
root
if
(
typeof
css
===
'object'
&&
css
!==
null
&&
(
css
.
type
===
'root'
||
css
.
type
===
'document'
)
)
{
root
=
cleanMarks
(
css
)
}
else
if
(
css
instanceof
LazyResult
||
css
instanceof
Result
)
{
root
=
cleanMarks
(
css
.
root
)
if
(
css
.
map
)
{
if
(
typeof
opts
.
map
===
'undefined'
)
opts
.
map
=
{}
if
(
!
opts
.
map
.
inline
)
opts
.
map
.
inline
=
false
opts
.
map
.
prev
=
css
.
map
}
}
else
{
let
parser
=
parse
if
(
opts
.
syntax
)
parser
=
opts
.
syntax
.
parse
if
(
opts
.
parser
)
parser
=
opts
.
parser
if
(
parser
.
parse
)
parser
=
parser
.
parse
try
{
root
=
parser
(
css
,
opts
)
}
catch
(
error
)
{
this
.
processed
=
true
this
.
error
=
error
}
if
(
root
&&
!
root
[
my
])
{
/* c8 ignore next 2 */
Container
.
rebuild
(
root
)
}
}
this
.
result
=
new
Result
(
processor
,
root
,
opts
)
this
.
helpers
=
{
...
postcss
,
result
:
this
.
result
,
postcss
}
this
.
plugins
=
this
.
processor
.
plugins
.
map
(
plugin
=>
{
if
(
typeof
plugin
===
'object'
&&
plugin
.
prepare
)
{
return
{
...
plugin
,
...
plugin
.
prepare
(
this
.
result
)
}
}
else
{
return
plugin
}
})
}
get
[
Symbol
.
toStringTag
]()
{
return
'LazyResult'
}
get
processor
()
{
return
this
.
result
.
processor
}
get
opts
()
{
return
this
.
result
.
opts
}
get
css
()
{
return
this
.
stringify
().
css
}
get
content
()
{
return
this
.
stringify
().
content
}
get
map
()
{
return
this
.
stringify
().
map
}
get
root
()
{
return
this
.
sync
().
root
}
get
messages
()
{
return
this
.
sync
().
messages
}
warnings
()
{
return
this
.
sync
().
warnings
()
}
toString
()
{
return
this
.
css
}
then
(
onFulfilled
,
onRejected
)
{
if
(
process
.
env
.
NODE_ENV
!==
'production'
)
{
if
(
!
(
'from'
in
this
.
opts
))
{
warnOnce
(
'Without `from` option PostCSS could generate wrong source map '
+
'and will not find Browserslist config. Set it to CSS file path '
+
'or to `undefined` to prevent this warning.'
)
}
}
return
this
.
async
().
then
(
onFulfilled
,
onRejected
)
}
catch
(
onRejected
)
{
return
this
.
async
().
catch
(
onRejected
)
}
finally
(
onFinally
)
{
return
this
.
async
().
then
(
onFinally
,
onFinally
)
}
async
()
{
if
(
this
.
error
)
return
Promise
.
reject
(
this
.
error
)
if
(
this
.
processed
)
return
Promise
.
resolve
(
this
.
result
)
if
(
!
this
.
processing
)
{
this
.
processing
=
this
.
runAsync
()
}
return
this
.
processing
}
sync
()
{
if
(
this
.
error
)
throw
this
.
error
if
(
this
.
processed
)
return
this
.
result
this
.
processed
=
true
if
(
this
.
processing
)
{
throw
this
.
getAsyncError
()
}
for
(
let
plugin
of
this
.
plugins
)
{
let
promise
=
this
.
runOnRoot
(
plugin
)
if
(
isPromise
(
promise
))
{
throw
this
.
getAsyncError
()
}
}
this
.
prepareVisitors
()
if
(
this
.
hasListener
)
{
let
root
=
this
.
result
.
root
while
(
!
root
[
isClean
])
{
root
[
isClean
]
=
true
this
.
walkSync
(
root
)
}
if
(
this
.
listeners
.
OnceExit
)
{
if
(
root
.
type
===
'document'
)
{
for
(
let
subRoot
of
root
.
nodes
)
{
this
.
visitSync
(
this
.
listeners
.
OnceExit
,
subRoot
)
}
}
else
{
this
.
visitSync
(
this
.
listeners
.
OnceExit
,
root
)
}
}
}
return
this
.
result
}
stringify
()
{
if
(
this
.
error
)
throw
this
.
error
if
(
this
.
stringified
)
return
this
.
result
this
.
stringified
=
true
this
.
sync
()
let
opts
=
this
.
result
.
opts
let
str
=
stringify
if
(
opts
.
syntax
)
str
=
opts
.
syntax
.
stringify
if
(
opts
.
stringifier
)
str
=
opts
.
stringifier
if
(
str
.
stringify
)
str
=
str
.
stringify
let
map
=
new
MapGenerator
(
str
,
this
.
result
.
root
,
this
.
result
.
opts
)
let
data
=
map
.
generate
()
this
.
result
.
css
=
data
[
0
]
this
.
result
.
map
=
data
[
1
]
return
this
.
result
}
walkSync
(
node
)
{
node
[
isClean
]
=
true
let
events
=
getEvents
(
node
)
for
(
let
event
of
events
)
{
if
(
event
===
CHILDREN
)
{
if
(
node
.
nodes
)
{
node
.
each
(
child
=>
{
if
(
!
child
[
isClean
])
this
.
walkSync
(
child
)
})
}
}
else
{
let
visitors
=
this
.
listeners
[
event
]
if
(
visitors
)
{
if
(
this
.
visitSync
(
visitors
,
node
.
toProxy
()))
return
}
}
}
}
visitSync
(
visitors
,
node
)
{
for
(
let
[
plugin
,
visitor
]
of
visitors
)
{
this
.
result
.
lastPlugin
=
plugin
let
promise
try
{
promise
=
visitor
(
node
,
this
.
helpers
)
}
catch
(
e
)
{
throw
this
.
handleError
(
e
,
node
.
proxyOf
)
}
if
(
node
.
type
!==
'root'
&&
node
.
type
!==
'document'
&&
!
node
.
parent
)
{
return
true
}
if
(
isPromise
(
promise
))
{
throw
this
.
getAsyncError
()
}
}
}
runOnRoot
(
plugin
)
{
this
.
result
.
lastPlugin
=
plugin
try
{
if
(
typeof
plugin
===
'object'
&&
plugin
.
Once
)
{
if
(
this
.
result
.
root
.
type
===
'document'
)
{
let
roots
=
this
.
result
.
root
.
nodes
.
map
(
root
=>
plugin
.
Once
(
root
,
this
.
helpers
)
)
if
(
isPromise
(
roots
[
0
]))
{
return
Promise
.
all
(
roots
)
}
return
roots
}
return
plugin
.
Once
(
this
.
result
.
root
,
this
.
helpers
)
}
else
if
(
typeof
plugin
===
'function'
)
{
return
plugin
(
this
.
result
.
root
,
this
.
result
)
}
}
catch
(
error
)
{
throw
this
.
handleError
(
error
)
}
}
getAsyncError
()
{
throw
new
Error
(
'Use process(css).then(cb) to work with async plugins'
)
}
handleError
(
error
,
node
)
{
let
plugin
=
this
.
result
.
lastPlugin
try
{
if
(
node
)
node
.
addToError
(
error
)
this
.
error
=
error
if
(
error
.
name
===
'CssSyntaxError'
&&
!
error
.
plugin
)
{
error
.
plugin
=
plugin
.
postcssPlugin
error
.
setMessage
()
}
else
if
(
plugin
.
postcssVersion
)
{
if
(
process
.
env
.
NODE_ENV
!==
'production'
)
{
let
pluginName
=
plugin
.
postcssPlugin
let
pluginVer
=
plugin
.
postcssVersion
let
runtimeVer
=
this
.
result
.
processor
.
version
let
a
=
pluginVer
.
split
(
'.'
)
let
b
=
runtimeVer
.
split
(
'.'
)
if
(
a
[
0
]
!==
b
[
0
]
||
parseInt
(
a
[
1
])
>
parseInt
(
b
[
1
]))
{
// eslint-disable-next-line no-console
console
.
error
(
'Unknown error from PostCSS plugin. Your current PostCSS '
+
'version is '
+
runtimeVer
+
', but '
+
pluginName
+
' uses '
+
pluginVer
+
'. Perhaps this is the source of the error below.'
)
}
}
}
}
catch
(
err
)
{
/* c8 ignore next 3 */
// eslint-disable-next-line no-console
if
(
console
&&
console
.
error
)
console
.
error
(
err
)
}
return
error
}
async
runAsync
()
{
this
.
plugin
=
0
for
(
let
i
=
0
;
i
<
this
.
plugins
.
length
;
i
++
)
{
let
plugin
=
this
.
plugins
[
i
]
let
promise
=
this
.
runOnRoot
(
plugin
)
if
(
isPromise
(
promise
))
{
try
{
await
promise
}
catch
(
error
)
{
throw
this
.
handleError
(
error
)
}
}
}
this
.
prepareVisitors
()
if
(
this
.
hasListener
)
{
let
root
=
this
.
result
.
root
while
(
!
root
[
isClean
])
{
root
[
isClean
]
=
true
let
stack
=
[
toStack
(
root
)]
while
(
stack
.
length
>
0
)
{
let
promise
=
this
.
visitTick
(
stack
)
if
(
isPromise
(
promise
))
{
try
{
await
promise
}
catch
(
e
)
{
let
node
=
stack
[
stack
.
length
-
1
].
node
throw
this
.
handleError
(
e
,
node
)
}
}
}
}
if
(
this
.
listeners
.
OnceExit
)
{
for
(
let
[
plugin
,
visitor
]
of
this
.
listeners
.
OnceExit
)
{
this
.
result
.
lastPlugin
=
plugin
try
{
if
(
root
.
type
===
'document'
)
{
let
roots
=
root
.
nodes
.
map
(
subRoot
=>
visitor
(
subRoot
,
this
.
helpers
)
)
await
Promise
.
all
(
roots
)
}
else
{
await
visitor
(
root
,
this
.
helpers
)
}
}
catch
(
e
)
{
throw
this
.
handleError
(
e
)
}
}
}
}
this
.
processed
=
true
return
this
.
stringify
()
}
prepareVisitors
()
{
this
.
listeners
=
{}
let
add
=
(
plugin
,
type
,
cb
)
=>
{
if
(
!
this
.
listeners
[
type
])
this
.
listeners
[
type
]
=
[]
this
.
listeners
[
type
].
push
([
plugin
,
cb
])
}
for
(
let
plugin
of
this
.
plugins
)
{
if
(
typeof
plugin
===
'object'
)
{
for
(
let
event
in
plugin
)
{
if
(
!
PLUGIN_PROPS
[
event
]
&&
/^[A-Z]/
.
test
(
event
))
{
throw
new
Error
(
`
Unknown
event
$
{
event
}
in
$
{
plugin
.
postcssPlugin
}.
`
+
`
Try
to
update
PostCSS
(
$
{
this
.
processor
.
version
}
now
).
`
)
}
if
(
!
NOT_VISITORS
[
event
])
{
if
(
typeof
plugin
[
event
]
===
'object'
)
{
for
(
let
filter
in
plugin
[
event
])
{
if
(
filter
===
'*'
)
{
add
(
plugin
,
event
,
plugin
[
event
][
filter
])
}
else
{
add
(
plugin
,
event
+
'-'
+
filter
.
toLowerCase
(),
plugin
[
event
][
filter
]
)
}
}
}
else
if
(
typeof
plugin
[
event
]
===
'function'
)
{
add
(
plugin
,
event
,
plugin
[
event
])
}
}
}
}
}
this
.
hasListener
=
Object
.
keys
(
this
.
listeners
).
length
>
0
}
visitTick
(
stack
)
{
let
visit
=
stack
[
stack
.
length
-
1
]
let
{
node
,
visitors
}
=
visit
if
(
node
.
type
!==
'root'
&&
node
.
type
!==
'document'
&&
!
node
.
parent
)
{
stack
.
pop
()
return
}
if
(
visitors
.
length
>
0
&&
visit
.
visitorIndex
<
visitors
.
length
)
{
let
[
plugin
,
visitor
]
=
visitors
[
visit
.
visitorIndex
]
visit
.
visitorIndex
+=
1
if
(
visit
.
visitorIndex
===
visitors
.
length
)
{
visit
.
visitors
=
[]
visit
.
visitorIndex
=
0
}
this
.
result
.
lastPlugin
=
plugin
try
{
return
visitor
(
node
.
toProxy
(),
this
.
helpers
)
}
catch
(
e
)
{
throw
this
.
handleError
(
e
,
node
)
}
}
if
(
visit
.
iterator
!==
0
)
{
let
iterator
=
visit
.
iterator
let
child
while
((
child
=
node
.
nodes
[
node
.
indexes
[
iterator
]]))
{
node
.
indexes
[
iterator
]
+=
1
if
(
!
child
[
isClean
])
{
child
[
isClean
]
=
true
stack
.
push
(
toStack
(
child
))
return
}
}
visit
.
iterator
=
0
delete
node
.
indexes
[
iterator
]
}
let
events
=
visit
.
events
while
(
visit
.
eventIndex
<
events
.
length
)
{
let
event
=
events
[
visit
.
eventIndex
]
visit
.
eventIndex
+=
1
if
(
event
===
CHILDREN
)
{
if
(
node
.
nodes
&&
node
.
nodes
.
length
)
{
node
[
isClean
]
=
true
visit
.
iterator
=
node
.
getIterator
()
}
return
}
else
if
(
this
.
listeners
[
event
])
{
visit
.
visitors
=
this
.
listeners
[
event
]
return
}
}
stack
.
pop
()
}
}
LazyResult
.
registerPostcss
=
dependant
=>
{
postcss
=
dependant
}
module
.
exports
=
LazyResult
LazyResult
.
default
=
LazyResult
Root
.
registerLazyResult
(
LazyResult
)
Document
.
registerLazyResult
(
LazyResult
)
Event Timeline
Log In to Comment