add contents

This commit is contained in:
Trevor Batley
2025-10-09 15:04:29 +11:00
parent 170362eec1
commit bce7dd054a
2537 changed files with 301282 additions and 0 deletions

View File

@@ -0,0 +1,293 @@
<?php
/**
* Utility class for handling border properties.
* Only works with properties stored in an array as delivered from
* class cssimportnew, e.g. from method getPropertiesForElement().
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author LarsDW223
*/
/**
* Class cssborder.
*
* @package CSS\CSSAttributeSelector
*/
class cssborder {
static public function getWidthShorthandValues ($value, &$top, &$right, &$bottom, &$left) {
$top = NULL;
$right = NULL;
$bottom = NULL;
$left = NULL;
$values = preg_split ('/\s+/', $value);
switch (count($values)) {
case 1:
$top = $values [0];
$bottom = $values [0];
$right = $values [0];
$left = $values [0];
break;
case 2:
$top = $values [0];
$bottom = $values [0];
$right = $values [1];
$left = $values [1];
break;
case 3:
$top = $values [0];
$right = $values [1];
$left = $values [1];
$bottom = $values [2];
break;
case 4:
default:
$top = $values [0];
$right = $values [1];
$bottom = $values [2];
$left = $values [3];
break;
}
}
static public function getShorthandValues ($value, &$width, &$style, &$color) {
$width = NULL;
$style = NULL;
$color = NULL;
if (empty($value)) {
return;
}
if ($value == 'initial' || $value == 'inherit') {
$width = $value;
$style = $value;
$color = $value;
return;
}
$values = preg_split ('/\s+/', $value);
$index = 0;
$border_width_set = false;
$border_style_set = false;
$border_color_set = false;
while ( $index < 3 ) {
if ( $border_width_set === false ) {
switch ($values [$index]) {
case 'thin':
case 'medium':
case 'thick':
$width = $values [$index];
$index++;
break;
default:
$unit = substr ($values [$index], -2);
if ( ctype_digit($values [$index]) ||
$unit == 'px' ||
$unit == 'pt' ||
$unit == 'cm' ) {
$width = $values [$index];
$index++;
} else {
// There is no default value? So leave it unset.
}
break;
}
$border_width_set = true;
continue;
}
if ( $border_style_set === false ) {
switch ($values [$index]) {
case 'none':
case 'hidden':
case 'dotted':
case 'dashed':
case 'solid':
case 'double':
case 'groove':
case 'ridge':
case 'inset':
case 'outset':
case 'initial':
case 'inherit':
$style = $values [$index];
$index++;
break;
}
$border_style_set = true;
continue;
}
if ( $border_color_set === false ) {
if (!empty($values [$index])) {
$color = $values [$index];
}
// This is the last value.
break;
}
}
}
/**
* The function checks if this atrribute selector matches the
* attributes given in $attributes as key - value pairs.
*
* @param string $attributes String containing the selector
* @return boolean
*/
static public function normalize (array &$properties) {
$border_sides = array ('border-left', 'border-right', 'border-top', 'border-bottom');
$bl_width = '0px';
$br_width = '0px';
$bb_width = '0px';
$bt_width = '0px';
$bl_style = 'none';
$br_style = 'none';
$bb_style = 'none';
$bt_style = 'none';
$bl_color = NULL;
$br_color = NULL;
$bb_color = NULL;
$bt_color = NULL;
if (!empty($properties ['border'])) {
$width = NULL;
$style = NULL;
$color = NULL;
self::getShorthandValues ($properties ['border'], $width, $style, $color);
if (!empty($width)) {
$bl_width = $width;
$br_width = $width;
$bb_width = $width;
$bt_width = $width;
}
if (!empty($style)) {
$bl_style = $style;
$br_style = $style;
$bb_style = $style;
$bt_style = $style;
}
if (!empty($color)) {
$bl_color = $color;
$br_color = $color;
$bb_color = $color;
$bt_color = $color;
}
unset ($properties ['border']);
}
if (!empty($properties ['border-left'])) {
$width = NULL;
$style = NULL;
$color = NULL;
self::getShorthandValues ($properties ['border-left'], $width, $style, $color);
if (!empty($width)) {
$bl_width = $width;
}
if (!empty($style)) {
$bl_style = $style;
}
if (!empty($color)) {
$bl_color = $color;
}
unset ($properties ['border-left']);
}
if (!empty($properties ['border-right'])) {
$width = NULL;
$style = NULL;
$color = NULL;
self::getShorthandValues ($properties ['border-right'], $width, $style, $color);
if (!empty($width)) {
$br_width = $width;
}
if (!empty($style)) {
$br_style = $style;
}
if (!empty($color)) {
$br_color = $color;
}
unset ($properties ['border-right']);
}
if (!empty($properties ['border-top'])) {
$width = NULL;
$style = NULL;
$color = NULL;
self::getShorthandValues ($properties ['border-top'], $width, $style, $color);
if (!empty($width)) {
$bt_width = $width;
}
if (!empty($style)) {
$bt_style = $style;
}
if (!empty($color)) {
$bt_color = $color;
}
unset ($properties ['border-top']);
}
if (!empty($properties ['border-bottom'])) {
$width = NULL;
$style = NULL;
$color = NULL;
self::getShorthandValues ($properties ['border-bottom'], $width, $style, $color);
if (!empty($width)) {
$bb_width = $width;
}
if (!empty($style)) {
$bb_style = $style;
}
if (!empty($color)) {
$bb_color = $color;
}
unset ($properties ['border-bottom']);
}
if (!empty($properties ['border-width'])) {
$top = NULL;
$right = NULL;
$bottom = NULL;
$left = NULL;
self::getWidthShorthandValues ($properties ['border-width'], $top, $right, $bottom, $left);
if (!empty($top)) {
$bt_width = $top;
}
if (!empty($right)) {
$br_width = $right;
}
if (!empty($bottom)) {
$bb_width = $bottom;
}
if (!empty($left)) {
$bl_width = $left;
}
unset ($properties ['border-width']);
}
// Now normalize and minimize the collected properties values
// Re-assemble border properties to per side shorthand.
if (!empty($bt_width) || !empty($bt_style) || !empty($bt_color)) {
$properties ['border-top'] = $bt_width.' '.$bt_style.' '.$bt_color;
}
if (!empty($br_width) || !empty($br_style) || !empty($br_color)) {
$properties ['border-right'] = $br_width.' '.$br_style.' '.$br_color;
}
if (!empty($bb_width) || !empty($bb_style) || !empty($bb_color)) {
$properties ['border-bottom'] = $bb_width.' '.$bb_style.' '.$bb_color;
}
if (!empty($bl_width) || !empty($bl_style) || !empty($bl_color)) {
$properties ['border-left'] = $bl_width.' '.$bl_style.' '.$bl_color;
}
// If all sides are the same we can put them all together as a single border shorthand
if ($properties ['border-top'] == $properties ['border-right'] &&
$properties ['border-top'] == $properties ['border-bottom'] &&
$properties ['border-top'] == $properties ['border-left']) {
$properties ['border'] = $properties ['border-top'];
unset ($properties ['border-top']);
unset ($properties ['border-right']);
unset ($properties ['border-bottom']);
unset ($properties ['border-left']);
}
}
}

