Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1430745
toCSS.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
toCSS.php
View Options
<?php
/**
* @private
*/
class
Less_Visitor_toCSS
extends
Less_VisitorReplacing
{
private
$charset
;
public
function
__construct
()
{
parent
::
__construct
();
}
/**
* @param Less_Tree_Ruleset $root
*/
public
function
run
(
$root
)
{
return
$this
->
visitObj
(
$root
);
}
public
function
visitDeclaration
(
$declNode
)
{
if
(
$declNode
->
variable
)
{
return
[];
}
return
$declNode
;
}
public
function
visitMixinDefinition
(
$mixinNode
)
{
// mixin definitions do not get eval'd - this means they keep state
// so we have to clear that state here so it isn't used if toCSS is called twice
$mixinNode
->
frames
=
[];
return
[];
}
public
function
visitExtend
()
{
return
[];
}
public
function
visitComment
(
$commentNode
)
{
if
(
$commentNode
->
isSilent
()
)
{
return
[];
}
return
$commentNode
;
}
public
function
visitMedia
(
$mediaNode
,
&
$visitDeeper
)
{
$mediaNode
->
accept
(
$this
);
$visitDeeper
=
false
;
if
(
!
$mediaNode
->
rules
)
{
return
[];
}
return
$mediaNode
;
}
public
function
visitAtRule
(
$atRuleNode
,
&
$visitDeeper
)
{
if
(
$atRuleNode
->
name
===
'@charset'
)
{
if
(
!
$atRuleNode
->
getIsReferenced
()
)
{
return
;
}
if
(
isset
(
$this
->
charset
)
&&
$this
->
charset
)
{
// NOTE: Skip debugInfo handling (not implemented)
return
;
}
$this
->
charset
=
true
;
}
if
(
$atRuleNode
->
rules
)
{
self
::
_mergeRules
(
$atRuleNode
->
rules
[
0
]->
rules
);
// process childs
$atRuleNode
->
accept
(
$this
);
$visitDeeper
=
false
;
// the directive was directly referenced and therefore needs to be shown in the output
if
(
$atRuleNode
->
getIsReferenced
()
)
{
return
$atRuleNode
;
}
if
(
!
$atRuleNode
->
rules
)
{
return
;
}
if
(
$this
->
hasVisibleChild
(
$atRuleNode
)
)
{
// marking as referenced in case the directive is stored inside another directive
$atRuleNode
->
markReferenced
();
return
$atRuleNode
;
}
// The directive was not directly referenced and does not contain anything that
//was referenced. Therefore it must not be shown in output.
return
;
}
else
{
if
(
!
$atRuleNode
->
getIsReferenced
()
)
{
return
;
}
}
return
$atRuleNode
;
}
public
function
checkPropertiesInRoot
(
$rulesetNode
)
{
if
(
!
$rulesetNode
->
firstRoot
)
{
return
;
}
foreach
(
$rulesetNode
->
rules
as
$ruleNode
)
{
if
(
$ruleNode
instanceof
Less_Tree_Declaration
&&
!
$ruleNode
->
variable
)
{
$msg
=
"properties must be inside selector blocks, they cannot be in the root. Index "
.
$ruleNode
->
index
.
(
$ruleNode
->
currentFileInfo
?
' Filename: '
.
$ruleNode
->
currentFileInfo
[
'filename'
]
:
null
);
throw
new
Less_Exception_Compiler
(
$msg
);
}
}
}
public
function
visitRuleset
(
$rulesetNode
,
&
$visitDeeper
)
{
$visitDeeper
=
false
;
$this
->
checkPropertiesInRoot
(
$rulesetNode
);
if
(
$rulesetNode
->
root
)
{
return
$this
->
visitRulesetRoot
(
$rulesetNode
);
}
$rulesets
=
[];
$rulesetNode
->
paths
=
$this
->
visitRulesetPaths
(
$rulesetNode
);
// Compile rules and rulesets
$nodeRuleCnt
=
$rulesetNode
->
rules
?
count
(
$rulesetNode
->
rules
)
:
0
;
for
(
$i
=
0
;
$i
<
$nodeRuleCnt
;
)
{
$rule
=
$rulesetNode
->
rules
[
$i
];
if
(
property_exists
(
$rule
,
'rules'
)
)
{
// visit because we are moving them out from being a child
$rulesets
[]
=
$this
->
visitObj
(
$rule
);
array_splice
(
$rulesetNode
->
rules
,
$i
,
1
);
$nodeRuleCnt
--;
continue
;
}
$i
++;
}
// accept the visitor to remove rules and refactor itself
// then we can decide now whether we want it or not
if
(
$nodeRuleCnt
>
0
)
{
$rulesetNode
->
accept
(
$this
);
if
(
$rulesetNode
->
rules
)
{
if
(
count
(
$rulesetNode
->
rules
)
>
1
)
{
self
::
_mergeRules
(
$rulesetNode
->
rules
);
$this
->
_removeDuplicateRules
(
$rulesetNode
->
rules
);
}
// now decide whether we keep the ruleset
if
(
$rulesetNode
->
paths
)
{
// array_unshift($rulesets, $rulesetNode);
array_splice
(
$rulesets
,
0
,
0
,
[
$rulesetNode
]
);
}
}
}
if
(
count
(
$rulesets
)
===
1
)
{
return
$rulesets
[
0
];
}
return
$rulesets
;
}
public
function
visitAnonymous
(
$anonymousNode
)
{
if
(
!
$anonymousNode
->
getIsReferenced
()
)
{
return
;
}
$anonymousNode
->
accept
(
$this
);
return
$anonymousNode
;
}
public
function
visitImport
(
$importNode
)
{
if
(
isset
(
$importNode
->
path
->
currentFileInfo
[
"reference"
]
)
&&
$importNode
->
css
)
{
return
;
}
return
$importNode
;
}
/**
* Helper function for visitiRuleset
*
* return array|Less_Tree_Ruleset
*/
private
function
visitRulesetRoot
(
$rulesetNode
)
{
$rulesetNode
->
accept
(
$this
);
if
(
$rulesetNode
->
firstRoot
||
$rulesetNode
->
rules
)
{
return
$rulesetNode
;
}
return
[];
}
/**
* Helper function for visitRuleset()
*
* @return array
*/
private
function
visitRulesetPaths
(
$rulesetNode
)
{
$paths
=
[];
foreach
(
$rulesetNode
->
paths
as
$p
)
{
if
(
$p
[
0
]->
elements
[
0
]->
combinator
===
' '
)
{
$p
[
0
]->
elements
[
0
]->
combinator
=
''
;
}
foreach
(
$p
as
$pi
)
{
if
(
$pi
->
getIsReferenced
()
&&
$pi
->
getIsOutput
()
)
{
$paths
[]
=
$p
;
break
;
}
}
}
return
$paths
;
}
protected
function
_removeDuplicateRules
(
&
$rules
)
{
// remove duplicates
$ruleCache
=
[];
for
(
$i
=
count
(
$rules
)
-
1
;
$i
>=
0
;
$i
--
)
{
$rule
=
$rules
[
$i
];
if
(
$rule
instanceof
Less_Tree_Declaration
||
$rule
instanceof
Less_Tree_NameValue
)
{
if
(
!
isset
(
$ruleCache
[
$rule
->
name
]
)
)
{
$ruleCache
[
$rule
->
name
]
=
$rule
;
}
else
{
$ruleList
=&
$ruleCache
[
$rule
->
name
];
if
(
$ruleList
instanceof
Less_Tree_Declaration
||
$ruleList
instanceof
Less_Tree_NameValue
)
{
$ruleList
=
$ruleCache
[
$rule
->
name
]
=
[
$ruleCache
[
$rule
->
name
]->
toCSS
()
];
}
$ruleCSS
=
$rule
->
toCSS
();
if
(
in_array
(
$ruleCSS
,
$ruleList
)
)
{
array_splice
(
$rules
,
$i
,
1
);
}
else
{
$ruleList
[]
=
$ruleCSS
;
}
}
}
}
}
public
static
function
_mergeRules
(
&
$rules
)
{
$groups
=
[];
// obj($rules);
$rules_len
=
count
(
$rules
);
for
(
$i
=
0
;
$i
<
$rules_len
;
$i
++
)
{
$rule
=
$rules
[
$i
];
if
(
(
$rule
instanceof
Less_Tree_Declaration
)
&&
$rule
->
merge
)
{
$key
=
$rule
->
name
;
if
(
$rule
->
important
)
{
$key
.=
',!'
;
}
if
(
!
isset
(
$groups
[
$key
]
)
)
{
$groups
[
$key
]
=
[];
}
else
{
array_splice
(
$rules
,
$i
--,
1
);
$rules_len
--;
}
$groups
[
$key
][]
=
$rule
;
}
}
foreach
(
$groups
as
$parts
)
{
if
(
count
(
$parts
)
>
1
)
{
$rule
=
$parts
[
0
];
$spacedGroups
=
[];
$lastSpacedGroup
=
[];
$parts_mapped
=
[];
foreach
(
$parts
as
$p
)
{
if
(
$p
->
merge
===
'+'
)
{
if
(
$lastSpacedGroup
)
{
$spacedGroups
[]
=
self
::
toExpression
(
$lastSpacedGroup
);
}
$lastSpacedGroup
=
[];
}
$lastSpacedGroup
[]
=
$p
;
}
$spacedGroups
[]
=
self
::
toExpression
(
$lastSpacedGroup
);
$rule
->
value
=
self
::
toValue
(
$spacedGroups
);
}
}
}
public
static
function
toExpression
(
$values
)
{
$mapped
=
[];
foreach
(
$values
as
$p
)
{
$mapped
[]
=
$p
->
value
;
}
return
new
Less_Tree_Expression
(
$mapped
);
}
public
static
function
toValue
(
$values
)
{
// return new Less_Tree_Value($values); ??
$mapped
=
[];
foreach
(
$values
as
$p
)
{
$mapped
[]
=
$p
;
}
return
new
Less_Tree_Value
(
$mapped
);
}
public
function
hasVisibleChild
(
$atRuleNode
)
{
// prepare list of childs
$rule
=
$bodyRules
=
$atRuleNode
->
rules
;
// if there is only one nested ruleset and that one has no path, then it is
//just fake ruleset that got not replaced and we need to look inside it to
//get real childs
if
(
count
(
$bodyRules
)
===
1
&&
(
!
$bodyRules
[
0
]->
paths
||
count
(
$bodyRules
[
0
]->
paths
)
===
0
)
)
{
$bodyRules
=
$bodyRules
[
0
]->
rules
;
}
foreach
(
$bodyRules
as
$rule
)
{
if
(
method_exists
(
$rule
,
'getIsReferenced'
)
&&
$rule
->
getIsReferenced
()
)
{
// the directive contains something that was referenced (likely by extend)
//therefore it needs to be shown in output too
return
true
;
}
}
return
false
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 19:29 (4 h, 3 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
13/4e/4ca860dbc7554b704a3ab284c6e1
Default Alt Text
toCSS.php (7 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment