One Hat Cyber Team
Your IP:
216.73.216.30
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
self
/
root
/
proc
/
thread-self
/
cwd
/
Edit File:
Frame.tar
FrameTree.php 0000644 00000021454 15111216042 0007126 0 ustar 00 <?php /** * @package dompdf * @link https://github.com/dompdf/dompdf * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Frame; use DOMDocument; use DOMNode; use DOMElement; use DOMXPath; use Dompdf\Exception; use Dompdf\Frame; use IteratorAggregate; /** * Represents an entire document as a tree of frames * * The FrameTree consists of {@link Frame} objects each tied to specific * DOMNode objects in a specific DomDocument. The FrameTree has the same * structure as the DomDocument, but adds additional capabilities for * styling and layout. * * @package dompdf */ class FrameTree implements IteratorAggregate { /** * Tags to ignore while parsing the tree * * @var array */ protected static $HIDDEN_TAGS = [ "area", "base", "basefont", "head", "style", "meta", "title", "colgroup", "noembed", "param", "#comment" ]; /** * The main DomDocument * * @see http://ca2.php.net/manual/en/ref.dom.php * @var DOMDocument */ protected $_dom; /** * The root node of the FrameTree. * * @var Frame */ protected $_root; /** * Subtrees of absolutely positioned elements * * @var array of Frames */ protected $_absolute_frames; /** * A mapping of {@link Frame} objects to DOMNode objects * * @var array */ protected $_registry; /** * Class constructor * * @param DOMDocument $dom the main DomDocument object representing the current html document */ public function __construct(DomDocument $dom) { $this->_dom = $dom; $this->_root = null; $this->_registry = []; } /** * Returns the DOMDocument object representing the current html document * * @return DOMDocument */ public function get_dom() { return $this->_dom; } /** * Returns the root frame of the tree * * @return Frame */ public function get_root() { return $this->_root; } /** * Returns a specific frame given its id * * @param string $id * * @return Frame|null */ public function get_frame($id) { return isset($this->_registry[$id]) ? $this->_registry[$id] : null; } /** * Returns a post-order iterator for all frames in the tree * * @deprecated Iterate the tree directly instead * @return FrameTreeIterator */ public function get_frames(): FrameTreeIterator { return new FrameTreeIterator($this->_root); } /** * Returns a post-order iterator for all frames in the tree * * @return FrameTreeIterator */ public function getIterator(): FrameTreeIterator { return new FrameTreeIterator($this->_root); } /** * Builds the tree */ public function build_tree() { $html = $this->_dom->getElementsByTagName("html")->item(0); if (is_null($html)) { $html = $this->_dom->firstChild; } if (is_null($html)) { throw new Exception("Requested HTML document contains no data."); } $this->fix_tables(); $this->_root = $this->_build_tree_r($html); } /** * Adds missing TBODYs around TR */ protected function fix_tables() { $xp = new DOMXPath($this->_dom); // Move table caption before the table // FIXME find a better way to deal with it... $captions = $xp->query('//table/caption'); foreach ($captions as $caption) { $table = $caption->parentNode; $table->parentNode->insertBefore($caption, $table); } $firstRows = $xp->query('//table/tr[1]'); /** @var DOMElement $tableChild */ foreach ($firstRows as $tableChild) { $tbody = $this->_dom->createElement('tbody'); $tableNode = $tableChild->parentNode; do { if ($tableChild->nodeName === 'tr') { $tmpNode = $tableChild; $tableChild = $tableChild->nextSibling; $tableNode->removeChild($tmpNode); $tbody->appendChild($tmpNode); } else { if ($tbody->hasChildNodes() === true) { $tableNode->insertBefore($tbody, $tableChild); $tbody = $this->_dom->createElement('tbody'); } $tableChild = $tableChild->nextSibling; } } while ($tableChild); if ($tbody->hasChildNodes() === true) { $tableNode->appendChild($tbody); } } } // FIXME: temporary hack, preferably we will improve rendering of sequential #text nodes /** * Remove a child from a node * * Remove a child from a node. If the removed node results in two * adjacent #text nodes then combine them. * * @param DOMNode $node the current DOMNode being considered * @param array $children an array of nodes that are the children of $node * @param int $index index from the $children array of the node to remove */ protected function _remove_node(DOMNode $node, array &$children, $index) { $child = $children[$index]; $previousChild = $child->previousSibling; $nextChild = $child->nextSibling; $node->removeChild($child); if (isset($previousChild, $nextChild)) { if ($previousChild->nodeName === "#text" && $nextChild->nodeName === "#text") { $previousChild->nodeValue .= $nextChild->nodeValue; $this->_remove_node($node, $children, $index+1); } } array_splice($children, $index, 1); } /** * Recursively adds {@link Frame} objects to the tree * * Recursively build a tree of Frame objects based on a dom tree. * No layout information is calculated at this time, although the * tree may be adjusted (i.e. nodes and frames for generated content * and images may be created). * * @param DOMNode $node the current DOMNode being considered * * @return Frame */ protected function _build_tree_r(DOMNode $node) { $frame = new Frame($node); $id = $frame->get_id(); $this->_registry[$id] = $frame; if (!$node->hasChildNodes()) { return $frame; } // Store the children in an array so that the tree can be modified $children = []; $length = $node->childNodes->length; for ($i = 0; $i < $length; $i++) { $children[] = $node->childNodes->item($i); } $index = 0; // INFO: We don't advance $index if a node is removed to avoid skipping nodes while ($index < count($children)) { $child = $children[$index]; $nodeName = strtolower($child->nodeName); // Skip non-displaying nodes if (in_array($nodeName, self::$HIDDEN_TAGS)) { if ($nodeName !== "head" && $nodeName !== "style") { $this->_remove_node($node, $children, $index); } else { $index++; } continue; } // Skip empty text nodes if ($nodeName === "#text" && $child->nodeValue === "") { $this->_remove_node($node, $children, $index); continue; } // Skip empty image nodes if ($nodeName === "img" && $child->getAttribute("src") === "") { $this->_remove_node($node, $children, $index); continue; } if (is_object($child)) { $frame->append_child($this->_build_tree_r($child), false); } $index++; } return $frame; } /** * @param DOMElement $node * @param DOMElement $new_node * @param string $pos * * @return mixed */ public function insert_node(DOMElement $node, DOMElement $new_node, $pos) { if ($pos === "after" || !$node->firstChild) { $node->appendChild($new_node); } else { $node->insertBefore($new_node, $node->firstChild); } $this->_build_tree_r($new_node); $frame_id = $new_node->getAttribute("frame_id"); $frame = $this->get_frame($frame_id); $parent_id = $node->getAttribute("frame_id"); $parent = $this->get_frame($parent_id); if ($parent) { if ($pos === "before") { $parent->prepend_child($frame, false); } else { $parent->append_child($frame, false); } } return $frame_id; } } Factory.php 0000644 00000020055 15111216042 0006657 0 ustar 00 <?php /** * @package dompdf * @link https://github.com/dompdf/dompdf * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Frame; use Dompdf\Dompdf; use Dompdf\Exception; use Dompdf\Frame; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\Page as PageFrameDecorator; use Dompdf\FrameReflower\Page as PageFrameReflower; use Dompdf\Positioner\AbstractPositioner; use DOMXPath; /** * Contains frame decorating logic * * This class is responsible for assigning the correct {@link AbstractFrameDecorator}, * {@link AbstractPositioner}, and {@link AbstractFrameReflower} objects to {@link Frame} * objects. This is determined primarily by the Frame's display type, but * also by the Frame's node's type (e.g. DomElement vs. #text) * * @package dompdf */ class Factory { /** * Array of positioners for specific frame types * * @var AbstractPositioner[] */ protected static $_positioners; /** * Decorate the root Frame * * @param Frame $root The frame to decorate * @param Dompdf $dompdf The dompdf instance * * @return PageFrameDecorator */ public static function decorate_root(Frame $root, Dompdf $dompdf): PageFrameDecorator { $frame = new PageFrameDecorator($root, $dompdf); $frame->set_reflower(new PageFrameReflower($frame)); $root->set_decorator($frame); return $frame; } /** * Decorate a Frame * * @param Frame $frame The frame to decorate * @param Dompdf $dompdf The dompdf instance * @param Frame|null $root The root of the frame * * @throws Exception * @return AbstractFrameDecorator|null * FIXME: this is admittedly a little smelly... */ public static function decorate_frame(Frame $frame, Dompdf $dompdf, ?Frame $root = null): ?AbstractFrameDecorator { $style = $frame->get_style(); $display = $style->display; switch ($display) { case "block": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "inline-block": $positioner = "Inline"; $decorator = "Block"; $reflower = "Block"; break; case "inline": $positioner = "Inline"; if ($frame->is_text_node()) { $decorator = "Text"; $reflower = "Text"; } else { $decorator = "Inline"; $reflower = "Inline"; } break; case "table": $positioner = "Block"; $decorator = "Table"; $reflower = "Table"; break; case "inline-table": $positioner = "Inline"; $decorator = "Table"; $reflower = "Table"; break; case "table-row-group": case "table-header-group": case "table-footer-group": $positioner = "NullPositioner"; $decorator = "TableRowGroup"; $reflower = "TableRowGroup"; break; case "table-row": $positioner = "NullPositioner"; $decorator = "TableRow"; $reflower = "TableRow"; break; case "table-cell": $positioner = "TableCell"; $decorator = "TableCell"; $reflower = "TableCell"; break; case "list-item": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "-dompdf-list-bullet": if ($style->list_style_position === "inside") { $positioner = "Inline"; } else { $positioner = "ListBullet"; } if ($style->list_style_image !== "none") { $decorator = "ListBulletImage"; } else { $decorator = "ListBullet"; } $reflower = "ListBullet"; break; case "-dompdf-image": $positioner = "Inline"; $decorator = "Image"; $reflower = "Image"; break; case "-dompdf-br": $positioner = "Inline"; $decorator = "Inline"; $reflower = "Inline"; break; default: case "none": if ($style->_dompdf_keep !== "yes") { // Remove the node and the frame $frame->get_parent()->remove_child($frame); return null; } $positioner = "NullPositioner"; $decorator = "NullFrameDecorator"; $reflower = "NullFrameReflower"; break; } // Handle CSS position $position = $style->position; if ($position === "absolute") { $positioner = "Absolute"; } elseif ($position === "fixed") { $positioner = "Fixed"; } $node = $frame->get_node(); // Handle nodeName if ($node->nodeName === "img") { $style->set_prop("display", "-dompdf-image"); $decorator = "Image"; $reflower = "Image"; } $decorator = "Dompdf\\FrameDecorator\\$decorator"; $reflower = "Dompdf\\FrameReflower\\$reflower"; /** @var AbstractFrameDecorator $deco */ $deco = new $decorator($frame, $dompdf); $deco->set_positioner(self::getPositionerInstance($positioner)); $deco->set_reflower(new $reflower($deco, $dompdf->getFontMetrics())); if ($root) { $deco->set_root($root); } if ($display === "list-item") { // Insert a list-bullet frame $xml = $dompdf->getDom(); $bullet_node = $xml->createElement("bullet"); // arbitrary choice $b_f = new Frame($bullet_node); $node = $frame->get_node(); $parent_node = $node->parentNode; if ($parent_node && $parent_node instanceof \DOMElement) { if (!$parent_node->hasAttribute("dompdf-children-count")) { $xpath = new DOMXPath($xml); $count = $xpath->query("li", $parent_node)->length; $parent_node->setAttribute("dompdf-children-count", $count); } if (is_numeric($node->getAttribute("value"))) { $index = intval($node->getAttribute("value")); } else { if (!$parent_node->hasAttribute("dompdf-counter")) { $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1); } else { $index = (int)$parent_node->getAttribute("dompdf-counter") + 1; } } $parent_node->setAttribute("dompdf-counter", $index); $bullet_node->setAttribute("dompdf-counter", $index); } $new_style = $dompdf->getCss()->create_style(); $new_style->set_prop("display", "-dompdf-list-bullet"); $new_style->inherit($style); $b_f->set_style($new_style); $deco->prepend_child(Factory::decorate_frame($b_f, $dompdf, $root)); } return $deco; } /** * Creates Positioners * * @param string $type Type of positioner to use * * @return AbstractPositioner */ protected static function getPositionerInstance(string $type): AbstractPositioner { if (!isset(self::$_positioners[$type])) { $class = '\\Dompdf\\Positioner\\'.$type; self::$_positioners[$type] = new $class(); } return self::$_positioners[$type]; } } FrameTreeIterator.php 0000644 00000003035 15111216042 0010633 0 ustar 00 <?php /** * @package dompdf * @link https://github.com/dompdf/dompdf * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Frame; use Iterator; use Dompdf\Frame; /** * Pre-order Iterator * * Returns frames in preorder traversal order (parent then children) * * @package dompdf */ class FrameTreeIterator implements Iterator { /** * @var Frame */ protected $_root; /** * @var Frame[] */ protected $_stack = []; /** * @var int */ protected $_num; /** * @param Frame $root */ public function __construct(Frame $root) { $this->_stack[] = $this->_root = $root; $this->_num = 0; } public function rewind(): void { $this->_stack = [$this->_root]; $this->_num = 0; } /** * @return bool */ public function valid(): bool { return count($this->_stack) > 0; } /** * @return int */ public function key(): int { return $this->_num; } /** * @return Frame */ public function current(): Frame { return end($this->_stack); } public function next(): void { $b = array_pop($this->_stack); $this->_num++; // Push all children onto the stack in reverse order if ($c = $b->get_last_child()) { $this->_stack[] = $c; while ($c = $c->get_prev_sibling()) { $this->_stack[] = $c; } } } } FrameListIterator.php 0000644 00000003630 15111216042 0010650 0 ustar 00 <?php /** * @package dompdf * @link https://github.com/dompdf/dompdf * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Frame; use Iterator; use Dompdf\Frame; /** * Linked-list Iterator * * Returns children in order and allows for the list to change during iteration, * provided the changes occur to or after the current element. * * @package dompdf */ class FrameListIterator implements Iterator { /** * @var Frame */ protected $parent; /** * @var Frame|null */ protected $cur; /** * @var Frame|null */ protected $prev; /** * @var int */ protected $num; /** * @param Frame $frame */ public function __construct(Frame $frame) { $this->parent = $frame; $this->rewind(); } public function rewind(): void { $this->cur = $this->parent->get_first_child(); $this->prev = null; $this->num = 0; } /** * @return bool */ public function valid(): bool { return $this->cur !== null; } /** * @return int */ public function key(): int { return $this->num; } /** * @return Frame|null */ public function current(): ?Frame { return $this->cur; } public function next(): void { if ($this->cur === null) { return; } if ($this->cur->get_parent() === $this->parent) { $this->prev = $this->cur; $this->cur = $this->cur->get_next_sibling(); $this->num++; } else { // Continue from the previous child if the current frame has been // moved to another parent $this->cur = $this->prev !== null ? $this->prev->get_next_sibling() : $this->parent->get_first_child(); } } }
Simpan