View File

@@ -0,0 +1,336 @@
<?php
/**
* Simple class to query CSS color values and names.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author LarsDW223
*/
/**
* Class csscolors
*/
class csscolors {
protected static $values = array(
'aliceblue' => '#F0F8FF',
'antiquewhite' => '#FAEBD7',
'aqua' => '#00FFFF',
'aquamarine' => '#7FFFD4',
'azure' => '#F0FFFF',
'beige' => '#F5F5DC',
'bisque' => '#FFE4C4',
'black' => '#000000',
'blanchedalmond' => '#FFEBCD',
'blue' => '#0000FF',
'blueviolet' => '#8A2BE2',
'brown' => '#A52A2A',
'burlywood' => '#DEB887',
'cadetblue' => '#5F9EA0',
'chartreuse' => '#7FFF00',
'chocolate' => '#D2691E',
'coral' => '#FF7F50',
'cornflowerblue' => '#6495ED',
'cornsilk' => '#FFF8DC',
'crimson' => '#DC143C',
'cyan' => '#00FFFF',
'darkblue' => '#00008B',
'darkcyan' => '#008B8B',
'darkgoldenrod' => '#B8860B',
'darkgray' => '#A9A9A9',
'darkgreen' => '#006400',
'darkkhaki' => '#BDB76B',
'darkmagenta' => '#8B008B',
'darkolivegreen' => '#556B2F',
'darkorange' => '#FF8C00',
'darkorchid' => '#9932CC',
'darkred' => '#8B0000',
'darksalmon' => '#E9967A',
'darkseagreen' => '#8FBC8F',
'darkslateblue' => '#483D8B',
'darkslategray' => '#2F4F4F',
'darkturquoise' => '#00CED1',
'darkviolet' => '#9400D3',
'deeppink' => '#FF1493',
'deepskyblue' => '#00BFFF',
'dimgray' => '#696969',
'dodgerblue' => '#1E90FF',
'firebrick' => '#B22222',
'floralwhite' => '#FFFAF0',
'forestgreen' => '#228B22',
'fuchsia' => '#FF00FF',
'gainsboro' => '#DCDCDC',
'ghostwhite' => '#F8F8FF',
'gold' => '#FFD700',
'goldenrod' => '#DAA520',
'gray' => '#808080',
'green' => '#008000',
'greenyellow' => '#ADFF2F',
'honeydew' => '#F0FFF0',
'hotpink' => '#FF69B4',
'indianred' => '#CD5C5C',
'indigo' => '#4B0082',
'ivory' => '#FFFFF0',
'khaki' => '#F0E68C',
'lavender' => '#E6E6FA',
'lavenderblush' => '#FFF0F5',
'lawngreen' => '#7CFC00',
'lemonchiffon' => '#FFFACD',
'lightblue' => '#ADD8E6',
'lightcoral' => '#F08080',
'lightcyan' => '#E0FFFF',
'lightgoldenrodyellow' => '#E0FFFF',
'lightgray' => '#D3D3D3',
'lightgreen' => '#90EE90',
'lightpink' => '#FFB6C1',
'lightsalmon' => '#FFA07A',
'lightseagreen' => '#20B2AA',
'lightskyblue' => '#87CEFA',
'lightslategray' => '#778899',
'lightsteelblue' => '#B0C4DE',
'lightyellow' => '#FFFFE0',
'lime' => '#00FF00',
'limegreen' => '#32CD32',
'linen' => '#FAF0E6',
'magenta' => '#FF00FF',
'maroon' => '#800000',
'mediumaquamarine' => '#66CDAA',
'mediumblue' => '#0000CD',
'mediumorchid' => '#BA55D3',
'mediumpurple' => '#9370DB',
'mediumseagreen' => '#3CB371',
'mediumslateblue' => '#7B68EE',
'mediumspringgreen' => '#00FA9A',
'mediumturquoise' => '#48D1CC',
'mediumvioletred' => '#C71585',
'midnightblue' => '#191970',
'mintcream' => '#F5FFFA',
'mistyrose' => '#FFE4E1',
'moccasin' => '#FFE4B5',
'navajowhite' => '#FFDEAD',
'navy' => '#000080',
'oldlace' => '#FDF5E6',
'olive' => '#808000',
'olivedrab' => '#6B8E23',
'orange' => '#FFA500',
'orangered' => '#FF4500',
'orchid' => '#DA70D6',
'palegoldenrod' => '#EEE8AA',
'palegreen' => '#98FB98',
'paleturquoise' => '#AFEEEE',
'palevioletred' => '#DB7093',
'papayawhip' => '#FFEFD5',
'peachpuff' => '#FFDAB9',
'peru' => '#CD853F',
'pink' => '#FFC0CB',
'plum' => '#DDA0DD',
'powderblue' => '#B0E0E6',
'purple' => '#800080',
'red' => '#FF0000',
'rosybrown' => '#BC8F8F',
'royalblue' => '#4169E1',
'saddlebrown' => '#8B4513',
'salmon' => '#FA8072',
'sandybrown' => '#F4A460',
'seagreen' => '#2E8B57',
'seashell' => '#FFF5EE',
'sienna' => '#A0522D',
'silver' => '#C0C0C0',
'skyblue' => '#87CEEB',
'slateblue' => '#6A5ACD',
'slategray' => '#708090',
'snow' => '#FFFAFA',
'springgreen' => '#00FF7F',
'steelblue' => '#4682B4',
'tan' => '#D2B48C',
'teal' => '#008080',
'thistle' => '#D8BFD8',
'tomato' => '#FF6347',
'turquoise' => '#40E0D0',
'violet' => '#EE82EE',
'wheat' => '#F5DEB3',
'white' => '#FFFFFF',
'whitesmoke' => '#F5F5F5',
'yellow' => '#FFFF00',
'yellowgreen' => '#9ACD32',
);
protected static $names = array(
'#F0F8FF' => 'AliceBlue',
'#FAEBD7' => 'AntiqueWhite',
// '#00FFFF' => 'Aqua', //duplicated key with Cyan
'#7FFFD4' => 'Aquamarine',
'#F0FFFF' => 'Azure',
'#F5F5DC' => 'Beige',
'#FFE4C4' => 'Bisque',
'#000000' => 'Black',
'#FFEBCD' => 'BlanchedAlmond',
'#0000FF' => 'Blue',
'#8A2BE2' => 'BlueViolet',
'#A52A2A' => 'Brown',
'#DEB887' => 'BurlyWood',
'#5F9EA0' => 'CadetBlue',
'#7FFF00' => 'Chartreuse',
'#D2691E' => 'Chocolate',
'#FF7F50' => 'Coral',
'#6495ED' => 'CornflowerBlue',
'#FFF8DC' => 'Cornsilk',
'#DC143C' => 'Crimson',
'#00FFFF' => 'Cyan',
'#00008B' => 'DarkBlue',
'#008B8B' => 'DarkCyan',
'#B8860B' => 'DarkGoldenRod',
'#A9A9A9' => 'DarkGray',
'#006400' => 'DarkGreen',
'#BDB76B' => 'DarkKhaki',
'#8B008B' => 'DarkMagenta',
'#556B2F' => 'DarkOliveGreen',
'#FF8C00' => 'DarkOrange',
'#9932CC' => 'DarkOrchid',
'#8B0000' => 'DarkRed',
'#E9967A' => 'DarkSalmon',
'#8FBC8F' => 'DarkSeaGreen',
'#483D8B' => 'DarkSlateBlue',
'#2F4F4F' => 'DarkSlateGray',
'#00CED1' => 'DarkTurquoise',
'#9400D3' => 'DarkViolet',
'#FF1493' => 'DeepPink',
'#00BFFF' => 'DeepSkyBlue',
'#696969' => 'DimGray',
'#1E90FF' => 'DodgerBlue',
'#B22222' => 'FireBrick',
'#FFFAF0' => 'FloralWhite',
'#228B22' => 'ForestGreen',
//'#FF00FF' => 'Fuchsia', //duplicated key with Magenta
'#DCDCDC' => 'Gainsboro',
'#F8F8FF' => 'GhostWhite',
'#FFD700' => 'Gold',
'#DAA520' => 'GoldenRod',
'#808080' => 'Gray',
'#008000' => 'Green',
'#ADFF2F' => 'GreenYellow',
'#F0FFF0' => 'HoneyDew',
'#FF69B4' => 'HotPink',
'#CD5C5C' => 'IndianRed',
'#4B0082' => 'Indigo',
'#FFFFF0' => 'Ivory',
'#F0E68C' => 'Khaki',
'#E6E6FA' => 'Lavender',
'#FFF0F5' => 'LavenderBlush',
'#7CFC00' => 'LawnGreen',
'#FFFACD' => 'LemonChiffon',
'#ADD8E6' => 'LightBlue',
'#F08080' => 'LightCoral',
'#E0FFFF' => 'LightCyan',
//'#E0FFFF' => 'LightGoldenRodYellow', //duplicated key with LightCyan
'#D3D3D3' => 'LightGray',
'#90EE90' => 'LightGreen',
'#FFB6C1' => 'LightPink',
'#FFA07A' => 'LightSalmon',
'#20B2AA' => 'LightSeaGreen',
'#87CEFA' => 'LightSkyBlue',
'#778899' => 'LightSlateGray',
'#B0C4DE' => 'LightSteelBlue',
'#FFFFE0' => 'LightYellow',
'#00FF00' => 'Lime',
'#32CD32' => 'LimeGreen',
'#FAF0E6' => 'Linen',
'#FF00FF' => 'Magenta',
'#800000' => 'Maroon',
'#66CDAA' => 'MediumAquaMarine',
'#0000CD' => 'MediumBlue',
'#BA55D3' => 'MediumOrchid',
'#9370DB' => 'MediumPurple',
'#3CB371' => 'MediumSeaGreen',
'#7B68EE' => 'MediumSlateBlue',
'#00FA9A' => 'MediumSpringGreen',
'#48D1CC' => 'MediumTurquoise',
'#C71585' => 'MediumVioletRed',
'#191970' => 'MidnightBlue',
'#F5FFFA' => 'MintCream',
'#FFE4E1' => 'MistyRose',
'#FFE4B5' => 'Moccasin',
'#FFDEAD' => 'NavajoWhite',
'#000080' => 'Navy',
'#FDF5E6' => 'OldLace',
'#808000' => 'Olive',
'#6B8E23' => 'OliveDrab',
'#FFA500' => 'Orange',
'#FF4500' => 'OrangeRed',
'#DA70D6' => 'Orchid',
'#EEE8AA' => 'PaleGoldenRod',
'#98FB98' => 'PaleGreen',
'#AFEEEE' => 'PaleTurquoise',
'#DB7093' => 'PaleVioletRed',
'#FFEFD5' => 'PapayaWhip',
'#FFDAB9' => 'PeachPuff',
'#CD853F' => 'Peru',
'#FFC0CB' => 'Pink',
'#DDA0DD' => 'Plum',
'#B0E0E6' => 'PowderBlue',
'#800080' => 'Purple',
'#FF0000' => 'Red',
'#BC8F8F' => 'RosyBrown',
'#4169E1' => 'RoyalBlue',
'#8B4513' => 'SaddleBrown',
'#FA8072' => 'Salmon',
'#F4A460' => 'SandyBrown',
'#2E8B57' => 'SeaGreen',
'#FFF5EE' => 'SeaShell',
'#A0522D' => 'Sienna',
'#C0C0C0' => 'Silver',
'#87CEEB' => 'SkyBlue',
'#6A5ACD' => 'SlateBlue',
'#708090' => 'SlateGray',
'#FFFAFA' => 'Snow',
'#00FF7F' => 'SpringGreen',
'#4682B4' => 'SteelBlue',
'#D2B48C' => 'Tan',
'#008080' => 'Teal',
'#D8BFD8' => 'Thistle',
'#FF6347' => 'Tomato',
'#40E0D0' => 'Turquoise',
'#EE82EE' => 'Violet',
'#F5DEB3' => 'Wheat',
'#FFFFFF' => 'White',
'#F5F5F5' => 'WhiteSmoke',
'#FFFF00' => 'Yellow',
'#9ACD32' => 'YellowGreen',
);
/**
* @param string|null $name
* @return string
*/
public static function getColorValue ($name=NULL) {
$value = '#000000';
if ($name != NULL) {
$value = self::$values [strtolower($name)];
if ($value == NULL)
$value = '#000000';
}
return $value;
}
/**
* @param null $value
* @return string
*/
public static function getValueName ($value=NULL) {
$name = 'Black';
if ($value != NULL) {
$name = self::$names [$value];
if ($name == NULL)
$name = 'Black';
}
return $name;
}
/**
* @param string $name
* @return boolean
*/
public static function isKnownColorName ($name=NULL) {
if ($name != NULL) {
return array_key_exists(strtolower($name), self::$values);
}
return false;
}
}

