[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Defines allowed CSS attributes and what their values are. 5 * @see HTMLPurifier_HTMLDefinition 6 */ 7 class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition 8 { 9 10 public $type = 'CSS'; 11 12 /** 13 * Assoc array of attribute name to definition object. 14 * @type HTMLPurifier_AttrDef[] 15 */ 16 public $info = array(); 17 18 /** 19 * Constructs the info array. The meat of this class. 20 * @param HTMLPurifier_Config $config 21 */ 22 protected function doSetup($config) 23 { 24 $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( 25 array('left', 'right', 'center', 'justify'), 26 false 27 ); 28 29 $border_style = 30 $this->info['border-bottom-style'] = 31 $this->info['border-right-style'] = 32 $this->info['border-left-style'] = 33 $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( 34 array( 35 'none', 36 'hidden', 37 'dotted', 38 'dashed', 39 'solid', 40 'double', 41 'groove', 42 'ridge', 43 'inset', 44 'outset' 45 ), 46 false 47 ); 48 49 $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); 50 51 $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( 52 array('none', 'left', 'right', 'both'), 53 false 54 ); 55 $this->info['float'] = new HTMLPurifier_AttrDef_Enum( 56 array('none', 'left', 'right'), 57 false 58 ); 59 $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( 60 array('normal', 'italic', 'oblique'), 61 false 62 ); 63 $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( 64 array('normal', 'small-caps'), 65 false 66 ); 67 68 $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( 69 array( 70 new HTMLPurifier_AttrDef_Enum(array('none')), 71 new HTMLPurifier_AttrDef_CSS_URI() 72 ) 73 ); 74 75 $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( 76 array('inside', 'outside'), 77 false 78 ); 79 $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( 80 array( 81 'disc', 82 'circle', 83 'square', 84 'decimal', 85 'lower-roman', 86 'upper-roman', 87 'lower-alpha', 88 'upper-alpha', 89 'none' 90 ), 91 false 92 ); 93 $this->info['list-style-image'] = $uri_or_none; 94 95 $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); 96 97 $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( 98 array('capitalize', 'uppercase', 'lowercase', 'none'), 99 false 100 ); 101 $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); 102 103 $this->info['background-image'] = $uri_or_none; 104 $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( 105 array('repeat', 'repeat-x', 'repeat-y', 'no-repeat') 106 ); 107 $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( 108 array('scroll', 'fixed') 109 ); 110 $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); 111 112 $border_color = 113 $this->info['border-top-color'] = 114 $this->info['border-bottom-color'] = 115 $this->info['border-left-color'] = 116 $this->info['border-right-color'] = 117 $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( 118 array( 119 new HTMLPurifier_AttrDef_Enum(array('transparent')), 120 new HTMLPurifier_AttrDef_CSS_Color() 121 ) 122 ); 123 124 $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); 125 126 $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); 127 128 $border_width = 129 $this->info['border-top-width'] = 130 $this->info['border-bottom-width'] = 131 $this->info['border-left-width'] = 132 $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( 133 array( 134 new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), 135 new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative 136 ) 137 ); 138 139 $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); 140 141 $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( 142 array( 143 new HTMLPurifier_AttrDef_Enum(array('normal')), 144 new HTMLPurifier_AttrDef_CSS_Length() 145 ) 146 ); 147 148 $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( 149 array( 150 new HTMLPurifier_AttrDef_Enum(array('normal')), 151 new HTMLPurifier_AttrDef_CSS_Length() 152 ) 153 ); 154 155 $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( 156 array( 157 new HTMLPurifier_AttrDef_Enum( 158 array( 159 'xx-small', 160 'x-small', 161 'small', 162 'medium', 163 'large', 164 'x-large', 165 'xx-large', 166 'larger', 167 'smaller' 168 ) 169 ), 170 new HTMLPurifier_AttrDef_CSS_Percentage(), 171 new HTMLPurifier_AttrDef_CSS_Length() 172 ) 173 ); 174 175 $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( 176 array( 177 new HTMLPurifier_AttrDef_Enum(array('normal')), 178 new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives 179 new HTMLPurifier_AttrDef_CSS_Length('0'), 180 new HTMLPurifier_AttrDef_CSS_Percentage(true) 181 ) 182 ); 183 184 $margin = 185 $this->info['margin-top'] = 186 $this->info['margin-bottom'] = 187 $this->info['margin-left'] = 188 $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( 189 array( 190 new HTMLPurifier_AttrDef_CSS_Length(), 191 new HTMLPurifier_AttrDef_CSS_Percentage(), 192 new HTMLPurifier_AttrDef_Enum(array('auto')) 193 ) 194 ); 195 196 $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); 197 198 // non-negative 199 $padding = 200 $this->info['padding-top'] = 201 $this->info['padding-bottom'] = 202 $this->info['padding-left'] = 203 $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( 204 array( 205 new HTMLPurifier_AttrDef_CSS_Length('0'), 206 new HTMLPurifier_AttrDef_CSS_Percentage(true) 207 ) 208 ); 209 210 $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); 211 212 $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( 213 array( 214 new HTMLPurifier_AttrDef_CSS_Length(), 215 new HTMLPurifier_AttrDef_CSS_Percentage() 216 ) 217 ); 218 219 $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( 220 array( 221 new HTMLPurifier_AttrDef_CSS_Length('0'), 222 new HTMLPurifier_AttrDef_CSS_Percentage(true), 223 new HTMLPurifier_AttrDef_Enum(array('auto')) 224 ) 225 ); 226 $max = $config->get('CSS.MaxImgLength'); 227 228 $this->info['width'] = 229 $this->info['height'] = 230 $max === null ? 231 $trusted_wh : 232 new HTMLPurifier_AttrDef_Switch( 233 'img', 234 // For img tags: 235 new HTMLPurifier_AttrDef_CSS_Composite( 236 array( 237 new HTMLPurifier_AttrDef_CSS_Length('0', $max), 238 new HTMLPurifier_AttrDef_Enum(array('auto')) 239 ) 240 ), 241 // For everyone else: 242 $trusted_wh 243 ); 244 245 $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); 246 247 $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); 248 249 // this could use specialized code 250 $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( 251 array( 252 'normal', 253 'bold', 254 'bolder', 255 'lighter', 256 '100', 257 '200', 258 '300', 259 '400', 260 '500', 261 '600', 262 '700', 263 '800', 264 '900' 265 ), 266 false 267 ); 268 269 // MUST be called after other font properties, as it references 270 // a CSSDefinition object 271 $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config); 272 273 // same here 274 $this->info['border'] = 275 $this->info['border-bottom'] = 276 $this->info['border-top'] = 277 $this->info['border-left'] = 278 $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); 279 280 $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( 281 array('collapse', 'separate') 282 ); 283 284 $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( 285 array('top', 'bottom') 286 ); 287 288 $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( 289 array('auto', 'fixed') 290 ); 291 292 $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( 293 array( 294 new HTMLPurifier_AttrDef_Enum( 295 array( 296 'baseline', 297 'sub', 298 'super', 299 'top', 300 'text-top', 301 'middle', 302 'bottom', 303 'text-bottom' 304 ) 305 ), 306 new HTMLPurifier_AttrDef_CSS_Length(), 307 new HTMLPurifier_AttrDef_CSS_Percentage() 308 ) 309 ); 310 311 $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); 312 313 // These CSS properties don't work on many browsers, but we live 314 // in THE FUTURE! 315 $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( 316 array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') 317 ); 318 319 if ($config->get('CSS.Proprietary')) { 320 $this->doSetupProprietary($config); 321 } 322 323 if ($config->get('CSS.AllowTricky')) { 324 $this->doSetupTricky($config); 325 } 326 327 if ($config->get('CSS.Trusted')) { 328 $this->doSetupTrusted($config); 329 } 330 331 $allow_important = $config->get('CSS.AllowImportant'); 332 // wrap all attr-defs with decorator that handles !important 333 foreach ($this->info as $k => $v) { 334 $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); 335 } 336 337 $this->setupConfigStuff($config); 338 } 339 340 /** 341 * @param HTMLPurifier_Config $config 342 */ 343 protected function doSetupProprietary($config) 344 { 345 // Internet Explorer only scrollbar colors 346 $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 347 $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 348 $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 349 $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 350 $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 351 $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); 352 353 // technically not proprietary, but CSS3, and no one supports it 354 $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); 355 $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); 356 $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); 357 358 // only opacity, for now 359 $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); 360 361 // more CSS3 362 $this->info['page-break-after'] = 363 $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( 364 array( 365 'auto', 366 'always', 367 'avoid', 368 'left', 369 'right' 370 ) 371 ); 372 $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); 373 374 } 375 376 /** 377 * @param HTMLPurifier_Config $config 378 */ 379 protected function doSetupTricky($config) 380 { 381 $this->info['display'] = new HTMLPurifier_AttrDef_Enum( 382 array( 383 'inline', 384 'block', 385 'list-item', 386 'run-in', 387 'compact', 388 'marker', 389 'table', 390 'inline-block', 391 'inline-table', 392 'table-row-group', 393 'table-header-group', 394 'table-footer-group', 395 'table-row', 396 'table-column-group', 397 'table-column', 398 'table-cell', 399 'table-caption', 400 'none' 401 ) 402 ); 403 $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( 404 array('visible', 'hidden', 'collapse') 405 ); 406 $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); 407 } 408 409 /** 410 * @param HTMLPurifier_Config $config 411 */ 412 protected function doSetupTrusted($config) 413 { 414 $this->info['position'] = new HTMLPurifier_AttrDef_Enum( 415 array('static', 'relative', 'absolute', 'fixed') 416 ); 417 $this->info['top'] = 418 $this->info['left'] = 419 $this->info['right'] = 420 $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( 421 array( 422 new HTMLPurifier_AttrDef_CSS_Length(), 423 new HTMLPurifier_AttrDef_CSS_Percentage(), 424 new HTMLPurifier_AttrDef_Enum(array('auto')), 425 ) 426 ); 427 $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( 428 array( 429 new HTMLPurifier_AttrDef_Integer(), 430 new HTMLPurifier_AttrDef_Enum(array('auto')), 431 ) 432 ); 433 } 434 435 /** 436 * Performs extra config-based processing. Based off of 437 * HTMLPurifier_HTMLDefinition. 438 * @param HTMLPurifier_Config $config 439 * @todo Refactor duplicate elements into common class (probably using 440 * composition, not inheritance). 441 */ 442 protected function setupConfigStuff($config) 443 { 444 // setup allowed elements 445 $support = "(for information on implementing this, see the " . 446 "support forums) "; 447 $allowed_properties = $config->get('CSS.AllowedProperties'); 448 if ($allowed_properties !== null) { 449 foreach ($this->info as $name => $d) { 450 if (!isset($allowed_properties[$name])) { 451 unset($this->info[$name]); 452 } 453 unset($allowed_properties[$name]); 454 } 455 // emit errors 456 foreach ($allowed_properties as $name => $d) { 457 // :TODO: Is this htmlspecialchars() call really necessary? 458 $name = htmlspecialchars($name); 459 trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING); 460 } 461 } 462 463 $forbidden_properties = $config->get('CSS.ForbiddenProperties'); 464 if ($forbidden_properties !== null) { 465 foreach ($this->info as $name => $d) { 466 if (isset($forbidden_properties[$name])) { 467 unset($this->info[$name]); 468 } 469 } 470 } 471 } 472 } 473 474 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |