1<?php 2// $Header: /cvsroot/html2ps/css.utils.inc.php,v 1.30 2007/04/07 11:16:34 Konstantin Exp $ 3 4// TODO: make an OO-style selectors interface instead of switches 5 6// Searches the CSS rule selector for pseudoelement selectors 7// (assuming that there can be only one) and returns its value 8// 9// note that there's not sence in applying pseudoelement to any chained selector except the last 10// (the deepest descendant) 11// 12function css_find_pseudoelement($selector) { 13 $selector_type = selector_get_type($selector); 14 switch ($selector_type) { 15 case SELECTOR_PSEUDOELEMENT_BEFORE: 16 case SELECTOR_PSEUDOELEMENT_AFTER: 17 return $selector_type; 18 case SELECTOR_SEQUENCE: 19 foreach ($selector[1] as $subselector) { 20 $pe = css_find_pseudoelement($subselector); 21 if (!is_null($pe)) { 22 return $pe; 23 }; 24 } 25 return null; 26 default: 27 return null; 28 } 29} 30 31function _fix_tag_display($default_display, &$state, &$pipeline) { 32 // In some cases 'display' CSS property should be ignored for element-generated boxes 33 // Here we will use the $default_display stored above 34 // Note that "display: none" should _never_ be changed 35 // 36 $handler =& CSS::get_handler(CSS_DISPLAY); 37 if ($handler->get($state->getState()) === "none") { 38 return; 39 }; 40 41 switch ($default_display) { 42 case 'table-cell': 43 // TD will always have 'display: table-cell' 44 $handler->css('table-cell', $pipeline); 45 break; 46 47 case '-button': 48 // INPUT buttons will always have 'display: -button' (in latter case if display = 'block', we'll use a wrapper box) 49 $css_state =& $pipeline->get_current_css_state(); 50 if ($handler->get($css_state->getState()) === 'block') { 51 $need_block_wrapper = true; 52 }; 53 $handler->css('-button', $pipeline); 54 break; 55 }; 56} 57 58function is_percentage($value) { 59 return $value{strlen($value)-1} == "%"; 60} 61 62/** 63 * Handle escape sequences in CSS string values 64 * 65 * 4.3.7 Strings 66 * 67 * Strings can either be written with double quotes or with single 68 * quotes. Double quotes cannot occur inside double quotes, unless 69 * escaped (e.g., as '\"' or as '\22'). Analogously for single quotes 70 * (e.g., "\'" or "\27")... 71 * 72 * A string cannot directly contain a newline. To include a newline in 73 * a string, use an escape representing the line feed character in 74 * Unicode (U+000A), such as "\A" or "\00000a"... 75 * 76 * It is possible to break strings over several lines, for esthetic or 77 * other reasons, but in such a case the newline itself has to be 78 * escaped with a backslash (\). 79 * 80 * 4.1.3 Characters and case 81 * 82 * In CSS 2.1, a backslash (\) character indicates three types of 83 * character escapes. 84 * 85 * First, inside a string, a backslash followed by a newline is 86 * ignored (i.e., the string is deemed not to contain either the 87 * backslash or the newline). 88 * 89 * Second, it cancels the meaning of special CSS characters. Any 90 * character (except a hexadecimal digit) can be escaped with a 91 * backslash to remove its special meaning. For example, "\"" is a 92 * string consisting of one double quote. Style sheet preprocessors 93 * must not remove these backslashes from a style sheet since that 94 * would change the style sheet's meaning. 95 * 96 * Third, backslash escapes allow authors to refer to characters they 97 * can't easily put in a document. In this case, the backslash is 98 * followed by at most six hexadecimal digits (0..9A..F), which stand 99 * for the ISO 10646 ([ISO10646]) character with that number, which 100 * must not be zero. If a character in the range [0-9a-fA-F] follows 101 * the hexadecimal number, the end of the number needs to be made 102 * clear. There are two ways to do that: 103 * 104 * 1. with a space (or other whitespace character): "\26 B" ("&B"). In 105 * this case, user agents should treat a "CR/LF" pair 106 * (U+000D/U+000A) as a single whitespace character. 107 * 2. by providing exactly 6 hexadecimal digits: "\000026B" ("&B") 108 * 109 * In fact, these two methods may be combined. Only one whitespace 110 * character is ignored after a hexadecimal escape. Note that this 111 * means that a "real" space after the escape sequence must itself 112 * either be escaped or doubled. 113 */ 114function css_process_escapes($value) { 115 $value = preg_replace_callback('/\\\\([\da-f]{1,6})( |[^][\da-f])/i', 116 'css_process_escapes_callback', 117 $value); 118 119 $value = preg_replace_callback('/\\\\([\da-f]{6})( ?)/i', 120 'css_process_escapes_callback', 121 $value); 122 return $value; 123} 124 125function css_process_escapes_callback($matches) { 126 if ($matches[2] == ' ') { 127 return hex_to_utf8($matches[1]); 128 } else { 129 return hex_to_utf8($matches[1]).$matches[2]; 130 }; 131} 132 133function css_remove_value_quotes($value) { 134 if (strlen($value) == 0) { return $value; }; 135 136 if ($value{0} === "'" || $value{0} === "\"") { 137 $value = substr($value, 1, strlen($value)-2); 138 }; 139 return $value; 140} 141 142?>