View File

@@ -0,0 +1,436 @@
<?php
/**
* Class to fake a document tree for CSS matching.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author LarsDW223
*/
/** Include ecm_interface */
require_once DOKU_INC.'lib/plugins/odt/helper/ecm_interface.php';
/**
* Class css_doc_element
*
* @package CSS\CSSDocElement
*/
class css_doc_element implements iElementCSSMatchable {
/** var Reference to corresponding cssdocument */
public $doc = NULL;
/** var Index of this element in the corresponding cssdocument */
public $index = 0;
/**
* Get the name of this element.
*
* @return string
*/
public function iECSSM_getName() {
return $this->doc->entries [$this->index]['element'];
}
/**
* Get the attributes of this element.
*
* @return array
*/
public function iECSSM_getAttributes() {
return $this->doc->entries [$this->index]['attributes_array'];
}
/**
* Get the parent of this element.
*
* @return css_doc_element
*/
public function iECSSM_getParent() {
$index = $this->doc->findParent($this->index);
if ($index == -1 ) {
return NULL;
}
$element = new css_doc_element();
$element->doc = $this->doc;
$element->index = $index;
return $element;
}
/**
* Get the preceding sibling of this element.
*
* @return css_doc_element
*/
public function iECSSM_getPrecedingSibling() {
$index = $this->doc->getPrecedingSibling($this->index);
if ($index == -1 ) {
return NULL;
}
$element = new css_doc_element();
$element->doc = $this->doc;
$element->index = $index;
return $element;
}
/**
* Does this element belong to pseudo class $class?
*
* @param string $class
* @return boolean
*/
public function iECSSM_has_pseudo_class($class) {
if ($this->doc->entries [$this->index]['pseudo_classes'] == NULL) {
return false;
}
$result = array_search($class,
$this->doc->entries [$this->index]['pseudo_classes']);
if ($result === false) {
return false;
}
return true;
}
/**
* Does this element match the pseudo element $element?
*
* @param string $element
* @return boolean
*/
public function iECSSM_has_pseudo_element($element) {
if ($this->doc->entries [$this->index]['pseudo_elements'] == NULL) {
return false;
}
$result = array_search($element,
$this->doc->entries [$this->index]['pseudo_elements']);
if ($result === false) {
return false;
}
return true;
}
/**
* Return the CSS properties assigned to this element.
* (from extern via setProperties())
*
* @return array
*/
public function getProperties () {
return $this->doc->entries [$this->index]['properties'];
}
/**
* Set/assign the CSS properties for this element.
*
* @param array $properties
*/
public function setProperties (array &$properties) {
$this->doc->entries [$this->index]['properties'] = $properties;
}
}
/**
* Class cssdocument.
*
* @package CSS\CSSDocument
*/
class cssdocument {
/** var Current size, Index for next entry */
public $size = 0;
/** var Current nesting level */
public $level = 0;
/** var Array of entries, see open() */
public $entries = array ();
/** var Root index, see saveRootIndex() */
protected $rootIndex = 0;
/** var Root level, see saveRootIndex() */
protected $rootLevel = 0;
/**
* Internal function to get the value of an attribute.
*
* @param string $value Value of the attribute
* @param string $input Code to parse
* @param integer $pos Current position in $input
* @param integer $max End of $input
* @return integer Position at which the attribute ends
*/
protected function collect_attribute_value (&$value, $input, $pos, $max) {
$value = '';
$in_quotes = false;
$quote = '';
while ($pos < $max) {
$sign = $input [$pos];
$pos++;
if ($in_quotes == false) {
if ($sign == '"' || $sign == "'") {
$quote = $sign;
$in_quotes = true;
}
} else {
if ($sign == $quote) {
break;
}
$value .= $sign;
}
}
if ($in_quotes == false || $sign != $quote) {
// No proper quotes, delete value
$value = NULL;
}
return $pos;
}
/**
* Internal function to parse $attributes for key="value" pairs
* and store the result in an array.
*
* @param string $attributes Code to parse
* @return array Array of attributes
*/
protected function get_attributes_array ($attributes) {
if ($attributes == NULL) {
return NULL;
}
$result = array();
$pos = 0;
$max = strlen($attributes);
while ($pos < $max) {
$equal_sign = strpos ($attributes, '=', $pos);
if ($equal_sign === false) {
break;
}
$att_name = substr ($attributes, $pos, $equal_sign-$pos);
$att_name = trim ($att_name, ' ');
$att_end = $this->collect_attribute_value($att_value, $attributes, $equal_sign+1, $max);
// Add a attribute to array
$result [$att_name] = $att_value;
$pos = $att_end + 1;
}
return $result;
}
/**
* Save the current position as the root index of the document.
* It is guaranteed that elements below the root index will not be
* discarded from the cssdocument.
*/
public function saveRootIndex () {
$this->rootIndex = $this->getIndexLastOpened ();
$this->rootLevel = $this->level-1;
}
/**
* Shrinks/cuts the cssdocument down to its root index.
*/
public function restoreToRoot () {
for ($index = $this->size-1 ; $index > $this->rootIndex ; $index--) {
$this->entries [$index] = NULL;
}
$this->size = $this->rootIndex + 1;
$this->level = $this->rootLevel + 1;
}
/**
* Get the current state of the cssdocument.
*
* @param array $state Returned state information
*/
public function getState (array &$state) {
$state ['index'] = $this->size-1;
$state ['level'] = $this->level;
}
/**
* Shrinks/cuts the cssdocument down to the given $state.
* ($state must be retrieved by calling getState())
*
* @param array $state State information
*/
public function restoreState (array $state) {
for ($index = $this->size-1 ; $index > $state ['index'] ; $index--) {
$this->entries [$index] = NULL;
}
$this->size = $state ['index'] + 1;
$this->level = $state ['level'];
}
/**
* Open a new element in the cssdocument.
*
* @param string $element The element's name
* @param string $attributes The element's attributes
* @param string $pseudo_classes The element's pseudo classes
* @param string $pseudo_elements The element's pseudo elements
*/
public function open ($element, $attributes=NULL, $pseudo_classes=NULL, $pseudo_elements=NULL) {
$this->entries [$this->size]['level'] = $this->level;
$this->entries [$this->size]['state'] = 'open';
$this->entries [$this->size]['element'] = $element;
$this->entries [$this->size]['attributes'] = $attributes;
if (!empty($pseudo_classes)) {
$this->entries [$this->size]['pseudo_classes'] = explode(' ', $pseudo_classes);
}
if (!empty($pseudo_elements)) {
$this->entries [$this->size]['pseudo_elements'] = explode(' ', $pseudo_elements);
}
// Build attribute array/parse attributes
if ($attributes != NULL) {
$this->entries [$this->size]['attributes_array'] =
$this->get_attributes_array ($attributes);
}
$this->size++;
$this->level++;
}
/**
* Close $element in the cssdocument.
*
* @param string $element The element's name
*/
public function close ($element) {
$this->level--;
$this->entries [$this->size]['level'] = $this->level;
$this->entries [$this->size]['state'] = 'close';
$this->entries [$this->size]['element'] = $element;
$this->size++;
}
/**
* Get the current element.
*
* @return css_doc_element
*/
public function getCurrentElement() {
$index = $this->getIndexLastOpened ();
if ($index == -1) {
return NULL;
}
$element = new css_doc_element();
$element->doc = $this;
$element->index = $index;
return $element;
}
/**
* Get the entry of internal array $entries at $index.
*
* @param integer $index
* @return array
*/
public function getEntry ($index) {
if ($index >= $this->size ) {
return NULL;
}
return $this->entries [$index];
}
/**
* Get the current entry of internal array $entries.
*
* @return array
*/
public function getCurrentEntry () {
if ($this->size == 0) {
return NULL;
}
return $this->entries [$this->size-1];
}
/**
* Get the index of the 'open' entry of the latest opened element.
*
* @return integer
*/
public function getIndexLastOpened () {
if ($this->size == 0) {
return -1;
}
for ($index = $this->size-1 ; $index >= 0 ; $index--) {
if ($this->entries [$index]['state'] == 'open') {
return $index;
}
}
return -1;
}
/**
* Find the parent for the entry at index $start.
*
* @param integer $start Starting point
*/
public function findParent ($start) {
if ($this->size == 0 || $start >= $this->size) {
return -1;
}
$start_level = $this->entries [$start]['level'];
if ($start_level == 0) {
return -1;
}
for ($index = $start-1 ; $index >= 0 ; $index--) {
if ($this->entries [$index]['state'] == 'open'
&&
$this->entries [$index]['level'] == $start_level-1) {
return $index;
}
}
return -1;
}
/**
* Find the preceding sibling for the entry at index $current.
*
* @param integer $current Starting point
*/
public function getPrecedingSibling ($current) {
if ($this->size == 0 || $current >= $this->size || $current == 0) {
return -1;
}
$current_level = $this->entries [$current]['level'];
if ($this->entries [$current-1]['level'] == $current_level) {
return ($current-1);
}
return -1;
}
/**
* Dump the current elements/entries in this cssdocument.
* Only for debugging purposes.
*/
public function getDump () {
$dump = '';
$dump .= 'RootLevel: '.$this->rootLevel.', RootIndex: '.$this->rootIndex."\n";
for ($index = 0 ; $index < $this->size ; $index++) {
$element = $this->entries [$index];
$dump .= str_repeat(' ', $element ['level'] * 2);
if ($this->entries [$index]['state'] == 'open') {
$dump .= '<'.$element ['element'];
$dump .= ' '.$element ['attributes'].'>';
} else {
$dump .= '</'.$element ['element'].'>';
}
$dump .= ' (Level: '.$element ['level'].')';
$dump .= "\n";
}
return $dump;
}
/**
* Remove the current entry.
*/
public function removeCurrent () {
$index = $this->size-1;
if ($index <= $this->rootIndex) {
// Do not remove root elements!
return;
}
$this->level = $this->entries [$index]['level'];
$this->entries [$index] = NULL;
$this->size--;
}
}

File diff suppressed because it is too large Load Diff