Browse Source

Modifying printing

• Added exceptions for disabled inherited DOMDocument methods that don't make sense in an HTML5 library.
• Moved the inherited methods from the Printing trait to Document as DocumentFragment and Element don't inherit anything to print.
split-manual
Dustin Wilson 6 years ago
parent
commit
ab1a78c192
  1. 22
      lib/DOM/Document.php
  2. 6
      lib/DOM/DocumentFragment.php
  3. 20
      lib/DOM/traits/Printing.php
  4. 48
      lib/Exception.php

22
lib/DOM/Document.php

@ -58,5 +58,25 @@ class Document extends \DOMDocument {
return true;
}
public function loadXML($source, $options = null) {}
public function loadXML($source, $options = null) {
throw new Exception(Exception::DOM_DISABLED_METHOD, __CLASS__, __FUNCTION__);
}
public function save($filename, $options = null) {
throw new Exception(Exception::DOM_DISABLED_METHOD, __CLASS__, __FUNCTION__);
}
public function saveHTML(\DOMNode $node = null): string {
return $this->serialize($node);
}
public function saveHTMLFile($filename) {}
public function saveXML(\DOMNode $node = null, $options = null) {
throw new Exception(Exception::DOM_DISABLED_METHOD, __CLASS__, __FUNCTION__);
}
public function __toString() {
return $this->serialize();
}
}

6
lib/DOM/DocumentFragment.php

@ -3,5 +3,9 @@ declare(strict_types=1);
namespace dW\HTML5;
class DocumentFragment extends \DOMDocumentFragment {
use Descendant;
use Descendant, Printing;
public function __toString() {
return $this->serialize();
}
}

20
lib/DOM/traits/Printing.php

