Dustin Wilson
3 years ago
5 changed files with 113 additions and 29 deletions
@ -0,0 +1,86 @@ |
|||||
|
<?php |
||||
|
/** @license MIT |
||||
|
* Copyright 2017 , Dustin Wilson, J. King et al. |
||||
|
* See LICENSE and AUTHORS files for details */ |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
namespace MensBeam\HTML\DOM; |
||||
|
|
||||
|
class HTMLElement extends Element { |
||||
|
protected function __get_accessKey(): string { |
||||
|
# The accessKey IDL attribute must reflect the accesskey content attribute. |
||||
|
return $this->getAttribute('accesskey'); |
||||
|
} |
||||
|
|
||||
|
protected function __set_accessKey(string $value) { |
||||
|
return $this->setAttribute('accesskey', $value); |
||||
|
} |
||||
|
|
||||
|
protected function __get_contentEditable(): string { |
||||
|
# The contentEditable IDL attribute, on getting, must return the string "true" |
||||
|
# if the content attribute is set to the true state, "false" if the content |
||||
|
# attribute is set to the false state, and "inherit" otherwise. |
||||
|
$result = $this->getAttribute('contenteditable'); |
||||
|
switch ($value) { |
||||
|
case 'false': |
||||
|
case 'true': |
||||
|
return $result; |
||||
|
default: |
||||
|
return 'inherit'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected function __set_contentEditable(string $value) { |
||||
|
# On setting, if the new value is an ASCII case-insensitive match for the |
||||
|
# string "inherit" then the content attribute must be removed, if the new value |
||||
|
# is an ASCII case-insensitive match for the string "true" then the content |
||||
|
# attribute must be set to the string "true", if the new value is an ASCII |
||||
|
# case-insensitive match for the string "false" then the content attribute must |
||||
|
# be set to the string "false", and otherwise the attribute setter must throw a |
||||
|
# "SyntaxError" DOMException. |
||||
|
switch ($value) { |
||||
|
case 'inherit' |
||||
|
$this->removeAttribute('contenteditable'); |
||||
|
case 'false': |
||||
|
case 'true': |
||||
|
return $this->setAttribute('contenteditable', $value); |
||||
|
default: |
||||
|
throw new DOMException(DOMException::SYNTAX_ERROR); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected function __get_isContentEditable(): bool { |
||||
|
# The isContentEditable IDL attribute, on getting, must return true if the |
||||
|
# element is either an editing host or editable, and false otherwise. |
||||
|
# |
||||
|
# An editing host is either an HTML element with its contenteditable attribute |
||||
|
# in the true state, or a child HTML element of a Document whose design mode |
||||
|
# enabled is true. |
||||
|
# |
||||
|
# Something is editable if it is a node; it is not an editing host; it does |
||||
|
# not have a contenteditable attribute set to the false state; its parent is an |
||||
|
# editing host or editable; and either it is an HTML element, or it is an svg or |
||||
|
# math element, or it is not an Element and its parent is an HTML element. |
||||
|
$contentEditable = $this->__get_contentEditable(); |
||||
|
$designMode = ($this->ownerDocument->designMode === 'on'); |
||||
|
if ($contentEditable === 'true' || $designMode) { |
||||
|
return true; |
||||
|
} elseif ($contentEditable !== 'false') { |
||||
|
// If the parent can be either an editing host or editable then all is needed |
||||
|
// is to see if there's an ancestor that's an editing host. Just seems absurd |
||||
|
// to word the specification like that. Since isContentEditable is a property |
||||
|
// of HTMLElement there's no need to check if it's an HTML element, svg, or |
||||
|
// non-element child of foreign content. There is also no need to check for |
||||
|
// design mode enabled on the document because it's checked above. |
||||
|
if ($this->moonwalk(function($n) { |
||||
|
if ($n instanceof HTMLElement && $n->contentEditable === 'true') { |
||||
|
return true; |
||||
|
} |
||||
|
})->current() !== null) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue