Differences Between: [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Autoprefixer. 19 * 20 * This autoprefixer has been developed to satisfy the basic needs of the 21 * theme Boost when working with Bootstrap 4 alpha. We do not recommend 22 * that this tool is shared, nor used outside of this theme. 23 * 24 * @package theme_boost 25 * @copyright 2016 Frédéric Massart - FMCorz.net 26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 27 */ 28 29 namespace theme_boost; 30 defined('MOODLE_INTERNAL') || die(); 31 32 use Sabberworm\CSS\CSSList\CSSList; 33 use Sabberworm\CSS\CSSList\Document; 34 use Sabberworm\CSS\CSSList\KeyFrame; 35 use Sabberworm\CSS\OutputFormat; 36 use Sabberworm\CSS\Parser; 37 use Sabberworm\CSS\Property\AtRule; 38 use Sabberworm\CSS\Property\Selector; 39 use Sabberworm\CSS\Rule\Rule; 40 use Sabberworm\CSS\RuleSet\AtRuleSet; 41 use Sabberworm\CSS\RuleSet\DeclarationBlock; 42 use Sabberworm\CSS\RuleSet\RuleSet; 43 use Sabberworm\CSS\Settings; 44 use Sabberworm\CSS\Value\CSSFunction; 45 use Sabberworm\CSS\Value\CSSString; 46 use Sabberworm\CSS\Value\PrimitiveValue; 47 use Sabberworm\CSS\Value\RuleValueList; 48 use Sabberworm\CSS\Value\Size; 49 use Sabberworm\CSS\Value\ValueList; 50 51 52 /** 53 * Autoprefixer class. 54 * 55 * Very basic implementation covering simple needs for Bootstrap 4. 56 * 57 * @package theme_boost 58 * @copyright 2016 Frédéric Massart - FMCorz.net 59 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 60 */ 61 class autoprefixer { 62 63 /** @var object The CSS tree. */ 64 protected $tree; 65 66 /** @var string Pseudo classes regex. */ 67 protected $pseudosregex; 68 69 /** @var array At rules prefixes. */ 70 protected static $atrules = [ 71 'keyframes' => ['-webkit-', '-o-'] 72 ]; 73 74 /** @var array Pseudo classes prefixes. */ 75 protected static $pseudos = [ 76 '::placeholder' => ['::-webkit-input-placeholder', '::-moz-placeholder', ':-ms-input-placeholder'] 77 ]; 78 79 /** @var array Rule properties prefixes. */ 80 protected static $rules = [ 81 'animation' => ['-webkit-'], 82 'appearance' => ['-webkit-', '-moz-'], 83 'backface-visibility' => ['-webkit-'], 84 'box-sizing' => ['-webkit-'], 85 'box-shadow' => ['-webkit-'], 86 'background-clip' => ['-webkit-'], 87 'background-size' => ['-webkit-'], 88 'box-shadow' => ['-webkit-'], 89 'column-count' => ['-webkit-', '-moz-'], 90 'column-gap' => ['-webkit-', '-moz-'], 91 'perspective' => ['-webkit-'], 92 'touch-action' => ['-ms-'], 93 'transform' => ['-webkit-', '-moz-', '-ms-', '-o-'], 94 'transition' => ['-webkit-', '-o-'], 95 'transition-timing-function' => ['-webkit-', '-o-'], 96 'transition-duration' => ['-webkit-', '-o-'], 97 'transition-property' => ['-webkit-', '-o-'], 98 'user-select' => ['-webkit-', '-moz-', '-ms-'], 99 ]; 100 101 /** 102 * Constructor. 103 * 104 * @param Document $tree The CSS tree. 105 */ 106 public function __construct(Document $tree) { 107 debugging('theme_boost\autoprefixer() is deprecated. Required prefixes for Bootstrap ' . 108 'are now in theme/boost/scss/moodle/prefixes.scss', DEBUG_DEVELOPER); 109 $this->tree = $tree; 110 111 $pseudos = array_map(function($pseudo) { 112 return '(' . preg_quote($pseudo) . ')'; 113 }, array_keys(self::$pseudos)); 114 $this->pseudosregex = '(' . implode('|', $pseudos) . ')'; 115 } 116 117 /** 118 * Manipulate an array of rules to adapt their values. 119 * 120 * @param array $rules The rules. 121 * @return New array of rules. 122 */ 123 protected function manipulateRuleValues(array $rules) { 124 $finalrules = []; 125 126 foreach ($rules as $rule) { 127 $property = $rule->getRule(); 128 $value = $rule->getValue(); 129 130 if ($property === 'position' && $value === 'sticky') { 131 $newrule = clone $rule; 132 $newrule->setValue('-webkit-sticky'); 133 $finalrules[] = $newrule; 134 135 } else if ($property === 'background-image' && 136 $value instanceof CSSFunction && 137 $value->getName() === 'linear-gradient') { 138 139 foreach (['-webkit-', '-o-'] as $prefix) { 140 $newfunction = clone $value; 141 $newfunction->setName($prefix . $value->getName()); 142 $newrule = clone $rule; 143 $newrule->setValue($newfunction); 144 $finalrules[] = $newrule; 145 } 146 } 147 148 $finalrules[] = $rule; 149 } 150 151 return $finalrules; 152 } 153 154 /** 155 * Prefix all the things! 156 */ 157 public function prefix() { 158 $this->processBlock($this->tree); 159 } 160 161 /** 162 * Process block. 163 * 164 * @param object $block A block. 165 * @param object $parent The parent of the block. 166 */ 167 protected function processBlock($block) { 168 foreach ($block->getContents() as $node) { 169 if ($node instanceof AtRule) { 170 171 $name = $node->atRuleName(); 172 if (isset(self::$atrules[$name])) { 173 foreach (self::$atrules[$name] as $prefix) { 174 $newname = $prefix . $name; 175 $newnode = clone $node; 176 177 if ($node instanceof KeyFrame) { 178 $newnode->setVendorKeyFrame($newname); 179 $block->insert($newnode, $node); 180 181 } else { 182 debugging('Unhandled atRule prefixing.', DEBUG_DEVELOPER); 183 } 184 } 185 } 186 } 187 188 if ($node instanceof CSSList) { 189 $this->processBlock($node); 190 191 } else if ($node instanceof RuleSet) { 192 $this->processDeclaration($node, $block); 193 } 194 } 195 } 196 197 /** 198 * Process declaration. 199 * 200 * @param object $node The declaration block. 201 * @param object $parent The parent. 202 */ 203 protected function processDeclaration($node, $parent) { 204 $rules = []; 205 206 foreach ($node->getRules() as $key => $rule) { 207 $name = $rule->getRule(); 208 $seen[$name] = true; 209 210 if (!isset(self::$rules[$name])) { 211 $rules[] = $rule; 212 continue; 213 } 214 215 foreach (self::$rules[$name] as $prefix) { 216 $newname = $prefix . $name; 217 if (isset($seen[$newname])) { 218 continue; 219 } 220 $newrule = clone $rule; 221 $newrule->setRule($newname); 222 $rules[] = $newrule; 223 } 224 225 $rules[] = $rule; 226 } 227 228 $node->setRules($this->manipulateRuleValues($rules)); 229 230 if ($node instanceof DeclarationBlock) { 231 $selectors = $node->getSelectors(); 232 foreach ($selectors as $key => $selector) { 233 234 $matches = []; 235 if (preg_match($this->pseudosregex, $selector->getSelector(), $matches)) { 236 237 $newnode = clone $node; 238 foreach (self::$pseudos[$matches[1]] as $newpseudo) { 239 $newselector = new Selector(str_replace($matches[1], $newpseudo, $selector->getSelector())); 240 $selectors[$key] = $newselector; 241 $newnode = clone $node; 242 $newnode->setSelectors($selectors); 243 $parent->insert($newnode, $node); 244 } 245 246 // We're only expecting one affected pseudo class per block. 247 break; 248 } 249 } 250 } 251 } 252 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body