@ -5,15 +5,17 @@ namespace dW\HTML5;
trait Printing {
protected $selfClosingElements = ['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
public function saveHTML(\DOMNode $node = null): string {
protected function serialize(\DOMNode $node = null): string {
if (is_null($node)) {
$node = $this;
}
if (!$node instanceof \DOMElement && !$node instanceof \DOMDocument && !$node instanceof \DOMDocumentFragment) {
if (!$node instanceof Element && !$node instanceof Document && !$node instanceof DocumentFragment) {
throw new Exception(Exception::DOM_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED, gettype($node));
}
# 8.3. Serializing HTML fragments
#
# 1. Let s be a string, and initialize it to the empty string.
$s = '';
@ -30,7 +32,7 @@ trait Printing {
# 2. Append the appropriate string from the following list to s:
# If current node is an Element
if ($currentNode instanceof \DOMElement) {
if ($currentNode instanceof Element) {
# If current node is an element in the HTML namespace, the MathML namespace,
# or the SVG namespace, then let tagname be current node’s local name.
# Otherwise, let tagname be current node’s qualified name.
@ -116,11 +118,11 @@ trait Printing {
# current node element (thus recursing into this algorithm for that element),
# followed by a U+003C LESS-THAN SIGN character (<), a U+002F SOLIDUS character (/),
# tagname again, and finally a U+003E GREATER-THAN SIGN character (>).
$s .= $this->saveHTML($currentNode);
$s .= $this->serialize($currentNode);
$s .= "</$currentNodeName>";
}
# If current node is a Text node
elseif ($currentNode instanceof \DOMText) {
elseif ($currentNode instanceof Text) {
# If the parent of current node is a style, script, xmp, iframe, noembed,
# noframes, or plaintext element, or if the parent of current node is a noscript
# element and scripting is enabled for the node, then append the value of
@ -132,7 +134,7 @@ trait Printing {
$s .= $this->escapeString($currentNode->data);
}
# If current node is a Comment
elseif ($currentNode instanceof \DOMComment) {
elseif ($currentNode instanceof Comment) {
# Append the literal string "<!--" (U+003C LESS-THAN SIGN, U+0021 EXCLAMATION
# MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS), followed by the value of
# current node’s data IDL attribute, followed by the literal string "-->"
@ -140,7 +142,7 @@ trait Printing {
$s .= "<!--{$currentNode->data}-->";
}
# If current node is a ProcessingInstruction
elseif ($currentNode instanceof \DOMProcessingInstruction) {
elseif ($currentNode instanceof ProcessingInstruction) {
# Append the literal string "<?" (U+003C LESS-THAN SIGN, U+003F QUESTION MARK),
# followed by the value of current node’s target IDL attribute, followed by a
# single U+0020 SPACE character, followed by the value of current node’s data
@ -164,10 +166,6 @@ trait Printing {
return $s;
}
public function save($filename, $options = null) {}
public function saveHTMLFile($filename) {}
public function saveXML(\DOMNode $node = null, $options = null) {}
protected function escapeString(string $string, bool $attribute = false): string {
# Escaping a string (for the purposes of the algorithm above) consists of
# running the following steps:

48
lib/Exception.php

@ -7,41 +7,45 @@ class Exception extends \Exception {
const UNKNOWN_ERROR = 10001;
const INCORRECT_PARAMETERS_FOR_MESSAGE = 10002;
const STACK_INVALID_INDEX = 10101;
const STACK_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10102;
const PARSER_NONEMPTY_DOCUMENT = 10101;
const DATA_NODATA = 10201;
const DATA_INVALID_DATA_CONSUMPTION_LENGTH = 10202;
const STACK_INVALID_INDEX = 10201;
const STACK_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10202;
const DOM_DOMNODE_STRING_OR_CLOSURE_EXPECTED = 10301;
const DOM_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10302;
const DATA_NODATA = 10301;
const DATA_INVALID_DATA_CONSUMPTION_LENGTH = 10302;
const TOKENIZER_INVALID_STATE = 10401;
const DOM_DOMNODE_STRING_OR_CLOSURE_EXPECTED = 10401;
const DOM_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10402;
const TREEBUILDER_FORMELEMENT_EXPECTED = 10501;
const TREEBUILDER_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10502;
const TOKENIZER_INVALID_STATE = 10501;
const PARSER_NONEMPTY_DOCUMENT = 10601;
const TREEBUILDER_FORMELEMENT_EXPECTED = 10601;
const TREEBUILDER_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10602;
const DOM_DISABLED_METHOD = 10701;
protected static $messages = [10000 => 'Invalid error code',
10001 => 'Unknown error; escaping',
10002 => 'Incorrect number of parameters for Exception message; %s expected',
10101 => '%s is an invalid Stack index',
10102 => 'Element, Document, or DOMDocumentFragment expected for fragment context; found %s',
10101 => 'Non-empty Document supplied as argument for Parser',
10201 => '%s is an invalid Stack index',
10202 => 'Element, Document, or DOMDocumentFragment expected for fragment context; found %s',
10201 => 'Data string expected; found %s',
10202 => '%s is an invalid data consumption length; a value of 1 or above is expected',
10301 => 'Data string expected; found %s',
10302 => '%s is an invalid data consumption length; a value of 1 or above is expected',
10301 => 'The first argument must either be an instance of \DOMNode, a string, or a closure; found %s',
10302 => 'Element, Document, or DOMDocumentFragment expected; found %s',
10401 => 'The first argument must either be an instance of \DOMNode, a string, or a closure; found %s',
10402 => 'Element, Document, or DOMDocumentFragment expected; found %s',
10401 => 'The Tokenizer has entered an invalid state',
10501 => 'The Tokenizer has entered an invalid state',
10501 => 'Form element expected, found %s',
10502 => 'Element, Document, or DOMDocumentFragment expected; found %s',
10601 => 'Form element expected, found %s',
10602 => 'Element, Document, or DOMDocumentFragment expected; found %s',
10601 => 'Non-empty Document supplied as argument for Parser'];
10701 => 'Method %1$s::%2$s has been disabled from %1$s'];
public function __construct(int $code, ...$args) {
if (!isset(static::$messages[$code])) {
@ -59,7 +63,9 @@ class Exception extends \Exception {
}
// Count the number of replacements needed in the message.
$count = substr_count($message, '%s');
preg_match_all('/(\%(?:\d+\$)?s)/', $message, $matches);
$count = count(array_unique($matches[1]));
// If the number of replacements don't match the arguments then oops.
if (count($args) !== $count) {
throw new Exception(self::INCORRECT_PARAMETERS_FOR_MESSAGE, $count);

Loading…
Cancel
Save