mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-21 20:29:57 +09:00
Move all composer files inside the common directory
- 2022년 3월 개발팀 결정사항 적용 - 모듈 등 서드파티 자료 개발시 composer를 사용하면 상위 경로에 있는 코어의 composer.json을 수정하고, 코어의 vendor 디렉토리를 건드리는 것이 기본값임 - 이를 방지하기 위해 코어의 composer.json과 vendor를 common 디렉토리 안으로 이동하여, 모듈 경로에서 상위 폴더로 인식하지 않도록 함
This commit is contained in:
parent
7b912d21fc
commit
5fff6b6eab
1478 changed files with 2 additions and 2 deletions
3
common/vendor/jbbcode/jbbcode/.coveralls.yml
vendored
Normal file
3
common/vendor/jbbcode/jbbcode/.coveralls.yml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
src_dir: .
|
||||
coverage_clover: clover.xml
|
||||
json_path: clover.json
|
||||
4
common/vendor/jbbcode/jbbcode/.gitignore
vendored
Normal file
4
common/vendor/jbbcode/jbbcode/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
composer.lock
|
||||
vendor
|
||||
clover.xml
|
||||
clover.json
|
||||
28
common/vendor/jbbcode/jbbcode/.travis.yml
vendored
Normal file
28
common/vendor/jbbcode/jbbcode/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
language: php
|
||||
php:
|
||||
- 5.6
|
||||
- hhvm
|
||||
- nightly
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
- php: nightly
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
sudo: false
|
||||
|
||||
install:
|
||||
- composer self-update
|
||||
- composer install --prefer-source --no-interaction
|
||||
|
||||
after_success:
|
||||
- php vendor/bin/coveralls -v
|
||||
333
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinition.php
vendored
Normal file
333
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinition.php
vendored
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
/**
|
||||
* This class represents a BBCode Definition. You may construct instances of this class directly,
|
||||
* usually through the CodeDefinitionBuilder class, to create text replacement bbcodes, or you
|
||||
* may subclass it to create more complex bbcode definitions.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class CodeDefinition
|
||||
{
|
||||
/** @var string NOTE: THIS PROPERTY SHOULD ALWAYS BE LOWERCASE; USE setTagName() TO ENSURE THIS */
|
||||
protected $tagName;
|
||||
|
||||
/** @var boolean Whether or not this CodeDefinition uses an option parameter. */
|
||||
protected $useOption;
|
||||
|
||||
/** @var string The replacement text to be used for simple CodeDefinitions */
|
||||
protected $replacementText;
|
||||
|
||||
/** @var boolean Whether or not to parse elements of this definition's contents */
|
||||
protected $parseContent;
|
||||
|
||||
/** @var integer How many of this element type may be nested within each other */
|
||||
protected $nestLimit;
|
||||
|
||||
/** @var integer How many of this element type have been seen */
|
||||
protected $elCounter;
|
||||
|
||||
/** @var array[string]InputValidator The input validators to run options through */
|
||||
protected $optionValidator;
|
||||
|
||||
/** @var InputValidator The input validator to run the body ({param}) through */
|
||||
protected $bodyValidator;
|
||||
|
||||
/**
|
||||
* Constructs a new CodeDefinition.
|
||||
*/
|
||||
public static function construct($tagName, $replacementText, $useOption = false,
|
||||
$parseContent = true, $nestLimit = -1, $optionValidator = array(),
|
||||
$bodyValidator = null)
|
||||
{
|
||||
$def = new CodeDefinition();
|
||||
$def->elCounter = 0;
|
||||
$def->setTagName($tagName);
|
||||
$def->setReplacementText($replacementText);
|
||||
$def->useOption = $useOption;
|
||||
$def->parseContent = $parseContent;
|
||||
$def->nestLimit = $nestLimit;
|
||||
$def->optionValidator = $optionValidator;
|
||||
$def->bodyValidator = $bodyValidator;
|
||||
return $def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new CodeDefinition.
|
||||
*
|
||||
* This constructor is deprecated. You should use the static construct() method or the
|
||||
* CodeDefinitionBuilder class to construct a new CodeDefiniton.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/* WARNING: This function is deprecated and will be made protected in a future
|
||||
* version of jBBCode. */
|
||||
$this->parseContent = true;
|
||||
$this->useOption = false;
|
||||
$this->nestLimit = -1;
|
||||
$this->elCounter = 0;
|
||||
$this->optionValidator = array();
|
||||
$this->bodyValidator = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the arguments to the given element are valid based on
|
||||
* any validators attached to this CodeDefinition.
|
||||
*
|
||||
* @param ElementNode $el the ElementNode to validate
|
||||
* @return boolean true if the ElementNode's {option} and {param} are OK, false if they're not
|
||||
*/
|
||||
public function hasValidInputs(ElementNode $el)
|
||||
{
|
||||
if ($this->usesOption() && $this->optionValidator) {
|
||||
$att = $el->getAttribute();
|
||||
|
||||
foreach ($att as $name => $value) {
|
||||
if (isset($this->optionValidator[$name]) && !$this->optionValidator[$name]->validate($value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->parseContent() && $this->bodyValidator) {
|
||||
/* We only evaluate the content if we're not parsing the content. */
|
||||
$content = "";
|
||||
foreach ($el->getChildren() as $child) {
|
||||
$content .= $child->getAsBBCode();
|
||||
}
|
||||
if (!$this->bodyValidator->validate($content)) {
|
||||
/* The content of the element is not valid. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an ElementNode that is defined by this CodeDefinition and returns the HTML
|
||||
* markup of the element. This is a commonly overridden class for custom CodeDefinitions
|
||||
* so that the content can be directly manipulated.
|
||||
*
|
||||
* @param ElementNode $el the element to return an html representation of
|
||||
*
|
||||
* @return string the parsed html of this element (INCLUDING ITS CHILDREN)
|
||||
*/
|
||||
public function asHtml(ElementNode $el)
|
||||
{
|
||||
if (!$this->hasValidInputs($el)) {
|
||||
return $el->getAsBBCode();
|
||||
}
|
||||
|
||||
$html = $this->getReplacementText();
|
||||
|
||||
if ($this->usesOption()) {
|
||||
$options = $el->getAttribute();
|
||||
if (count($options)==1) {
|
||||
$vals = array_values($options);
|
||||
$html = str_ireplace('{option}', reset($vals), $html);
|
||||
} else {
|
||||
foreach ($options as $key => $val) {
|
||||
$html = str_ireplace('{' . $key . '}', $val, $html);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = $this->getContent($el);
|
||||
|
||||
$html = str_ireplace('{param}', $content, $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function getContent(ElementNode $el)
|
||||
{
|
||||
if ($this->parseContent()) {
|
||||
$content = "";
|
||||
foreach ($el->getChildren() as $child) {
|
||||
$content .= $child->getAsHTML();
|
||||
}
|
||||
} else {
|
||||
$content = "";
|
||||
foreach ($el->getChildren() as $child) {
|
||||
$content .= $child->getAsBBCode();
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an ElementNode that is defined by this CodeDefinition and returns the text
|
||||
* representation of the element. This may be overridden by a custom CodeDefinition.
|
||||
*
|
||||
* @param ElementNode $el the element to return a text representation of
|
||||
*
|
||||
* @return string the text representation of $el
|
||||
*/
|
||||
public function asText(ElementNode $el)
|
||||
{
|
||||
if (!$this->hasValidInputs($el)) {
|
||||
return $el->getAsBBCode();
|
||||
}
|
||||
|
||||
$s = "";
|
||||
foreach ($el->getChildren() as $child) {
|
||||
$s .= $child->getAsText();
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag name of this code definition
|
||||
*
|
||||
* @return string this definition's associated tag name
|
||||
*/
|
||||
public function getTagName()
|
||||
{
|
||||
return $this->tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the replacement text of this code definition. This usually has little, if any meaning if the
|
||||
* CodeDefinition class was extended. For default, html replacement CodeDefinitions this returns the html
|
||||
* markup for the definition.
|
||||
*
|
||||
* @return string the replacement text of this CodeDefinition
|
||||
*/
|
||||
public function getReplacementText()
|
||||
{
|
||||
return $this->replacementText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this CodeDefinition uses the optional {option}
|
||||
*
|
||||
* @return boolean true if this CodeDefinition uses the option, false otherwise
|
||||
*/
|
||||
public function usesOption()
|
||||
{
|
||||
return $this->useOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this CodeDefinition parses elements contained within it,
|
||||
* or just treats its children as text.
|
||||
*
|
||||
* @return boolean true if this CodeDefinition parses elements contained within itself
|
||||
*/
|
||||
public function parseContent()
|
||||
{
|
||||
return $this->parseContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the limit of how many elements defined by this CodeDefinition may be
|
||||
* nested together. If after parsing elements are nested beyond this limit, the
|
||||
* subtrees formed by those nodes will be removed from the parse tree. A nest
|
||||
* limit of -1 signifies no limit.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getNestLimit()
|
||||
{
|
||||
return $this->nestLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag name of this CodeDefinition
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $tagName the new tag name of this definition
|
||||
*/
|
||||
public function setTagName($tagName)
|
||||
{
|
||||
$this->tagName = strtolower($tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the html replacement text of this CodeDefinition
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $txt the new replacement text
|
||||
*/
|
||||
public function setReplacementText($txt)
|
||||
{
|
||||
$this->replacementText = $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not this CodeDefinition uses the {option}
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param boolean $bool
|
||||
*/
|
||||
public function setUseOption($bool)
|
||||
{
|
||||
$this->useOption = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not this CodeDefinition allows its children to be parsed as html
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param boolean $bool
|
||||
*/
|
||||
public function setParseContent($bool)
|
||||
{
|
||||
$this->parseContent = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the element counter. This is used for tracking depth of elements of the same type for next limits.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function incrementCounter()
|
||||
{
|
||||
$this->elCounter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the element counter.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function decrementCounter()
|
||||
{
|
||||
$this->elCounter--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the element counter.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function resetCounter()
|
||||
{
|
||||
$this->elCounter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value of the element counter.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return $this->elCounter;
|
||||
}
|
||||
}
|
||||
174
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinitionBuilder.php
vendored
Normal file
174
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinitionBuilder.php
vendored
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once "CodeDefinition.php";
|
||||
|
||||
/**
|
||||
* Implements the builder pattern for the CodeDefinition class. A builder
|
||||
* is the recommended way of constructing CodeDefinition objects.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class CodeDefinitionBuilder
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
protected $tagName;
|
||||
/** @var boolean */
|
||||
protected $useOption = false;
|
||||
/** @var string */
|
||||
protected $replacementText;
|
||||
/** @var boolean */
|
||||
protected $parseContent = true;
|
||||
/** @var integer */
|
||||
protected $nestLimit = -1;
|
||||
/** @var array[string]InputValidator The input validators to run options through */
|
||||
protected $optionValidator = array();
|
||||
/** @var InputValidator */
|
||||
protected $bodyValidator = null;
|
||||
|
||||
/**
|
||||
* Construct a CodeDefinitionBuilder.
|
||||
*
|
||||
* @param string $tagName the tag name of the definition to build
|
||||
* @param string $replacementText the replacement text of the definition to build
|
||||
*/
|
||||
public function __construct($tagName, $replacementText)
|
||||
{
|
||||
$this->tagName = $tagName;
|
||||
$this->replacementText = $replacementText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag name the CodeDefinition should be built with.
|
||||
*
|
||||
* @param string $tagName the tag name for the new CodeDefinition
|
||||
* @return self
|
||||
*/
|
||||
public function setTagName($tagName)
|
||||
{
|
||||
$this->tagName = $tagName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the replacement text that the new CodeDefinition should be
|
||||
* built with.
|
||||
*
|
||||
* @param string $replacementText the replacement text for the new CodeDefinition
|
||||
* @return self
|
||||
*/
|
||||
public function setReplacementText($replacementText)
|
||||
{
|
||||
$this->replacementText = $replacementText;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the built CodeDefinition should use the {option} bbcode
|
||||
* argument.
|
||||
*
|
||||
* @param boolean $option true iff the definition includes an option
|
||||
* @return self
|
||||
*/
|
||||
public function setUseOption($option)
|
||||
{
|
||||
$this->useOption = $option;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the built CodeDefinition should allow its content
|
||||
* to be parsed and evaluated as bbcode.
|
||||
*
|
||||
* @param boolean $parseContent true iff the content should be parsed
|
||||
* @return self
|
||||
*/
|
||||
public function setParseContent($parseContent)
|
||||
{
|
||||
$this->parseContent = $parseContent;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nest limit for this code definition.
|
||||
*
|
||||
* @param integer $limit a positive integer, or -1 if there is no limit.
|
||||
* @throws \InvalidArgumentException if the nest limit is invalid
|
||||
* @return self
|
||||
*/
|
||||
public function setNestLimit($limit)
|
||||
{
|
||||
if (!is_int($limit) || ($limit <= 0 && -1 != $limit)) {
|
||||
throw new \InvalidArgumentException("A nest limit must be a positive integer " .
|
||||
"or -1.");
|
||||
}
|
||||
$this->nestLimit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the InputValidator that option arguments should be validated with.
|
||||
*
|
||||
* @param InputValidator $validator the InputValidator instance to use
|
||||
* @return self
|
||||
*/
|
||||
public function setOptionValidator(\JBBCode\InputValidator $validator, $option=null)
|
||||
{
|
||||
if (empty($option)) {
|
||||
$option = $this->tagName;
|
||||
}
|
||||
$this->optionValidator[$option] = $validator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the InputValidator that body ({param}) text should be validated with.
|
||||
*
|
||||
* @param InputValidator $validator the InputValidator instance to use
|
||||
* @return self
|
||||
*/
|
||||
public function setBodyValidator(\JBBCode\InputValidator $validator)
|
||||
{
|
||||
$this->bodyValidator = $validator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the attached option validator if one is attached.
|
||||
* @return self
|
||||
*/
|
||||
public function removeOptionValidator()
|
||||
{
|
||||
$this->optionValidator = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the attached body validator if one is attached.
|
||||
* @return self
|
||||
*/
|
||||
public function removeBodyValidator()
|
||||
{
|
||||
$this->bodyValidator = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a CodeDefinition with the current state of the builder.
|
||||
*
|
||||
* @return CodeDefinition a new CodeDefinition instance
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$definition = CodeDefinition::construct($this->tagName,
|
||||
$this->replacementText,
|
||||
$this->useOption,
|
||||
$this->parseContent,
|
||||
$this->nestLimit,
|
||||
$this->optionValidator,
|
||||
$this->bodyValidator);
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
22
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinitionSet.php
vendored
Normal file
22
common/vendor/jbbcode/jbbcode/JBBCode/CodeDefinitionSet.php
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'CodeDefinition.php';
|
||||
|
||||
use JBBCode\CodeDefinition;
|
||||
|
||||
/**
|
||||
* An interface for sets of code definitions.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
interface CodeDefinitionSet
|
||||
{
|
||||
|
||||
/**
|
||||
* Retrieves the CodeDefinitions within this set as an array.
|
||||
* @return CodeDefinition[]
|
||||
*/
|
||||
public function getCodeDefinitions();
|
||||
}
|
||||
76
common/vendor/jbbcode/jbbcode/JBBCode/DefaultCodeDefinitionSet.php
vendored
Normal file
76
common/vendor/jbbcode/jbbcode/JBBCode/DefaultCodeDefinitionSet.php
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'CodeDefinition.php';
|
||||
require_once 'CodeDefinitionBuilder.php';
|
||||
require_once 'CodeDefinitionSet.php';
|
||||
require_once 'validators/CssColorValidator.php';
|
||||
require_once 'validators/UrlValidator.php';
|
||||
|
||||
/**
|
||||
* Provides a default set of common bbcode definitions.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class DefaultCodeDefinitionSet implements CodeDefinitionSet
|
||||
{
|
||||
|
||||
/** @var CodeDefinition[] The default code definitions in this set. */
|
||||
protected $definitions = array();
|
||||
|
||||
/**
|
||||
* Constructs the default code definitions.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/* [b] bold tag */
|
||||
$builder = new CodeDefinitionBuilder('b', '<strong>{param}</strong>');
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [i] italics tag */
|
||||
$builder = new CodeDefinitionBuilder('i', '<em>{param}</em>');
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [u] underline tag */
|
||||
$builder = new CodeDefinitionBuilder('u', '<u>{param}</u>');
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
$urlValidator = new \JBBCode\validators\UrlValidator();
|
||||
|
||||
/* [url] link tag */
|
||||
$builder = new CodeDefinitionBuilder('url', '<a href="{param}">{param}</a>');
|
||||
$builder->setParseContent(false)->setBodyValidator($urlValidator);
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [url=http://example.com] link tag */
|
||||
$builder = new CodeDefinitionBuilder('url', '<a href="{option}">{param}</a>');
|
||||
$builder->setUseOption(true)->setParseContent(true)->setOptionValidator($urlValidator);
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [img] image tag */
|
||||
$builder = new CodeDefinitionBuilder('img', '<img src="{param}" />');
|
||||
$builder->setUseOption(false)->setParseContent(false)->setBodyValidator($urlValidator);
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [img=alt text] image tag */
|
||||
$builder = new CodeDefinitionBuilder('img', '<img src="{param}" alt="{option}" />');
|
||||
$builder->setUseOption(true)->setParseContent(false)->setBodyValidator($urlValidator);
|
||||
$this->definitions[] = $builder->build();
|
||||
|
||||
/* [color] color tag */
|
||||
$builder = new CodeDefinitionBuilder('color', '<span style="color: {option}">{param}</span>');
|
||||
$builder->setUseOption(true)->setOptionValidator(new \JBBCode\validators\CssColorValidator());
|
||||
$this->definitions[] = $builder->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the default code definitions.
|
||||
*
|
||||
* @return CodeDefinition[]
|
||||
*/
|
||||
public function getCodeDefinitions()
|
||||
{
|
||||
return $this->definitions;
|
||||
}
|
||||
}
|
||||
66
common/vendor/jbbcode/jbbcode/JBBCode/DocumentElement.php
vendored
Normal file
66
common/vendor/jbbcode/jbbcode/JBBCode/DocumentElement.php
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'ElementNode.php';
|
||||
|
||||
/**
|
||||
* A DocumentElement object represents the root of a document tree. All
|
||||
* documents represented by this document model should have one as its root.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class DocumentElement extends ElementNode
|
||||
{
|
||||
/**
|
||||
* Constructs the document element node
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->setTagName("Document");
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.ElementNode::getAsBBCode()
|
||||
*
|
||||
* Returns the BBCode representation of this document
|
||||
*
|
||||
* @return string this document's bbcode representation
|
||||
*/
|
||||
public function getAsBBCode()
|
||||
{
|
||||
$s = "";
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$s .= $child->getAsBBCode();
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.ElementNode::getAsHTML()
|
||||
*
|
||||
* Documents don't add any html. They only exist as a container for their
|
||||
* children, so getAsHTML() simply iterates through the document's children,
|
||||
* returning their html.
|
||||
*
|
||||
* @return string the HTML representation of this document
|
||||
*/
|
||||
public function getAsHTML()
|
||||
{
|
||||
$s = "";
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$s .= $child->getAsHTML();
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
public function accept(NodeVisitor $visitor)
|
||||
{
|
||||
$visitor->visitDocumentElement($this);
|
||||
}
|
||||
}
|
||||
238
common/vendor/jbbcode/jbbcode/JBBCode/ElementNode.php
vendored
Normal file
238
common/vendor/jbbcode/jbbcode/JBBCode/ElementNode.php
vendored
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'Node.php';
|
||||
|
||||
/**
|
||||
* An element within the tree. Consists of a tag name which defines the type of the
|
||||
* element and any number of Node children. It also contains a CodeDefinition matching
|
||||
* the tag name of the element.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class ElementNode extends Node
|
||||
{
|
||||
/** @var string The tagname of this element, for i.e. "b" in [b]bold[/b] */
|
||||
protected $tagName;
|
||||
|
||||
/** @var string[] The attributes, if any, of this element node */
|
||||
protected $attribute;
|
||||
|
||||
/** @var Node[] The child nodes contained within this element */
|
||||
protected $children;
|
||||
|
||||
/** @var CodeDefinition The code definition that defines this element's behavior */
|
||||
protected $codeDefinition;
|
||||
|
||||
/** @var integer How deeply this node is nested */
|
||||
protected $nestDepth;
|
||||
|
||||
/**
|
||||
* Constructs the element node
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->children = array();
|
||||
$this->nestDepth = 0;
|
||||
}
|
||||
|
||||
public function accept(NodeVisitor $nodeVisitor)
|
||||
{
|
||||
$nodeVisitor->visitElementNode($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CodeDefinition that defines this element.
|
||||
*
|
||||
* @return CodeDefinition this element's code definition
|
||||
*/
|
||||
public function getCodeDefinition()
|
||||
{
|
||||
return $this->codeDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CodeDefinition that defines this element.
|
||||
*
|
||||
* @param CodeDefinition $codeDef the code definition that defines this element node
|
||||
*/
|
||||
public function setCodeDefinition(CodeDefinition $codeDef)
|
||||
{
|
||||
$this->codeDefinition = $codeDef;
|
||||
$this->setTagName($codeDef->getTagName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag name of this element.
|
||||
*
|
||||
* @return string the element's tag name
|
||||
*/
|
||||
public function getTagName()
|
||||
{
|
||||
return $this->tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute (used as the option in bbcode definitions) of this element.
|
||||
*
|
||||
* @return array the attributes of this element
|
||||
*/
|
||||
public function getAttribute()
|
||||
{
|
||||
return $this->attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the children of this element.
|
||||
*
|
||||
* @return Node[] an array of this node's child nodes
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsText()
|
||||
*
|
||||
* Returns the element as text (not including any bbcode markup)
|
||||
*
|
||||
* @return string the plain text representation of this node
|
||||
*/
|
||||
public function getAsText()
|
||||
{
|
||||
if ($this->codeDefinition) {
|
||||
return $this->codeDefinition->asText($this);
|
||||
} else {
|
||||
$s = "";
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$s .= $child->getAsText();
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsBBCode()
|
||||
*
|
||||
* Returns the element as bbcode (with all unclosed tags closed)
|
||||
*
|
||||
* @return string the bbcode representation of this element
|
||||
*/
|
||||
public function getAsBBCode()
|
||||
{
|
||||
$str = "[".$this->tagName;
|
||||
if (!empty($this->attribute)) {
|
||||
if (isset($this->attribute[$this->tagName])) {
|
||||
$str .= "=".$this->attribute[$this->tagName];
|
||||
}
|
||||
|
||||
foreach ($this->attribute as $key => $value) {
|
||||
if ($key == $this->tagName) {
|
||||
continue;
|
||||
} else {
|
||||
$str .= " ".$key."=" . $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$str .= "]";
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$str .= $child->getAsBBCode();
|
||||
}
|
||||
$str .= "[/".$this->tagName."]";
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsHTML()
|
||||
*
|
||||
* Returns the element as html with all replacements made
|
||||
*
|
||||
* @return string the html representation of this node
|
||||
*/
|
||||
public function getAsHTML()
|
||||
{
|
||||
if ($this->codeDefinition) {
|
||||
return $this->codeDefinition->asHtml($this);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child to this node's content. A child may be a TextNode, or
|
||||
* another ElementNode... or anything else that may extend the
|
||||
* abstract Node class.
|
||||
*
|
||||
* @param Node $child the node to add as a child
|
||||
*/
|
||||
public function addChild(Node $child)
|
||||
{
|
||||
$this->children[] = $child;
|
||||
$child->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a child from this node's content.
|
||||
*
|
||||
* @param Node $child the child node to remove
|
||||
*/
|
||||
public function removeChild(Node $child)
|
||||
{
|
||||
foreach ($this->children as $key => $value) {
|
||||
if ($value === $child) {
|
||||
unset($this->children[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag name of this element node.
|
||||
*
|
||||
* @param string $tagName the element's new tag name
|
||||
*/
|
||||
public function setTagName($tagName)
|
||||
{
|
||||
$this->tagName = $tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute (option) of this element node.
|
||||
*
|
||||
* @param string[] $attribute the attribute(s) of this element node
|
||||
*/
|
||||
public function setAttribute($attribute)
|
||||
{
|
||||
$this->attribute = $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the parse tree upwards, going from parent to parent, until it finds a
|
||||
* parent who has the given tag name. Returns the parent with the matching tag name
|
||||
* if it exists, otherwise returns null.
|
||||
*
|
||||
* @param string $str the tag name to search for
|
||||
*
|
||||
* @return ElementNode|null the closest parent with the given tag name
|
||||
*/
|
||||
public function closestParentOfType($str)
|
||||
{
|
||||
$str = strtolower($str);
|
||||
$currentEl = $this;
|
||||
|
||||
while (strtolower($currentEl->getTagName()) != $str && $currentEl->hasParent()) {
|
||||
$currentEl = $currentEl->getParent();
|
||||
}
|
||||
|
||||
if (strtolower($currentEl->getTagName()) != $str) {
|
||||
return null;
|
||||
} else {
|
||||
return $currentEl;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
common/vendor/jbbcode/jbbcode/JBBCode/InputValidator.php
vendored
Normal file
21
common/vendor/jbbcode/jbbcode/JBBCode/InputValidator.php
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
/**
|
||||
* Defines an interface for validation filters for bbcode options and
|
||||
* parameters.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
interface InputValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns true iff the given input is valid, false otherwise.
|
||||
* @param string $input
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate($input);
|
||||
}
|
||||
86
common/vendor/jbbcode/jbbcode/JBBCode/Node.php
vendored
Normal file
86
common/vendor/jbbcode/jbbcode/JBBCode/Node.php
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
/**
|
||||
* A node within the document tree.
|
||||
*
|
||||
* Known subclasses: TextNode, ElementNode
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
abstract class Node
|
||||
{
|
||||
/** @var Node Pointer to the parent node of this node */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Returns this node's immediate parent.
|
||||
*
|
||||
* @return Node the node's parent
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this node has a parent.
|
||||
*
|
||||
* @return boolean true if this node has a parent, false otherwise
|
||||
*/
|
||||
public function hasParent()
|
||||
{
|
||||
return $this->parent != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a text node. Returns false otherwise.
|
||||
* (Overridden by TextNode to return true)
|
||||
*
|
||||
* @return boolean true if this node is a text node
|
||||
*/
|
||||
public function isTextNode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the given NodeVisitor. This is part of an implementation
|
||||
* of the Visitor pattern.
|
||||
*
|
||||
* @param NodeVisitor $nodeVisitor the NodeVisitor traversing the graph
|
||||
*/
|
||||
abstract public function accept(NodeVisitor $nodeVisitor);
|
||||
|
||||
/**
|
||||
* Returns this node as text (without any bbcode markup)
|
||||
*
|
||||
* @return string the plain text representation of this node
|
||||
*/
|
||||
abstract public function getAsText();
|
||||
|
||||
/**
|
||||
* Returns this node as bbcode
|
||||
*
|
||||
* @return string the bbcode representation of this node
|
||||
*/
|
||||
abstract public function getAsBBCode();
|
||||
|
||||
/**
|
||||
* Returns this node as HTML
|
||||
*
|
||||
* @return string the html representation of this node
|
||||
*/
|
||||
abstract public function getAsHTML();
|
||||
|
||||
/**
|
||||
* Sets this node's parent to be the given node.
|
||||
*
|
||||
* @param Node $parent the node to set as this node's parent
|
||||
*/
|
||||
public function setParent(Node $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
}
|
||||
18
common/vendor/jbbcode/jbbcode/JBBCode/NodeVisitor.php
vendored
Normal file
18
common/vendor/jbbcode/jbbcode/JBBCode/NodeVisitor.php
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
/**
|
||||
* Defines an interface for a visitor to traverse the node graph.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since January 2013
|
||||
*/
|
||||
interface NodeVisitor
|
||||
{
|
||||
public function visitDocumentElement(DocumentElement $documentElement);
|
||||
|
||||
public function visitTextNode(TextNode $textNode);
|
||||
|
||||
public function visitElementNode(ElementNode $elementNode);
|
||||
}
|
||||
640
common/vendor/jbbcode/jbbcode/JBBCode/Parser.php
vendored
Normal file
640
common/vendor/jbbcode/jbbcode/JBBCode/Parser.php
vendored
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'ElementNode.php';
|
||||
require_once 'TextNode.php';
|
||||
require_once 'DefaultCodeDefinitionSet.php';
|
||||
require_once 'DocumentElement.php';
|
||||
require_once 'CodeDefinition.php';
|
||||
require_once 'CodeDefinitionBuilder.php';
|
||||
require_once 'CodeDefinitionSet.php';
|
||||
require_once 'NodeVisitor.php';
|
||||
require_once 'Tokenizer.php';
|
||||
require_once 'visitors/NestLimitVisitor.php';
|
||||
require_once 'InputValidator.php';
|
||||
|
||||
use JBBCode\CodeDefinition;
|
||||
|
||||
/**
|
||||
* BBCodeParser is the main parser class that constructs and stores the parse tree. Through this class
|
||||
* new bbcode definitions can be added, and documents may be parsed and converted to html/bbcode/plaintext, etc.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
const OPTION_STATE_DEFAULT = 0;
|
||||
const OPTION_STATE_TAGNAME = 1;
|
||||
const OPTION_STATE_KEY = 2;
|
||||
const OPTION_STATE_VALUE = 3;
|
||||
const OPTION_STATE_QUOTED_VALUE = 4;
|
||||
const OPTION_STATE_JAVASCRIPT = 5;
|
||||
|
||||
/** @var DocumentElement The root element of the parse tree */
|
||||
protected $treeRoot;
|
||||
|
||||
/** @var CodeDefinition[] The list of bbcodes to be used by the parser. */
|
||||
protected $bbcodes = array();
|
||||
|
||||
/**
|
||||
* Constructs an instance of the BBCode parser
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->treeRoot = new DocumentElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a simple (text-replacement only) bbcode definition
|
||||
*
|
||||
* @param string $tagName the tag name of the code (for example the b in [b])
|
||||
* @param string $replace the html to use, with {param} and optionally {option} for replacements
|
||||
* @param boolean $useOption whether or not this bbcode uses the secondary {option} replacement
|
||||
* @param boolean $parseContent whether or not to parse the content within these elements
|
||||
* @param integer $nestLimit an optional limit of the number of elements of this kind that can be nested within
|
||||
* each other before the parser stops parsing them.
|
||||
* @param InputValidator $optionValidator the validator to run {option} through
|
||||
* @param InputValidator $bodyValidator the validator to run {param} through (only used if $parseContent == false)
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function addBBCode($tagName, $replace, $useOption = false, $parseContent = true, $nestLimit = -1,
|
||||
InputValidator $optionValidator = null, InputValidator $bodyValidator = null)
|
||||
{
|
||||
$builder = new CodeDefinitionBuilder($tagName, $replace);
|
||||
|
||||
$builder->setUseOption($useOption);
|
||||
$builder->setParseContent($parseContent);
|
||||
$builder->setNestLimit($nestLimit);
|
||||
|
||||
if ($optionValidator) {
|
||||
$builder->setOptionValidator($optionValidator);
|
||||
}
|
||||
|
||||
if ($bodyValidator) {
|
||||
$builder->setBodyValidator($bodyValidator);
|
||||
}
|
||||
|
||||
$this->addCodeDefinition($builder->build());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a complex bbcode definition. You may subclass the CodeDefinition class, instantiate a definition of your new
|
||||
* class and add it to the parser through this method.
|
||||
*
|
||||
* @param CodeDefinition $definition the bbcode definition to add
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function addCodeDefinition(CodeDefinition $definition)
|
||||
{
|
||||
$this->bbcodes[$definition->getTagName()][$definition->usesOption()] = $definition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of CodeDefinitions.
|
||||
*
|
||||
* @param CodeDefinitionSet $set the set of definitions to add
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function addCodeDefinitionSet(CodeDefinitionSet $set)
|
||||
{
|
||||
foreach ($set->getCodeDefinitions() as $def) {
|
||||
$this->addCodeDefinition($def);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire parse tree as text. Only {param} content is returned. BBCode markup will be ignored.
|
||||
*
|
||||
* @return string a text representation of the parse tree
|
||||
*/
|
||||
public function getAsText()
|
||||
{
|
||||
return $this->treeRoot->getAsText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire parse tree as bbcode. This will be identical to the inputted string, except unclosed tags
|
||||
* will be closed.
|
||||
*
|
||||
* @return string a bbcode representation of the parse tree
|
||||
*/
|
||||
public function getAsBBCode()
|
||||
{
|
||||
return $this->treeRoot->getAsBBCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire parse tree as HTML. All BBCode replacements will be made. This is generally the method
|
||||
* you will want to use to retrieve the parsed bbcode.
|
||||
*
|
||||
* @return string a parsed html string
|
||||
*/
|
||||
public function getAsHTML()
|
||||
{
|
||||
return $this->treeRoot->getAsHTML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the given NodeVisitor at the root.
|
||||
*
|
||||
* @param NodeVisitor $nodeVisitor a NodeVisitor
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function accept(NodeVisitor $nodeVisitor)
|
||||
{
|
||||
$this->treeRoot->accept($nodeVisitor);
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Constructs the parse tree from a string of bbcode markup.
|
||||
*
|
||||
* @param string $str the bbcode markup to parse
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function parse($str)
|
||||
{
|
||||
/* Set the tree root back to a fresh DocumentElement. */
|
||||
$this->reset();
|
||||
|
||||
$parent = $this->treeRoot;
|
||||
$tokenizer = new Tokenizer($str);
|
||||
|
||||
while ($tokenizer->hasNext()) {
|
||||
$parent = $this->parseStartState($parent, $tokenizer);
|
||||
if ($parent->getCodeDefinition() && false ===
|
||||
$parent->getCodeDefinition()->parseContent()) {
|
||||
/* We're inside an element that does not allow its contents to be parseable. */
|
||||
$this->parseAsTextUntilClose($parent, $tokenizer);
|
||||
$parent = $parent->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/* We parsed ignoring nest limits. Do an O(n) traversal to remove any elements that
|
||||
* are nested beyond their CodeDefinition's nest limit. */
|
||||
$this->removeOverNestedElements();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any elements that are nested beyond their nest limit from the parse tree. This
|
||||
* method is now deprecated. In a future release its access privileges will be made
|
||||
* protected.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function removeOverNestedElements()
|
||||
{
|
||||
$nestLimitVisitor = new \JBBCode\visitors\NestLimitVisitor();
|
||||
$this->accept($nestLimitVisitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the old parse tree if one exists.
|
||||
*/
|
||||
protected function reset()
|
||||
{
|
||||
// remove any old tree information
|
||||
$this->treeRoot = new DocumentElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a bbcode exists based on its tag name and whether or not it uses an option
|
||||
*
|
||||
* @param string $tagName the bbcode tag name to check
|
||||
* @param boolean $usesOption whether or not the bbcode accepts an option
|
||||
*
|
||||
* @return bool true if the code exists, false otherwise
|
||||
*/
|
||||
public function codeExists($tagName, $usesOption = false)
|
||||
{
|
||||
return isset($this->bbcodes[strtolower($tagName)][$usesOption]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CodeDefinition of a bbcode with the matching tag name and usesOption parameter
|
||||
*
|
||||
* @param string $tagName the tag name of the bbcode being searched for
|
||||
* @param boolean $usesOption whether or not the bbcode accepts an option
|
||||
*
|
||||
* @return CodeDefinition if the bbcode exists, null otherwise
|
||||
*/
|
||||
public function getCode($tagName, $usesOption = false)
|
||||
{
|
||||
if ($this->codeExists($tagName, $usesOption)) {
|
||||
return $this->bbcodes[strtolower($tagName)][$usesOption];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of default, standard bbcode definitions commonly used across the web.
|
||||
*
|
||||
* This method is now deprecated. Please use DefaultCodeDefinitionSet and
|
||||
* addCodeDefinitionSet() instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function loadDefaultCodes()
|
||||
{
|
||||
$defaultSet = new DefaultCodeDefinitionSet();
|
||||
$this->addCodeDefinitionSet($defaultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new text node with the given parent and text string.
|
||||
*
|
||||
* @param ElementNode $parent the parent of the text node
|
||||
* @param string $string the text of the text node
|
||||
*
|
||||
* @return TextNode the newly created TextNode
|
||||
*/
|
||||
protected function createTextNode(ElementNode $parent, $string)
|
||||
{
|
||||
$children = $parent->getChildren();
|
||||
if (!empty($children)) {
|
||||
$lastElement = end($children);
|
||||
reset($children);
|
||||
|
||||
if ($lastElement->isTextNode()) {
|
||||
$lastElement->setValue($lastElement->getValue() . $string);
|
||||
return $lastElement;
|
||||
}
|
||||
}
|
||||
|
||||
$textNode = new TextNode($string);
|
||||
$parent->addChild($textNode);
|
||||
return $textNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* jBBCode parsing logic is loosely modelled after a FSM. While not every function maps
|
||||
* to a unique DFSM state, each function handles the logic of one or more FSM states.
|
||||
* This function handles the beginning parse state when we're not currently in a tag
|
||||
* name.
|
||||
*
|
||||
* @param ElementNode $parent the current parent node we're under
|
||||
* @param Tokenizer $tokenizer the tokenizer we're using
|
||||
*
|
||||
* @return ElementNode the new parent we should use for the next iteration.
|
||||
*/
|
||||
protected function parseStartState(ElementNode $parent, Tokenizer $tokenizer)
|
||||
{
|
||||
$next = $tokenizer->next();
|
||||
|
||||
if ('[' == $next) {
|
||||
return $this->parseTagOpen($parent, $tokenizer);
|
||||
} else {
|
||||
$this->createTextNode($parent, $next);
|
||||
/* Drop back into the main parse loop which will call this
|
||||
* same method again. */
|
||||
return $parent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles parsing the beginnings of an open tag. When we see a [
|
||||
* at an appropriate time, this function is entered.
|
||||
*
|
||||
* @param ElementNode $parent the current parent node
|
||||
* @param Tokenizer $tokenizer the tokenizer we're using
|
||||
*
|
||||
* @return ElementNode the new parent node
|
||||
*/
|
||||
protected function parseTagOpen(ElementNode $parent, Tokenizer $tokenizer)
|
||||
{
|
||||
if (!$tokenizer->hasNext()) {
|
||||
/* The [ that sent us to this state was just a trailing [, not the
|
||||
* opening for a new tag. Treat it as such. */
|
||||
$this->createTextNode($parent, '[');
|
||||
return $parent;
|
||||
}
|
||||
|
||||
$next = $tokenizer->next();
|
||||
|
||||
/* This while loop could be replaced by a recursive call to this same method,
|
||||
* which would likely be a lot clearer but I decided to use a while loop to
|
||||
* prevent stack overflow with a string like [[[[[[[[[...[[[.
|
||||
*/
|
||||
while ('[' == $next) {
|
||||
/* The previous [ was just a random bracket that should be treated as text.
|
||||
* Continue until we get a non open bracket. */
|
||||
$this->createTextNode($parent, '[');
|
||||
if (!$tokenizer->hasNext()) {
|
||||
$this->createTextNode($parent, '[');
|
||||
return $parent;
|
||||
}
|
||||
$next = $tokenizer->next();
|
||||
}
|
||||
|
||||
if (!$tokenizer->hasNext()) {
|
||||
$this->createTextNode($parent, '['.$next);
|
||||
return $parent;
|
||||
}
|
||||
|
||||
$after_next = $tokenizer->next();
|
||||
$tokenizer->stepBack();
|
||||
|
||||
if ($after_next != ']') {
|
||||
$this->createTextNode($parent, '['.$next);
|
||||
return $parent;
|
||||
}
|
||||
|
||||
/* At this point $next is either ']' or plain text. */
|
||||
if (']' == $next) {
|
||||
$this->createTextNode($parent, '[');
|
||||
$this->createTextNode($parent, ']');
|
||||
return $parent;
|
||||
} else {
|
||||
/* $next is plain text... likely a tag name. */
|
||||
return $this->parseTag($parent, $tokenizer, $next);
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseOptions($tagContent)
|
||||
{
|
||||
$buffer = "";
|
||||
$tagName = "";
|
||||
$state = static::OPTION_STATE_TAGNAME;
|
||||
$keys = array();
|
||||
$values = array();
|
||||
$options = array();
|
||||
|
||||
$len = strlen($tagContent);
|
||||
$done = false;
|
||||
$idx = 0;
|
||||
|
||||
try {
|
||||
while (!$done) {
|
||||
$char = $idx < $len ? $tagContent[$idx]:null;
|
||||
switch ($state) {
|
||||
case static::OPTION_STATE_TAGNAME:
|
||||
switch ($char) {
|
||||
case '=':
|
||||
$state = static::OPTION_STATE_VALUE;
|
||||
$tagName = $buffer;
|
||||
$keys[] = $tagName;
|
||||
$buffer = "";
|
||||
break;
|
||||
case ' ':
|
||||
if ($buffer) {
|
||||
$state = static::OPTION_STATE_DEFAULT;
|
||||
$tagName = $buffer;
|
||||
$buffer = '';
|
||||
$keys[] = $tagName;
|
||||
}
|
||||
break;
|
||||
case "\n":
|
||||
case "\r":
|
||||
break;
|
||||
|
||||
case null:
|
||||
$tagName = $buffer;
|
||||
$buffer = '';
|
||||
$keys[] = $tagName;
|
||||
break;
|
||||
default:
|
||||
$buffer .= $char;
|
||||
}
|
||||
break;
|
||||
|
||||
case static::OPTION_STATE_DEFAULT:
|
||||
switch ($char) {
|
||||
case ' ':
|
||||
// do nothing
|
||||
default:
|
||||
$state = static::OPTION_STATE_KEY;
|
||||
$buffer .= $char;
|
||||
}
|
||||
break;
|
||||
|
||||
case static::OPTION_STATE_VALUE:
|
||||
switch ($char) {
|
||||
case '"':
|
||||
$state = static::OPTION_STATE_QUOTED_VALUE;
|
||||
break;
|
||||
case null: // intentional fall-through
|
||||
case ' ': // key=value<space> delimits to next key
|
||||
$values[] = trim($buffer);
|
||||
$buffer = "";
|
||||
$state = static::OPTION_STATE_KEY;
|
||||
break;
|
||||
case ":":
|
||||
if ($buffer=="javascript") {
|
||||
$state = static::OPTION_STATE_JAVASCRIPT;
|
||||
}
|
||||
$buffer .= $char;
|
||||
break;
|
||||
default:
|
||||
$buffer .= $char;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case static::OPTION_STATE_JAVASCRIPT:
|
||||
switch ($char) {
|
||||
case ";":
|
||||
$buffer .= $char;
|
||||
$values[] = $buffer;
|
||||
$buffer = "";
|
||||
$state = static::OPTION_STATE_KEY;
|
||||
|
||||
break;
|
||||
default:
|
||||
$buffer .= $char;
|
||||
}
|
||||
break;
|
||||
|
||||
case static::OPTION_STATE_KEY:
|
||||
switch ($char) {
|
||||
case '=':
|
||||
$state = static::OPTION_STATE_VALUE;
|
||||
$keys[] = trim($buffer);
|
||||
$buffer = '';
|
||||
break;
|
||||
case ' ': // ignore <space>key=value
|
||||
break;
|
||||
default:
|
||||
$buffer .= $char;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case static::OPTION_STATE_QUOTED_VALUE:
|
||||
switch ($char) {
|
||||
case null:
|
||||
case '"':
|
||||
$state = static::OPTION_STATE_KEY;
|
||||
$values[] = $buffer;
|
||||
$buffer = '';
|
||||
|
||||
// peek ahead. If the next character is not a space or a closing brace, we have a bad tag and need to abort
|
||||
if (isset($tagContent[$idx+1]) && $tagContent[$idx+1]!=" " && $tagContent[$idx+1]!="]") {
|
||||
throw new \DomainException("Badly formed attribute: $tagContent");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$buffer .= $char;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!empty($char)) {
|
||||
$state = static::OPTION_STATE_KEY;
|
||||
}
|
||||
|
||||
}
|
||||
if ($idx >= $len) {
|
||||
$done = true;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
|
||||
if (!empty($keys) && !empty($values)) {
|
||||
if (count($keys)==(count($values)+1)) {
|
||||
array_unshift($values, "");
|
||||
}
|
||||
|
||||
$options = array_combine($keys, $values);
|
||||
}
|
||||
} catch (\DomainException $e) {
|
||||
// if we're in this state, then something evidently went wrong. We'll consider everything that came after the tagname to be the attribute for that keyname
|
||||
$options[$tagName]= substr($tagContent, strpos($tagContent, "=")+1);
|
||||
}
|
||||
return array($tagName, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the next step in parsing a tag. It's possible for it to still be invalid at this
|
||||
* point but many of the basic invalid tag name conditions have already been handled.
|
||||
*
|
||||
* @param ElementNode $parent the current parent element
|
||||
* @param Tokenizer $tokenizer the tokenizer we're using
|
||||
* @param string $tagContent the text between the [ and the ], assuming there is actually a ]
|
||||
*
|
||||
* @return ElementNode the new parent element
|
||||
*/
|
||||
protected function parseTag(ElementNode $parent, Tokenizer $tokenizer, $tagContent)
|
||||
{
|
||||
if (!$tokenizer->hasNext() || ($next = $tokenizer->next()) != ']') {
|
||||
/* This is a malformed tag. Both the previous [ and the tagContent
|
||||
* is really just plain text. */
|
||||
$this->createTextNode($parent, '[');
|
||||
$this->createTextNode($parent, $tagContent);
|
||||
return $parent;
|
||||
}
|
||||
|
||||
/* This is a well-formed tag consisting of [something] or [/something], but
|
||||
* we still need to ensure that 'something' is a valid tag name. Additionally,
|
||||
* if it's a closing tag, we need to ensure that there was a previous matching
|
||||
* opening tag.
|
||||
*/
|
||||
/* There could be attributes. */
|
||||
list($tmpTagName, $options) = $this->parseOptions($tagContent);
|
||||
|
||||
// $tagPieces = explode('=', $tagContent);
|
||||
// $tmpTagName = $tagPieces[0];
|
||||
|
||||
$actualTagName = $tmpTagName;
|
||||
if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
|
||||
/* This is a closing tag name. */
|
||||
$actualTagName = substr($tmpTagName, 1);
|
||||
}
|
||||
|
||||
if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
|
||||
/* This is attempting to close an open tag. We must verify that there exists an
|
||||
* open tag of the same type and that there is no option (options on closing
|
||||
* tags don't make any sense). */
|
||||
$elToClose = $parent->closestParentOfType($actualTagName);
|
||||
if (null == $elToClose || count($options) > 1) {
|
||||
/* Closing an unopened tag or has an option. Treat everything as plain text. */
|
||||
$this->createTextNode($parent, '[');
|
||||
$this->createTextNode($parent, $tagContent);
|
||||
$this->createTextNode($parent, ']');
|
||||
return $parent;
|
||||
} else {
|
||||
/* We're closing $elToClose. In order to do that, we just need to return
|
||||
* $elToClose's parent, since that will change our effective parent to be
|
||||
* elToClose's parent. */
|
||||
return $elToClose->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that this is a known bbcode tag name. */
|
||||
if ('' == $actualTagName || !$this->codeExists($actualTagName, !empty($options))) {
|
||||
/* This is an invalid tag name! Treat everything we've seen as plain text. */
|
||||
$this->createTextNode($parent, '[');
|
||||
$this->createTextNode($parent, $tagContent);
|
||||
$this->createTextNode($parent, ']');
|
||||
return $parent;
|
||||
}
|
||||
|
||||
/* If we're here, this is a valid opening tag. Let's make a new node for it. */
|
||||
$el = new ElementNode();
|
||||
$code = $this->getCode($actualTagName, !empty($options));
|
||||
$el->setCodeDefinition($code);
|
||||
if (!empty($options)) {
|
||||
/* We have an attribute we should save. */
|
||||
$el->setAttribute($options);
|
||||
}
|
||||
$parent->addChild($el);
|
||||
return $el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles parsing elements whose CodeDefinitions disable parsing of element
|
||||
* contents. This function uses a rolling window of 3 tokens until it finds the
|
||||
* appropriate closing tag or reaches the end of the token stream.
|
||||
*
|
||||
* @param ElementNode $parent the current parent element
|
||||
* @param Tokenizer $tokenizer the tokenizer we're using
|
||||
*
|
||||
* @return ElementNode the new parent element
|
||||
*/
|
||||
protected function parseAsTextUntilClose(ElementNode $parent, Tokenizer $tokenizer)
|
||||
{
|
||||
/* $parent's code definition doesn't allow its contents to be parsed. Here we use
|
||||
* a sliding window of three tokens until we find [ /tagname ], signifying the
|
||||
* end of the parent. */
|
||||
if (!$tokenizer->hasNext()) {
|
||||
return $parent;
|
||||
}
|
||||
$prevPrev = $tokenizer->next();
|
||||
if (!$tokenizer->hasNext()) {
|
||||
$this->createTextNode($parent, $prevPrev);
|
||||
return $parent;
|
||||
}
|
||||
$prev = $tokenizer->next();
|
||||
if (!$tokenizer->hasNext()) {
|
||||
$this->createTextNode($parent, $prevPrev);
|
||||
$this->createTextNode($parent, $prev);
|
||||
return $parent;
|
||||
}
|
||||
$curr = $tokenizer->next();
|
||||
while ('[' != $prevPrev || '/'.$parent->getTagName() != strtolower($prev) ||
|
||||
']' != $curr) {
|
||||
$this->createTextNode($parent, $prevPrev);
|
||||
$prevPrev = $prev;
|
||||
$prev = $curr;
|
||||
if (!$tokenizer->hasNext()) {
|
||||
$this->createTextNode($parent, $prevPrev);
|
||||
$this->createTextNode($parent, $prev);
|
||||
return $parent;
|
||||
}
|
||||
$curr = $tokenizer->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
101
common/vendor/jbbcode/jbbcode/JBBCode/TextNode.php
vendored
Normal file
101
common/vendor/jbbcode/jbbcode/JBBCode/TextNode.php
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
require_once 'Node.php';
|
||||
|
||||
/**
|
||||
* Represents a piece of text data. TextNodes never have children.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class TextNode extends Node
|
||||
{
|
||||
/** @var string The value of this text node */
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* Constructs a text node from its text string
|
||||
*
|
||||
* @param string $val
|
||||
*/
|
||||
public function __construct($val)
|
||||
{
|
||||
$this->value = $val;
|
||||
}
|
||||
|
||||
public function accept(NodeVisitor $visitor)
|
||||
{
|
||||
$visitor->visitTextNode($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::isTextNode()
|
||||
*
|
||||
* @returns boolean true
|
||||
*/
|
||||
public function isTextNode()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text string value of this text node.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsText()
|
||||
*
|
||||
* Returns the text representation of this node.
|
||||
*
|
||||
* @return string this node represented as text
|
||||
*/
|
||||
public function getAsText()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsBBCode()
|
||||
*
|
||||
* Returns the bbcode representation of this node. (Just its value)
|
||||
*
|
||||
* @return string this node represented as bbcode
|
||||
*/
|
||||
public function getAsBBCode()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see JBBCode.Node::getAsHTML()
|
||||
*
|
||||
* Returns the html representation of this node. (Just its value)
|
||||
*
|
||||
* @return string this node represented as HTML
|
||||
*/
|
||||
public function getAsHTML()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the text value contained within this text node.
|
||||
*
|
||||
* @param string $newValue the new text value of the text node
|
||||
*/
|
||||
public function setValue($newValue)
|
||||
{
|
||||
$this->value = $newValue;
|
||||
}
|
||||
}
|
||||
106
common/vendor/jbbcode/jbbcode/JBBCode/Tokenizer.php
vendored
Normal file
106
common/vendor/jbbcode/jbbcode/JBBCode/Tokenizer.php
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode;
|
||||
|
||||
/**
|
||||
* This Tokenizer is used while constructing the parse tree. The tokenizer
|
||||
* handles splitting the input into brackets and miscellaneous text. The
|
||||
* parser is then built as a FSM ontop of these possible inputs.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class Tokenizer
|
||||
{
|
||||
|
||||
/** @var integer[] the positions of tokens found during parsing */
|
||||
protected $tokens = array();
|
||||
|
||||
/** @var integer the number of the current token */
|
||||
protected $i = -1;
|
||||
|
||||
/**
|
||||
* Constructs a tokenizer from the given string. The string will be tokenized
|
||||
* upon construction.
|
||||
*
|
||||
* @param string $str the string to tokenize
|
||||
*/
|
||||
public function __construct($str)
|
||||
{
|
||||
$strLen = strlen($str);
|
||||
$position = 0;
|
||||
|
||||
while ($position < $strLen) {
|
||||
$offset = strcspn($str, '[]', $position);
|
||||
//Have we hit a single ']' or '['?
|
||||
if ($offset == 0) {
|
||||
$this->tokens[] = $str[$position];
|
||||
$position++;
|
||||
} else {
|
||||
$this->tokens[] = substr($str, $position, $offset);
|
||||
$position += $offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is another token in the token stream.
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasNext()
|
||||
{
|
||||
return isset($this->tokens[$this->i + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the token stream to the next token and returns the new token.
|
||||
* @return null|string
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
if (!$this->hasNext()) {
|
||||
return null;
|
||||
} else {
|
||||
return $this->tokens[++$this->i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current token.
|
||||
* @return null|string
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->i < 0) {
|
||||
return null;
|
||||
} else {
|
||||
return $this->tokens[$this->i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the token stream back a token.
|
||||
*/
|
||||
public function stepBack()
|
||||
{
|
||||
if ($this->i > -1) {
|
||||
$this->i--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts the tokenizer, returning to the beginning of the token stream.
|
||||
*/
|
||||
public function restart()
|
||||
{
|
||||
$this->i = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString method that returns the entire string from the current index on.
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return implode('', array_slice($this->tokens, $this->i + 1));
|
||||
}
|
||||
}
|
||||
12
common/vendor/jbbcode/jbbcode/JBBCode/examples/1-GettingStarted.php
vendored
Normal file
12
common/vendor/jbbcode/jbbcode/JBBCode/examples/1-GettingStarted.php
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
require_once "/path/to/jbbcode/Parser.php";
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
$text = "The default codes include: [b]bold[/b], [i]italics[/i], [u]underlining[/u], ";
|
||||
$text .= "[url=http://jbbcode.com]links[/url], [color=red]color![/color] and more.";
|
||||
|
||||
$parser->parse($text);
|
||||
|
||||
print $parser->getAsHtml();
|
||||
10
common/vendor/jbbcode/jbbcode/JBBCode/examples/2-ClosingUnclosedTags.php
vendored
Normal file
10
common/vendor/jbbcode/jbbcode/JBBCode/examples/2-ClosingUnclosedTags.php
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
require_once "/path/to/jbbcode/Parser.php";
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
$text = "The bbcode in here [b]is never closed!";
|
||||
$parser->parse($text);
|
||||
|
||||
print $parser->getAsBBCode();
|
||||
11
common/vendor/jbbcode/jbbcode/JBBCode/examples/3-MarkuplessText.php
vendored
Normal file
11
common/vendor/jbbcode/jbbcode/JBBCode/examples/3-MarkuplessText.php
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
require_once "/path/to/jbbcode/Parser.php";
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
$text = "[b][u]There is [i]a lot[/i] of [url=http://en.wikipedia.org/wiki/Markup_language]markup[/url] in this";
|
||||
$text .= "[color=#333333]text[/color]![/u][/b]";
|
||||
$parser->parse($text);
|
||||
|
||||
print $parser->getAsText();
|
||||
7
common/vendor/jbbcode/jbbcode/JBBCode/examples/4-CreatingNewCodes.php
vendored
Normal file
7
common/vendor/jbbcode/jbbcode/JBBCode/examples/4-CreatingNewCodes.php
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
require_once "/path/to/jbbcode/Parser.php";
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
|
||||
$parser->addBBCode("quote", '<div class="quote">{param}</div>');
|
||||
$parser->addBBCode("code", '<pre class="code">{param}</pre>', false, false, 1);
|
||||
22
common/vendor/jbbcode/jbbcode/JBBCode/examples/SmileyVisitorTest.php
vendored
Normal file
22
common/vendor/jbbcode/jbbcode/JBBCode/examples/SmileyVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
require_once("../Parser.php");
|
||||
require_once("../visitors/SmileyVisitor.php");
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
if (count($argv) < 2) {
|
||||
die("Usage: " . $argv[0] . " \"bbcode string\"\n");
|
||||
}
|
||||
|
||||
$inputText = $argv[1];
|
||||
|
||||
$parser->parse($inputText);
|
||||
|
||||
$smileyVisitor = new \JBBCode\visitors\SmileyVisitor();
|
||||
$parser->accept($smileyVisitor);
|
||||
|
||||
echo $parser->getAsHTML() . "\n";
|
||||
23
common/vendor/jbbcode/jbbcode/JBBCode/examples/TagCountingVisitorTest.php
vendored
Normal file
23
common/vendor/jbbcode/jbbcode/JBBCode/examples/TagCountingVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
require_once("../Parser.php");
|
||||
require_once("../visitors/TagCountingVisitor.php");
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
if (count($argv) < 3) {
|
||||
die("Usage: " . $argv[0] . " \"bbcode string\" <tag name to check>\n");
|
||||
}
|
||||
|
||||
$inputText = $argv[1];
|
||||
$tagName = $argv[2];
|
||||
|
||||
$parser->parse($inputText);
|
||||
|
||||
$tagCountingVisitor = new \JBBCode\visitors\TagCountingVisitor();
|
||||
$parser->accept($tagCountingVisitor);
|
||||
|
||||
echo $tagCountingVisitor->getFrequency($tagName) . "\n";
|
||||
141
common/vendor/jbbcode/jbbcode/JBBCode/tests/CodeDefinitionBuilderTest.php
vendored
Normal file
141
common/vendor/jbbcode/jbbcode/JBBCode/tests/CodeDefinitionBuilderTest.php
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
class CodeDefinitionBuilderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var CodeDefinitionBuilderStub
|
||||
*/
|
||||
private $_builder;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_builder = new CodeDefinitionBuilderStub('foo', 'bar');
|
||||
}
|
||||
|
||||
public function testConstructor()
|
||||
{
|
||||
$codeDefinition = $this->_builder->build();
|
||||
$this->assertInstanceOf('JBBCode\CodeDefinition', $codeDefinition);
|
||||
$this->assertEquals('foo', $codeDefinition->getTagName());
|
||||
$this->assertEquals('bar', $codeDefinition->getReplacementText());
|
||||
}
|
||||
|
||||
public function testSetTagName()
|
||||
{
|
||||
$this->assertSame($this->_builder, $this->_builder->setTagName('baz'));
|
||||
$this->assertEquals('baz', $this->_builder->build()->getTagName());
|
||||
}
|
||||
|
||||
public function testSetReplacementText()
|
||||
{
|
||||
$this->assertSame($this->_builder, $this->_builder->setReplacementText('baz'));
|
||||
$this->assertEquals('baz', $this->_builder->build()->getReplacementText());
|
||||
}
|
||||
|
||||
public function testSetUseOption()
|
||||
{
|
||||
$this->assertFalse($this->_builder->build()->usesOption());
|
||||
$this->assertSame($this->_builder, $this->_builder->setUseOption(true));
|
||||
$this->assertTrue($this->_builder->build()->usesOption());
|
||||
}
|
||||
|
||||
public function testSetParseContent()
|
||||
{
|
||||
$this->assertTrue($this->_builder->build()->parseContent());
|
||||
$this->assertSame($this->_builder, $this->_builder->setParseContent(false));
|
||||
$this->assertFalse($this->_builder->build()->parseContent());
|
||||
}
|
||||
|
||||
public function testSetNestLimit()
|
||||
{
|
||||
$this->assertEquals(-1, $this->_builder->build()->getNestLimit());
|
||||
$this->assertSame($this->_builder, $this->_builder->setNestLimit(1));
|
||||
$this->assertEquals(1, $this->_builder->build()->getNestLimit());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @dataProvider invalidNestLimitProvider
|
||||
*/
|
||||
public function testSetInvalidNestLimit($limit)
|
||||
{
|
||||
$this->_builder->setNestLimit($limit);
|
||||
}
|
||||
|
||||
public function testSetOptionValidator()
|
||||
{
|
||||
$this->assertEmpty($this->_builder->getOptionValidators());
|
||||
$urlValidator = new JBBCode\validators\UrlValidator();
|
||||
$this->assertSame($this->_builder, $this->_builder->setOptionValidator($urlValidator));
|
||||
$this->assertArrayHasKey('foo', $this->_builder->getOptionValidators());
|
||||
$this->assertContains($urlValidator, $this->_builder->getOptionValidators());
|
||||
|
||||
$otherUrlValidator = new JBBCode\validators\UrlValidator();
|
||||
$this->assertSame($this->_builder, $this->_builder->setOptionValidator($otherUrlValidator, 'url'));
|
||||
$this->assertArrayHasKey('url', $this->_builder->getOptionValidators());
|
||||
$this->assertContains($urlValidator, $this->_builder->getOptionValidators());
|
||||
$this->assertContains($otherUrlValidator, $this->_builder->getOptionValidators());
|
||||
}
|
||||
|
||||
public function testSetBodyValidator()
|
||||
{
|
||||
$this->assertNull($this->_builder->getBodyValidator());
|
||||
$validator = new JBBCode\validators\UrlValidator();
|
||||
$this->assertSame($this->_builder, $this->_builder->setBodyValidator($validator));
|
||||
$this->assertSame($validator, $this->_builder->getBodyValidator());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetOptionValidator
|
||||
*/
|
||||
public function testRemoveOptionValidator()
|
||||
{
|
||||
$this->assertSame($this->_builder, $this->_builder->removeOptionValidator());
|
||||
$this->assertEmpty($this->_builder->getOptionValidators());
|
||||
$this->_builder->setOptionValidator(new JBBCode\validators\UrlValidator());
|
||||
$this->assertSame($this->_builder, $this->_builder->removeOptionValidator());
|
||||
$this->assertEmpty($this->_builder->getOptionValidators());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetBodyValidator
|
||||
*/
|
||||
public function testRemoveBodyValidator()
|
||||
{
|
||||
$this->assertSame($this->_builder, $this->_builder->removeBodyValidator());
|
||||
$this->assertNull($this->_builder->getBodyValidator());
|
||||
$this->_builder->setOptionValidator(new JBBCode\validators\UrlValidator());
|
||||
$this->assertSame($this->_builder, $this->_builder->removeBodyValidator());
|
||||
$this->assertNull($this->_builder->getBodyValidator());
|
||||
}
|
||||
|
||||
public function invalidNestLimitProvider()
|
||||
{
|
||||
return array(
|
||||
array(-2),
|
||||
array(null),
|
||||
array(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CodeDefinitionBuilderStub extends \JBBCode\CodeDefinitionBuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \JBBCode\InputValidator
|
||||
*/
|
||||
public function getBodyValidator()
|
||||
{
|
||||
return $this->bodyValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \JBBCode\InputValidator[]
|
||||
*/
|
||||
public function getOptionValidators()
|
||||
{
|
||||
return $this->optionValidator;
|
||||
}
|
||||
}
|
||||
37
common/vendor/jbbcode/jbbcode/JBBCode/tests/DefaultCodeDefinitionSetTest.php
vendored
Normal file
37
common/vendor/jbbcode/jbbcode/JBBCode/tests/DefaultCodeDefinitionSetTest.php
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test cases for the default bbcode set.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class DefaultCodeDefinitionSetTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetCodeDefinitions()
|
||||
{
|
||||
$dcds = new JBBCode\DefaultCodeDefinitionSet();
|
||||
$definitions = $dcds->getCodeDefinitions();
|
||||
$this->assertInternalType('array', $definitions);
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
|
||||
$this->assertFalse($parser->codeExists('b'));
|
||||
$this->assertFalse($parser->codeExists('i'));
|
||||
$this->assertFalse($parser->codeExists('u'));
|
||||
$this->assertFalse($parser->codeExists('url', true));
|
||||
$this->assertFalse($parser->codeExists('img'));
|
||||
$this->assertFalse($parser->codeExists('img', true));
|
||||
$this->assertFalse($parser->codeExists('color', true));
|
||||
|
||||
$parser->addCodeDefinitionSet($dcds);
|
||||
|
||||
$this->assertTrue($parser->codeExists('b'));
|
||||
$this->assertTrue($parser->codeExists('i'));
|
||||
$this->assertTrue($parser->codeExists('u'));
|
||||
$this->assertTrue($parser->codeExists('url', true));
|
||||
$this->assertTrue($parser->codeExists('img'));
|
||||
$this->assertTrue($parser->codeExists('img', true));
|
||||
$this->assertTrue($parser->codeExists('color', true));
|
||||
}
|
||||
}
|
||||
80
common/vendor/jbbcode/jbbcode/JBBCode/tests/ElementNodeTest.php
vendored
Normal file
80
common/vendor/jbbcode/jbbcode/JBBCode/tests/ElementNodeTest.php
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
class ElementNodeTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var JBBCode\ElementNode */
|
||||
private $_elementNode;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_elementNode = new JBBCode\ElementNode();
|
||||
}
|
||||
|
||||
public function testConstructor()
|
||||
{
|
||||
$this->assertNull($this->_elementNode->getCodeDefinition());
|
||||
$this->assertEmpty($this->_elementNode->getTagName());
|
||||
$this->assertEmpty($this->_elementNode->getAttribute());
|
||||
$this->assertEmpty($this->_elementNode->getChildren());
|
||||
$this->assertEmpty($this->_elementNode->getAsText());
|
||||
$this->assertEmpty($this->_elementNode->getAsHTML());
|
||||
}
|
||||
|
||||
public function testAccept()
|
||||
{
|
||||
$mock = $this->getMock('JBBCode\NodeVisitor',
|
||||
array('visitDocumentElement', 'visitTextNode', 'visitElementNode'));
|
||||
$mock->expects($this->never())
|
||||
->method('visitDocumentElement');
|
||||
$mock->expects($this->never())
|
||||
->method('visitTextNode');
|
||||
$mock->expects($this->once())
|
||||
->method('visitElementNode')
|
||||
->with($this->equalTo($this->_elementNode));
|
||||
$this->_elementNode->accept($mock);
|
||||
}
|
||||
|
||||
public function testSetCodeDefinition()
|
||||
{
|
||||
$mock = $this->getMock('JBBCode\CodeDefinition', array('getTagName'));
|
||||
$mock->expects($this->once())
|
||||
->method('getTagName')
|
||||
->will($this->returnValue('foo'));
|
||||
$this->_elementNode->setCodeDefinition($mock);
|
||||
$this->assertSame($mock, $this->_elementNode->getCodeDefinition());
|
||||
$this->assertEquals('foo', $this->_elementNode->getTagName());
|
||||
}
|
||||
|
||||
public function testAddChild()
|
||||
{
|
||||
$mock = $this->getMock('JBBCode\ElementNode', array('setParent'));
|
||||
$mock->expects($this->once())
|
||||
->method('setParent')
|
||||
->with($this->equalTo($this->_elementNode));
|
||||
$this->_elementNode->addChild($mock);
|
||||
$this->assertContains($mock, $this->_elementNode->getChildren());
|
||||
}
|
||||
|
||||
public function testIsTextNode()
|
||||
{
|
||||
$this->assertFalse($this->_elementNode->isTextNode());
|
||||
}
|
||||
|
||||
public function testGetAsBBCode()
|
||||
{
|
||||
$builder = new JBBCode\CodeDefinitionBuilder('foo', 'bar');
|
||||
$codeDefinition = $builder->build();
|
||||
$this->_elementNode->setCodeDefinition($codeDefinition);
|
||||
$this->assertEquals('[foo][/foo]', $this->_elementNode->getAsBBCode());
|
||||
|
||||
$this->_elementNode->setAttribute(array('bar' => 'baz'));
|
||||
$this->assertEquals('[foo bar=baz][/foo]', $this->_elementNode->getAsBBCode());
|
||||
|
||||
/** @ticket 55 */
|
||||
$this->_elementNode->setAttribute(array(
|
||||
'bar' => 'baz',
|
||||
'foo' => 'bar'
|
||||
));
|
||||
$this->assertEquals('[foo=bar bar=baz][/foo]', $this->_elementNode->getAsBBCode());
|
||||
}
|
||||
}
|
||||
91
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParseContentTest.php
vendored
Normal file
91
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParseContentTest.php
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test cases for the code definition parameter that disallows parsing
|
||||
* of an element's content.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class ParseContentTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var JBBCode\Parser
|
||||
*/
|
||||
private $_parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_parser = new JBBCode\Parser();
|
||||
$this->_parser->addCodeDefinitionSet(new JBBcode\DefaultCodeDefinitionSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that when a bbcode is created with parseContent = false,
|
||||
* its contents actually are not parsed.
|
||||
*/
|
||||
public function testSimpleNoParsing()
|
||||
{
|
||||
$this->_parser->addBBCode('verbatim', '{param}', false, false);
|
||||
|
||||
$this->_parser->parse('[verbatim]plain text[/verbatim]');
|
||||
$this->assertEquals('plain text', $this->_parser->getAsHtml());
|
||||
|
||||
$this->_parser->parse('[verbatim][b]bold[/b][/verbatim]');
|
||||
$this->assertEquals('[b]bold[/b]', $this->_parser->getAsHtml());
|
||||
}
|
||||
|
||||
public function testNoParsingWithBufferText()
|
||||
{
|
||||
$this->_parser->addBBCode('verbatim', '{param}', false, false);
|
||||
|
||||
$this->_parser->parse('buffer text[verbatim]buffer text[b]bold[/b]buffer text[/verbatim]buffer text');
|
||||
$this->assertEquals('buffer textbuffer text[b]bold[/b]buffer textbuffer text', $this->_parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that when a tag is not closed within an unparseable tag,
|
||||
* the BBCode output does not automatically close that tag (because
|
||||
* the contents were not parsed).
|
||||
*/
|
||||
public function testUnclosedTag()
|
||||
{
|
||||
$this->_parser->addBBCode('verbatim', '{param}', false, false);
|
||||
|
||||
$this->_parser->parse('[verbatim]i wonder [b]what will happen[/verbatim]');
|
||||
$this->assertEquals('i wonder [b]what will happen', $this->_parser->getAsHtml());
|
||||
$this->assertEquals('[verbatim]i wonder [b]what will happen[/verbatim]', $this->_parser->getAsBBCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an unclosed tag with parseContent = false ends cleanly.
|
||||
*/
|
||||
public function testUnclosedVerbatimTag()
|
||||
{
|
||||
$this->_parser->addBBCode('verbatim', '{param}', false, false);
|
||||
|
||||
$this->_parser->parse('[verbatim]yo this [b]text should not be bold[/b]');
|
||||
$this->assertEquals('yo this [b]text should not be bold[/b]', $this->_parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a malformed closing tag for a verbatim block.
|
||||
*/
|
||||
public function testMalformedVerbatimClosingTag()
|
||||
{
|
||||
$this->_parser->addBBCode('verbatim', '{param}', false, false);
|
||||
$this->_parser->parse('[verbatim]yo this [b]text should not be bold[/b][/verbatim');
|
||||
$this->assertEquals('yo this [b]text should not be bold[/b][/verbatim', $this->_parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an immediate end after a verbatim.
|
||||
*/
|
||||
public function testVerbatimThenEof()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addBBCode('verbatim', '{param}', false, false);
|
||||
$parser->parse('[verbatim]');
|
||||
$this->assertEquals('', $parser->getAsHtml());
|
||||
}
|
||||
}
|
||||
150
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParserTest.php
vendored
Normal file
150
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParserTest.php
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
class ParserTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var JBBCode\Parser
|
||||
*/
|
||||
private $_parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_parser = new JBBCode\Parser();
|
||||
$this->_parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
}
|
||||
|
||||
public function testAddCodeDefinition()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
|
||||
$this->assertFalse($parser->codeExists('foo', true));
|
||||
$this->assertFalse($parser->codeExists('foo', false));
|
||||
}
|
||||
|
||||
public function testAddBBCode()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
|
||||
$this->assertFalse($parser->codeExists('foo', true));
|
||||
$this->assertFalse($parser->codeExists('foo', false));
|
||||
|
||||
$this->assertSame($parser, $parser->addBBCode('foo', 'bar', true));
|
||||
|
||||
$this->assertTrue($parser->codeExists('foo', true));
|
||||
$this->assertFalse($parser->codeExists('foo', false));
|
||||
|
||||
$this->assertSame($parser, $parser->addBBCode('foo', 'bar', true));
|
||||
|
||||
$this->assertTrue($parser->codeExists('foo', true));
|
||||
$this->assertFalse($parser->codeExists('foo', false));
|
||||
|
||||
$this->assertSame($parser, $parser->addBBCode('foo', 'bar', false));
|
||||
|
||||
$this->assertTrue($parser->codeExists('foo', true));
|
||||
$this->assertTrue($parser->codeExists('foo', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for empty strings being the result of empty input
|
||||
*/
|
||||
public function testParseEmptyString()
|
||||
{
|
||||
$parser = $this->_parser->parse('');
|
||||
$this->assertEmpty($parser->getAsBBCode());
|
||||
$this->assertEmpty($parser->getAsText());
|
||||
$this->assertEmpty($parser->getAsHTML());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for artifacts of previous parses
|
||||
*/
|
||||
public function testParseContentCleared()
|
||||
{
|
||||
$parser = $this->_parser->parse('foo');
|
||||
|
||||
$this->assertEquals('foo', $parser->getAsText());
|
||||
$this->assertEquals('foo', $parser->getAsHTML());
|
||||
$this->assertEquals('foo', $parser->getAsBBCode());
|
||||
|
||||
$parser->parse('bar');
|
||||
|
||||
$this->assertEquals('bar', $parser->getAsText());
|
||||
$this->assertEquals('bar', $parser->getAsHTML());
|
||||
$this->assertEquals('bar', $parser->getAsBBCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @param string[] $expected
|
||||
* @dataProvider textCodeProvider
|
||||
*/
|
||||
public function testParse($code, $expected)
|
||||
{
|
||||
$parser = $this->_parser->parse($code);
|
||||
$this->assertEquals($expected['text'], $parser->getAsText());
|
||||
$this->assertEquals($expected['html'], $parser->getAsHTML());
|
||||
$this->assertEquals($expected['bbcode'], $parser->getAsBBCode());
|
||||
}
|
||||
|
||||
public function textCodeProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'foo',
|
||||
array(
|
||||
'text' => 'foo',
|
||||
'html' => 'foo',
|
||||
'bbcode' => 'foo',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'[b]this is bold[/b]',
|
||||
array(
|
||||
'text' => 'this is bold',
|
||||
'html' => '<strong>this is bold</strong>',
|
||||
'bbcode' => '[b]this is bold[/b]',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'[b]this is bold',
|
||||
array(
|
||||
'text' => 'this is bold',
|
||||
'html' => '<strong>this is bold</strong>',
|
||||
'bbcode' => '[b]this is bold[/b]',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'buffer text [b]this is bold[/b] buffer text',
|
||||
array(
|
||||
'text' => 'buffer text this is bold buffer text',
|
||||
'html' => 'buffer text <strong>this is bold</strong> buffer text',
|
||||
'bbcode' => 'buffer text [b]this is bold[/b] buffer text',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'this is some text with [b]bold tags[/b] and [i]italics[/i] and things like [u]that[/u].',
|
||||
array(
|
||||
'text' => 'this is some text with bold tags and italics and things like that.',
|
||||
'html' => 'this is some text with <strong>bold tags</strong> and <em>italics</em> and things like <u>that</u>.',
|
||||
'bbcode' => 'this is some text with [b]bold tags[/b] and [i]italics[/i] and things like [u]that[/u].',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'This contains a [url=http://jbbcode.com]url[/url] which uses an option.',
|
||||
array(
|
||||
'text' => 'This contains a url which uses an option.',
|
||||
'html' => 'This contains a <a href="http://jbbcode.com">url</a> which uses an option.',
|
||||
'bbcode' => 'This contains a [url=http://jbbcode.com]url[/url] which uses an option.',
|
||||
)
|
||||
),
|
||||
array(
|
||||
'This doesn\'t use the url option [url]http://jbbcode.com[/url].',
|
||||
array(
|
||||
'text' => 'This doesn\'t use the url option http://jbbcode.com.',
|
||||
'html' => 'This doesn\'t use the url option <a href="http://jbbcode.com">http://jbbcode.com</a>.',
|
||||
'bbcode' => 'This doesn\'t use the url option [url]http://jbbcode.com[/url].',
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
127
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParsingEdgeCaseTest.php
vendored
Normal file
127
common/vendor/jbbcode/jbbcode/JBBCode/tests/ParsingEdgeCaseTest.php
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A series of test cases for various potential parsing edge cases. This
|
||||
* includes a lot of tests using brackets for things besides genuine tag
|
||||
* names.
|
||||
*
|
||||
* @author jbowens
|
||||
*
|
||||
*/
|
||||
class ParsingEdgeCaseTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* A utility method for these tests that will evaluate
|
||||
* its arguments as bbcode with a fresh parser loaded
|
||||
* with only the default bbcodes. It returns the
|
||||
* html output.
|
||||
*/
|
||||
private function defaultParse($bbcode)
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse($bbcode);
|
||||
return $parser->getAsHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given bbcode matches the given html when
|
||||
* the bbcode is run through defaultParse.
|
||||
*/
|
||||
private function assertProduces($bbcode, $html)
|
||||
{
|
||||
$this->assertEquals($html, $this->defaultParse($bbcode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests attempting to use a code that doesn't exist.
|
||||
*/
|
||||
public function testNonexistentCodeMalformed()
|
||||
{
|
||||
$this->assertProduces('[wat]', '[wat]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests attempting to use a code that doesn't exist, but this
|
||||
* time in a well-formed fashion.
|
||||
*
|
||||
* @depends testNonexistentCodeMalformed
|
||||
*/
|
||||
public function testNonexistentCodeWellformed()
|
||||
{
|
||||
$this->assertProduces('[wat]something[/wat]', '[wat]something[/wat]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a whole bunch of meaningless left brackets.
|
||||
*/
|
||||
public function testAllLeftBrackets()
|
||||
{
|
||||
$this->assertProduces('[[[[[[[[', '[[[[[[[[');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a whole bunch of meaningless right brackets.
|
||||
*/
|
||||
public function testAllRightBrackets()
|
||||
{
|
||||
$this->assertProduces(']]]]]', ']]]]]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Intermixes well-formed, meaningful tags with meaningless brackets.
|
||||
*/
|
||||
public function testRandomBracketsInWellformedCode()
|
||||
{
|
||||
$this->assertProduces('[b][[][[i]heh[/i][/b]',
|
||||
'<strong>[[][<em>heh</em></strong>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an unclosed tag within a closed tag.
|
||||
*/
|
||||
public function testUnclosedWithinClosed()
|
||||
{
|
||||
$this->assertProduces('[url=http://jbbcode.com][b]oh yeah[/url]',
|
||||
'<a href="http://jbbcode.com"><strong>oh yeah</strong></a>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests half completed opening tag.
|
||||
*/
|
||||
public function testHalfOpenTag()
|
||||
{
|
||||
$this->assertProduces('[b', '[b');
|
||||
$this->assertProduces('wut [url=http://jbbcode.com',
|
||||
'wut [url=http://jbbcode.com');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests half completed closing tag.
|
||||
*/
|
||||
public function testHalfClosingTag()
|
||||
{
|
||||
$this->assertProduces('[b]this should be bold[/b',
|
||||
'<strong>this should be bold[/b</strong>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests lots of left brackets before the actual tag. For example:
|
||||
* [[[[[[[[b]bold![/b]
|
||||
*/
|
||||
public function testLeftBracketsThenTag()
|
||||
{
|
||||
$this->assertProduces('[[[[[b]bold![/b]',
|
||||
'[[[[<strong>bold!</strong>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a whitespace after left bracket.
|
||||
*/
|
||||
public function testWhitespaceAfterLeftBracketWhithoutTag()
|
||||
{
|
||||
$this->assertProduces('[ ABC ] ',
|
||||
'[ ABC ] ');
|
||||
}
|
||||
}
|
||||
81
common/vendor/jbbcode/jbbcode/JBBCode/tests/SimpleEvaluationTest.php
vendored
Normal file
81
common/vendor/jbbcode/jbbcode/JBBCode/tests/SimpleEvaluationTest.php
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
class SimpleEvaluationTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* A utility method for these tests that will evaluate
|
||||
* its arguments as bbcode with a fresh parser loaded
|
||||
* with only the default bbcodes. It returns the
|
||||
* html output.
|
||||
*/
|
||||
private function defaultParse($bbcode)
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse($bbcode);
|
||||
return $parser->getAsHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given bbcode matches the given html when
|
||||
* the bbcode is run through defaultParse.
|
||||
*/
|
||||
private function assertProduces($bbcode, $html)
|
||||
{
|
||||
$this->assertEquals($html, $this->defaultParse($bbcode));
|
||||
}
|
||||
|
||||
public function testCodeOptions()
|
||||
{
|
||||
$code = 'This contains a [url=http://jbbcode.com/?b=2]url[/url] which uses an option.';
|
||||
$html = 'This contains a <a href="http://jbbcode.com/?b=2">url</a> which uses an option.';
|
||||
$this->assertProduces($code, $html);
|
||||
}
|
||||
|
||||
public function testAttributes()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$builder = new JBBCode\CodeDefinitionBuilder('img', '<img src="{param}" height="{height}" alt="{alt}" />');
|
||||
$parser->addCodeDefinition($builder->setUseOption(true)->setParseContent(false)->build());
|
||||
|
||||
$expected = 'Multiple <img src="http://jbbcode.com/img.png" height="50" alt="alt text" /> options.';
|
||||
|
||||
$code = 'Multiple [img height="50" alt="alt text"]http://jbbcode.com/img.png[/img] options.';
|
||||
$parser->parse($code);
|
||||
$result = $parser->getAsHTML();
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$code = 'Multiple [img height=50 alt="alt text"]http://jbbcode.com/img.png[/img] options.';
|
||||
$parser->parse($code);
|
||||
$result = $parser->getAsHTML();
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testNestingTags()
|
||||
{
|
||||
$code = '[url=http://jbbcode.com][b]hello [u]world[/u][/b][/url]';
|
||||
$html = '<a href="http://jbbcode.com"><strong>hello <u>world</u></strong></a>';
|
||||
$this->assertProduces($code, $html);
|
||||
}
|
||||
|
||||
public function testBracketInTag()
|
||||
{
|
||||
$this->assertProduces('[b]:-[[/b]', '<strong>:-[</strong>');
|
||||
}
|
||||
|
||||
public function testBracketWithSpaceInTag()
|
||||
{
|
||||
$this->assertProduces('[b]:-[ [/b]', '<strong>:-[ </strong>');
|
||||
}
|
||||
|
||||
public function testBracketWithTextInTag()
|
||||
{
|
||||
$this->assertProduces('[b]:-[ foobar[/b]', '<strong>:-[ foobar</strong>');
|
||||
}
|
||||
|
||||
public function testMultibleBracketsWithTextInTag()
|
||||
{
|
||||
$this->assertProduces('[b]:-[ [fo[o[bar[/b]', '<strong>:-[ [fo[o[bar</strong>');
|
||||
}
|
||||
}
|
||||
31
common/vendor/jbbcode/jbbcode/JBBCode/tests/TextNodeTest.php
vendored
Normal file
31
common/vendor/jbbcode/jbbcode/JBBCode/tests/TextNodeTest.php
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
class TextNodeTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var JBBCode\TextNode */
|
||||
private $_textNode;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_textNode = new JBBCode\TextNode('');
|
||||
}
|
||||
|
||||
public function accept()
|
||||
{
|
||||
$mock = $this->getMock('JBBCode\NodeVisitor',
|
||||
array('visitDocumentElement', 'visitTextNode', 'visitElementNode'));
|
||||
$mock->expects($this->never())
|
||||
->method('visitDocumentElement');
|
||||
$mock->expects($this->once())
|
||||
->method('visitTextNode')
|
||||
->with($this->equalTo($this->_textNode));
|
||||
$mock->expects($this->never())
|
||||
->method('visitElementNode');
|
||||
$this->_textNode->accept($mock);
|
||||
}
|
||||
|
||||
public function testIsTextNode()
|
||||
{
|
||||
$this->assertTrue($this->_textNode->isTextNode());
|
||||
}
|
||||
}
|
||||
116
common/vendor/jbbcode/jbbcode/JBBCode/tests/TokenizerTest.php
vendored
Normal file
116
common/vendor/jbbcode/jbbcode/JBBCode/tests/TokenizerTest.php
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test cases testing the functionality of the Tokenizer. The tokenizer
|
||||
* is used by the parser to make parsing simpler.
|
||||
*
|
||||
* @author jbowens
|
||||
*/
|
||||
class TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testEmptyString()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('');
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
$this->assertNull($tokenizer->current());
|
||||
$this->assertNull($tokenizer->next());
|
||||
$this->assertEmpty($tokenizer->toString());
|
||||
}
|
||||
|
||||
public function testHasNext()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('');
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$this->assertTrue($tokenizer->hasNext());
|
||||
$tokenizer->next();
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
}
|
||||
|
||||
public function testNext()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$this->assertEquals('[', $tokenizer->next());
|
||||
$this->assertNull($tokenizer->next());
|
||||
}
|
||||
|
||||
public function testCurrent()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$this->assertNull($tokenizer->current());
|
||||
$tokenizer->next();
|
||||
$this->assertEquals('[', $tokenizer->current());
|
||||
}
|
||||
|
||||
public function testStepBack()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('');
|
||||
$tokenizer->stepBack();
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$this->assertTrue($tokenizer->hasNext());
|
||||
$this->assertEquals('[', $tokenizer->next());
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
$tokenizer->stepBack();
|
||||
$this->assertTrue($tokenizer->hasNext());
|
||||
$this->assertEquals('[', $tokenizer->next());
|
||||
}
|
||||
|
||||
public function testRestart()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('');
|
||||
$tokenizer->restart();
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$tokenizer->next();
|
||||
$tokenizer->restart();
|
||||
$this->assertTrue($tokenizer->hasNext());
|
||||
}
|
||||
|
||||
public function testToString()
|
||||
{
|
||||
$tokenizer = new JBBCode\Tokenizer('[');
|
||||
$this->assertEquals('[', $tokenizer->toString());
|
||||
$tokenizer->next();
|
||||
$this->assertEmpty($tokenizer->toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $tokens
|
||||
* @dataProvider tokenProvider()
|
||||
*/
|
||||
public function testTokenize($tokens)
|
||||
{
|
||||
$string = implode('', $tokens);
|
||||
$tokenizer = new JBBCode\Tokenizer($string);
|
||||
$this->assertEquals($string, $tokenizer->toString());
|
||||
|
||||
$this->assertTrue($tokenizer->hasNext());
|
||||
$this->assertNull($tokenizer->current());
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
$this->assertEquals($token, $tokenizer->next());
|
||||
}
|
||||
|
||||
$this->assertNull($tokenizer->next());
|
||||
$this->assertFalse($tokenizer->hasNext());
|
||||
}
|
||||
|
||||
public function tokenProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array('foo'),
|
||||
),
|
||||
array(
|
||||
array('foo', '[', 'b', ']', 'bar'),
|
||||
),
|
||||
array(
|
||||
array('[', 'foo', ']'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
2
common/vendor/jbbcode/jbbcode/JBBCode/tests/bootstrap.php
vendored
Normal file
2
common/vendor/jbbcode/jbbcode/JBBCode/tests/bootstrap.php
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Parser.php';
|
||||
37
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/CssColorValidatorTest.php
vendored
Normal file
37
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/CssColorValidatorTest.php
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
class CssColorValidatorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var JBBCode\validators\CssColorValidator
|
||||
*/
|
||||
private $_validator;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_validator = new JBBCode\validators\CssColorValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $color
|
||||
* @dataProvider validColorProvider
|
||||
*/
|
||||
public function testValidColors($color)
|
||||
{
|
||||
$this->assertTrue($this->_validator->validate($color));
|
||||
}
|
||||
|
||||
public function validColorProvider()
|
||||
{
|
||||
return array(
|
||||
array('red'),
|
||||
array('yellow'),
|
||||
array('LightGoldenRodYellow'),
|
||||
array('#000'),
|
||||
array('#00ff00'),
|
||||
array('rgba(255, 0, 0, 0.5)'),
|
||||
array('rgba(50, 50, 50, 0.0)'),
|
||||
);
|
||||
}
|
||||
}
|
||||
30
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/FnValidatorTest.php
vendored
Normal file
30
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/FnValidatorTest.php
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
class FnValidatorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test custom functional validator implementations.
|
||||
*
|
||||
* @param JBBCode\validators\FnValidator $validator
|
||||
* @dataProvider validatorProvider
|
||||
*/
|
||||
public function testValidator($validator)
|
||||
{
|
||||
$this->assertTrue($validator->validate('1234567890'));
|
||||
$this->assertFalse($validator->validate('QWERTZUIOP'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide custom numeric string validator implementations.
|
||||
*
|
||||
*/
|
||||
public function validatorProvider()
|
||||
{
|
||||
return array(
|
||||
array(new JBBCode\validators\FnValidator('is_numeric')),
|
||||
array(new JBBCode\validators\FnValidator(function ($input) {
|
||||
return is_numeric($input);
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
50
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/UrlValidatorTest.php
vendored
Normal file
50
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/UrlValidatorTest.php
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
class UrlValidatorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var JBBCode\validators\UrlValidator
|
||||
*/
|
||||
private $_validator;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_validator = new JBBCode\validators\UrlValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @dataProvider invalidUrlProvider
|
||||
*/
|
||||
public function testInvalidUrl($url)
|
||||
{
|
||||
$this->assertFalse($this->_validator->validate($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @dataProvider validUrlProvider
|
||||
*/
|
||||
public function testValidUrl($url)
|
||||
{
|
||||
$this->assertTrue($this->_validator->validate($url));
|
||||
}
|
||||
|
||||
public function invalidUrlProvider()
|
||||
{
|
||||
return array(
|
||||
array('#yolo#swag'),
|
||||
array('giehtiehwtaw352353%3'),
|
||||
);
|
||||
}
|
||||
|
||||
public function validUrlProvider()
|
||||
{
|
||||
return array(
|
||||
array('http://google.com'),
|
||||
array('http://jbbcode.com/docs'),
|
||||
array('https://www.maps.google.com'),
|
||||
);
|
||||
}
|
||||
}
|
||||
72
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/ValidatorTest.php
vendored
Normal file
72
common/vendor/jbbcode/jbbcode/JBBCode/tests/validators/ValidatorTest.php
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test cases for InputValidators.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class ValidatorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Tests an invalid url as an option to a url bbcode.
|
||||
*
|
||||
*/
|
||||
public function testInvalidOptionUrlBBCode()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse('[url=javascript:alert("HACKED!");]click me[/url]');
|
||||
$this->assertEquals('[url=javascript:alert("HACKED!");]click me[/url]',
|
||||
$parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an invalid url as the body to a url bbcode.
|
||||
*
|
||||
*/
|
||||
public function testInvalidBodyUrlBBCode()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse('[url]javascript:alert("HACKED!");[/url]');
|
||||
$this->assertEquals('[url]javascript:alert("HACKED!");[/url]', $parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a valid url as the body to a url bbcode.
|
||||
*
|
||||
*/
|
||||
public function testValidUrlBBCode()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse('[url]http://jbbcode.com[/url]');
|
||||
$this->assertEquals('<a href="http://jbbcode.com">http://jbbcode.com</a>',
|
||||
$parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests invalid CSS color values on the CssColorValidator.
|
||||
*/
|
||||
public function testInvalidCssColor()
|
||||
{
|
||||
$colorValidator = new JBBCode\validators\CssColorValidator();
|
||||
$this->assertFalse($colorValidator->validate('" onclick="javascript: alert(\"gotcha!\");'));
|
||||
$this->assertFalse($colorValidator->validate('"><marquee scrollamount="100'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests invalid css colors in a color bbcode.
|
||||
*
|
||||
* @depends testInvalidCssColor
|
||||
*/
|
||||
public function testInvalidColorBBCode()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse('[color=" onclick="alert(\'hey ya!\');]click me[/color]');
|
||||
$this->assertEquals('[color=" onclick="alert(\'hey ya!\');]click me[/color]',
|
||||
$parser->getAsHtml());
|
||||
}
|
||||
}
|
||||
76
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/HTMLSafeVisitorTest.php
vendored
Normal file
76
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/HTMLSafeVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(dirname(__DIR__)) . '/visitors/HTMLSafeVisitor.php';
|
||||
|
||||
/**
|
||||
* Test cases testing the HTMLSafe visitor, which escapes all html characters in the source text
|
||||
*
|
||||
* @author astax-t
|
||||
*/
|
||||
class HTMLSafeVisitorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Asserts that the given bbcode string produces the given html string
|
||||
* when parsed with the default bbcodes.
|
||||
*/
|
||||
public function assertProduces($bbcode, $html)
|
||||
{
|
||||
$parser = new \JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->parse($bbcode);
|
||||
|
||||
$htmlsafer = new JBBCode\visitors\HTMLSafeVisitor();
|
||||
$parser->accept($htmlsafer);
|
||||
|
||||
$this->assertEquals($html, $parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping quotes and ampersands in simple text
|
||||
*/
|
||||
public function testQuoteAndAmp()
|
||||
{
|
||||
$this->assertProduces('te"xt te&xt', 'te"xt te&xt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping quotes and ampersands inside a BBCode tag
|
||||
*/
|
||||
public function testQuoteAndAmpInTag()
|
||||
{
|
||||
$this->assertProduces('[b]te"xt te&xt[/b]', '<strong>te"xt te&xt</strong>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping HTML tags
|
||||
*/
|
||||
public function testHtmlTag()
|
||||
{
|
||||
$this->assertProduces('<b>not bold</b>', '<b>not bold</b>');
|
||||
$this->assertProduces('[b]<b>bold</b>[/b] <hr>', '<strong><b>bold</b></strong> <hr>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping ampersands in URL using [url]...[/url]
|
||||
*/
|
||||
public function testUrlParam()
|
||||
{
|
||||
$this->assertProduces('text [url]http://example.com/?a=b&c=d[/url] more text', 'text <a href="http://example.com/?a=b&c=d">http://example.com/?a=b&c=d</a> more text');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping ampersands in URL using [url=...] tag
|
||||
*/
|
||||
public function testUrlOption()
|
||||
{
|
||||
$this->assertProduces('text [url=http://example.com/?a=b&c=d]this is a "link"[/url]', 'text <a href="http://example.com/?a=b&c=d">this is a "link"</a>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping ampersands in URL using [url=...] tag when URL is in quotes
|
||||
*/
|
||||
public function testUrlOptionQuotes()
|
||||
{
|
||||
$this->assertProduces('text [url="http://example.com/?a=b&c=d"]this is a "link"[/url]', 'text <a href="http://example.com/?a=b&c=d">this is a "link"</a>');
|
||||
}
|
||||
}
|
||||
80
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/NestLimitVisitorTest.php
vendored
Normal file
80
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/NestLimitVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test cases for CodeDefinition nest limits. If an element is nested beyond
|
||||
* its CodeDefinition's nest limit, it should be removed from the parse tree.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class NestLimitVisitorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/** @var \JBBCode\visitors\NestLimitVisitor */
|
||||
private $_nestLimitVisitor;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_nestLimitVisitor = new \JBBCode\visitors\NestLimitVisitor();
|
||||
}
|
||||
|
||||
public function testVisitDocumentElement()
|
||||
{
|
||||
$childMock = $this->getMock('JBBCode\ElementNode', array('accept'));
|
||||
$childMock->expects($this->once())
|
||||
->method('accept')
|
||||
->with($this->equalTo($this->_nestLimitVisitor));
|
||||
|
||||
$mock = $this->getMock('JBBCode\DocumentElement', array('getChildren'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array(
|
||||
$childMock
|
||||
)));
|
||||
|
||||
$this->_nestLimitVisitor->visitDocumentElement($mock);
|
||||
}
|
||||
|
||||
public function testVisitTextNode()
|
||||
{
|
||||
$mock = $this->getMockBuilder('JBBCode\TextNode')
|
||||
->setMethods(array('accept'))
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$mock->expects($this->never())
|
||||
->method('accept');
|
||||
|
||||
$this->_nestLimitVisitor->visitTextNode($mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that when elements have no nest limits they may be
|
||||
* nested indefinitely.
|
||||
*/
|
||||
public function testIndefiniteNesting()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addBBCode('b', '<strong>{param}</strong>', false, true, -1);
|
||||
$parser->parse('[b][b][b][b][b][b][b][b]bold text[/b][/b][/b][/b][/b][/b][/b][/b]');
|
||||
$this->assertEquals('<strong><strong><strong><strong><strong><strong><strong><strong>' .
|
||||
'bold text' .
|
||||
'</strong></strong></strong></strong></strong></strong></strong></strong>',
|
||||
$parser->getAsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test over nesting.
|
||||
*/
|
||||
public function testOverNesting()
|
||||
{
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
$parser->addBBCode('quote', '<blockquote>{param}</blockquote>', false, true, 2);
|
||||
$bbcode = '[quote][quote][quote]wut[/quote] huh?[/quote] i don\'t know[/quote]';
|
||||
$parser->parse($bbcode);
|
||||
$expectedBbcode = '[quote][quote] huh?[/quote] i don\'t know[/quote]';
|
||||
$expectedHtml = '<blockquote><blockquote> huh?</blockquote> i don\'t know</blockquote>';
|
||||
$this->assertEquals($expectedBbcode, $parser->getAsBBCode());
|
||||
$this->assertEquals($expectedHtml, $parser->getAsHtml());
|
||||
}
|
||||
}
|
||||
91
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/SmileyVisitorTest.php
vendored
Normal file
91
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/SmileyVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(dirname(__DIR__)) . '/visitors/SmileyVisitor.php';
|
||||
|
||||
class SmileyVisitorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var \JBBCode\visitors\SmileyVisitor */
|
||||
private $_smileyVisitor;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_smileyVisitor = new \JBBCode\visitors\SmileyVisitor();
|
||||
}
|
||||
|
||||
public function testVisitDocumentElement()
|
||||
{
|
||||
$childMock = $this->getMock('JBBCode\ElementNode', array('accept'));
|
||||
$childMock->expects($this->once())
|
||||
->method('accept')
|
||||
->with($this->equalTo($this->_smileyVisitor));
|
||||
|
||||
$mock = $this->getMock('JBBCode\DocumentElement', array('getChildren'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array(
|
||||
$childMock,
|
||||
)));
|
||||
|
||||
$this->_smileyVisitor->visitDocumentElement($mock);
|
||||
}
|
||||
|
||||
public function testVisitElementNode()
|
||||
{
|
||||
$builder = new \JBBCode\CodeDefinitionBuilder('foo', 'bar');
|
||||
$builder->setParseContent(false);
|
||||
|
||||
$mock = $this->getMock('JBBCode\DocumentElement', array('getChildren', 'getCodeDefinition'));
|
||||
$mock->expects($this->never())
|
||||
->method('getChildren');
|
||||
$mock->expects($this->once())
|
||||
->method('getCodeDefinition')
|
||||
->will($this->returnValue(
|
||||
$builder->build()
|
||||
));
|
||||
$this->_smileyVisitor->visitElementNode($mock);
|
||||
|
||||
$childMock = $this->getMock('JBBCode\ElementNode', array('accept', 'parseContent'));
|
||||
$childMock->expects($this->once())
|
||||
->method('accept')
|
||||
->with($this->equalTo($this->_smileyVisitor));
|
||||
|
||||
$mock = $this->getMock('JBBCode\DocumentElement', array('getChildren', 'getCodeDefinition'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array(
|
||||
$childMock,
|
||||
)));
|
||||
$mock->expects($this->once())
|
||||
->method('getCodeDefinition')
|
||||
->will($this->returnValue($builder->setParseContent(true)->build()));
|
||||
$this->_smileyVisitor->visitElementNode($mock);
|
||||
}
|
||||
|
||||
public function testVisitTextNodeEmpty()
|
||||
{
|
||||
$textNode = new JBBCode\TextNode('');
|
||||
$textNode->accept($this->_smileyVisitor);
|
||||
$this->assertEmpty($textNode->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* @dataProvider smileyProvider()
|
||||
*/
|
||||
public function testVisitTextNode($string)
|
||||
{
|
||||
$textNode = new JBBCode\TextNode($string);
|
||||
$textNode->accept($this->_smileyVisitor);
|
||||
$this->assertNotFalse(strpos($textNode->getValue(), '<img src="/smiley.png" alt=":)" />'));
|
||||
}
|
||||
|
||||
public function smileyProvider()
|
||||
{
|
||||
return array(
|
||||
array( ':)'),
|
||||
array( ':) foo'),
|
||||
array( 'foo :)'),
|
||||
array( 'foo :) bar'),
|
||||
);
|
||||
}
|
||||
}
|
||||
77
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/TagCountingVisitorTest.php
vendored
Normal file
77
common/vendor/jbbcode/jbbcode/JBBCode/tests/visitors/TagCountingVisitorTest.php
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(dirname(__DIR__)) . '/visitors/TagCountingVisitor.php';
|
||||
|
||||
class TagCountingVisitorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var JBBCode\visitors\TagCountingVisitor */
|
||||
protected $_tagCountingVisitor;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_tagCountingVisitor = new JBBCode\visitors\TagCountingVisitor();
|
||||
}
|
||||
|
||||
public function testVisitTextNode()
|
||||
{
|
||||
$mock = $this->getMock('JBBCode\TextNode', array('accept'), array(''));
|
||||
$mock->expects($this->never())
|
||||
->method('accept');
|
||||
$this->_tagCountingVisitor->visitTextNode($mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers JBBCode\visitors\TagCountingVisitor::getFrequency()
|
||||
* @covers JBBCode\visitors\TagCountingVisitor::visitElementNode()
|
||||
*/
|
||||
public function testVisitElementNode()
|
||||
{
|
||||
$childMock = $this->getMock('JBBCode\ElementNode', array('accept'));
|
||||
$childMock->expects($this->once())
|
||||
->method('accept')
|
||||
->with($this->equalTo($this->_tagCountingVisitor));
|
||||
|
||||
$mock = $this->getMock('JBBCode\ElementNode', array('getChildren', 'getTagName'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array(
|
||||
$childMock,
|
||||
)));
|
||||
$mock->expects($this->once())
|
||||
->method('getTagName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertEquals(0, $this->_tagCountingVisitor->getFrequency('foo'));
|
||||
|
||||
$this->_tagCountingVisitor->visitElementNode($mock);
|
||||
$this->assertEquals(1, $this->_tagCountingVisitor->getFrequency('foo'));
|
||||
|
||||
$mock = $this->getMock('JBBCode\ElementNode', array('getChildren', 'getTagName'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array()));
|
||||
$mock->expects($this->once())
|
||||
->method('getTagName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->_tagCountingVisitor->visitElementNode($mock);
|
||||
$this->assertEquals(2, $this->_tagCountingVisitor->getFrequency('foo'));
|
||||
}
|
||||
|
||||
public function testVisitDocumentElement()
|
||||
{
|
||||
$childMock = $this->getMock('JBBCode\ElementNode', array('accept'));
|
||||
$childMock->expects($this->once())
|
||||
->method('accept')
|
||||
->with($this->equalTo($this->_tagCountingVisitor));
|
||||
|
||||
$mock = $this->getMock('JBBCode\DocumentElement', array('getChildren'));
|
||||
$mock->expects($this->once())
|
||||
->method('getChildren')
|
||||
->will($this->returnValue(array(
|
||||
$childMock,
|
||||
)));
|
||||
|
||||
$this->_tagCountingVisitor->visitDocumentElement($mock);
|
||||
}
|
||||
}
|
||||
30
common/vendor/jbbcode/jbbcode/JBBCode/validators/CssColorValidator.php
vendored
Normal file
30
common/vendor/jbbcode/jbbcode/JBBCode/validators/CssColorValidator.php
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\validators;
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'InputValidator.php';
|
||||
|
||||
/**
|
||||
* An InputValidator for CSS color values. This is a very rudimentary
|
||||
* validator. It will allow a lot of color values that are invalid. However,
|
||||
* it shouldn't allow any invalid color values that are also a security
|
||||
* concern.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class CssColorValidator implements \JBBCode\InputValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns true if $input uses only valid CSS color value
|
||||
* characters.
|
||||
*
|
||||
* @param string $input the string to validate
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate($input)
|
||||
{
|
||||
return (bool) preg_match('/^[A-z0-9\-#., ()%]+$/', $input);
|
||||
}
|
||||
}
|
||||
40
common/vendor/jbbcode/jbbcode/JBBCode/validators/FnValidator.php
vendored
Normal file
40
common/vendor/jbbcode/jbbcode/JBBCode/validators/FnValidator.php
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\validators;
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'InputValidator.php';
|
||||
|
||||
/**
|
||||
* An InputValidator that allows for shortcut implementation
|
||||
* of a validator using callable types (a function or a \Closure).
|
||||
*
|
||||
* @author Kubo2
|
||||
* @since Feb 2020
|
||||
*/
|
||||
class FnValidator implements \JBBCode\InputValidator
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $validator;
|
||||
|
||||
/**
|
||||
* Construct a custom validator from a callable.
|
||||
* @param callable $validator
|
||||
*/
|
||||
public function __construct(callable $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff the given input is valid, false otherwise.
|
||||
* @param string $input
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate($input)
|
||||
{
|
||||
$validator = $this->validator; // FIXME: for PHP>=7.0 replace with ($this->validator)($input)
|
||||
return (bool) $validator($input);
|
||||
}
|
||||
}
|
||||
27
common/vendor/jbbcode/jbbcode/JBBCode/validators/UrlValidator.php
vendored
Normal file
27
common/vendor/jbbcode/jbbcode/JBBCode/validators/UrlValidator.php
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\validators;
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'InputValidator.php';
|
||||
|
||||
/**
|
||||
* An InputValidator for urls. This can be used to make [url] bbcodes secure.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class UrlValidator implements \JBBCode\InputValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns true iff $input is a valid url.
|
||||
*
|
||||
* @param string $input the string to validate
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate($input)
|
||||
{
|
||||
$valid = filter_var($input, FILTER_VALIDATE_URL);
|
||||
return !!$valid;
|
||||
}
|
||||
}
|
||||
53
common/vendor/jbbcode/jbbcode/JBBCode/visitors/HTMLSafeVisitor.php
vendored
Normal file
53
common/vendor/jbbcode/jbbcode/JBBCode/visitors/HTMLSafeVisitor.php
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\visitors;
|
||||
|
||||
/**
|
||||
* This visitor escapes html content of all strings and attributes
|
||||
*
|
||||
* @author Alexander Polyanskikh
|
||||
*/
|
||||
class HTMLSafeVisitor implements \JBBCode\NodeVisitor
|
||||
{
|
||||
public function visitDocumentElement(\JBBCode\DocumentElement $documentElement)
|
||||
{
|
||||
foreach ($documentElement->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function visitTextNode(\JBBCode\TextNode $textNode)
|
||||
{
|
||||
$textNode->setValue($this->htmlSafe($textNode->getValue()));
|
||||
}
|
||||
|
||||
public function visitElementNode(\JBBCode\ElementNode $elementNode)
|
||||
{
|
||||
$attrs = $elementNode->getAttribute();
|
||||
if (is_array($attrs)) {
|
||||
foreach ($attrs as &$el) {
|
||||
$el = $this->htmlSafe($el);
|
||||
}
|
||||
|
||||
$elementNode->setAttribute($attrs);
|
||||
}
|
||||
|
||||
foreach ($elementNode->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
protected function htmlSafe($str, $options = null)
|
||||
{
|
||||
if (is_null($options)) {
|
||||
if (defined('ENT_DISALLOWED')) {
|
||||
$options = ENT_QUOTES | ENT_DISALLOWED | ENT_HTML401;
|
||||
} // PHP 5.4+
|
||||
else {
|
||||
$options = ENT_QUOTES;
|
||||
} // PHP 5.3
|
||||
}
|
||||
|
||||
return htmlspecialchars($str, $options, 'UTF-8');
|
||||
}
|
||||
}
|
||||
64
common/vendor/jbbcode/jbbcode/JBBCode/visitors/NestLimitVisitor.php
vendored
Normal file
64
common/vendor/jbbcode/jbbcode/JBBCode/visitors/NestLimitVisitor.php
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\visitors;
|
||||
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'CodeDefinition.php';
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'DocumentElement.php';
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'ElementNode.php';
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'NodeVisitor.php';
|
||||
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'TextNode.php';
|
||||
|
||||
/**
|
||||
* This visitor is used by the jBBCode core to enforce nest limits after
|
||||
* parsing. It traverses the parse graph depth first, removing any subtrees
|
||||
* that are nested deeper than an element's code definition allows.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since May 2013
|
||||
*/
|
||||
class NestLimitVisitor implements \JBBCode\NodeVisitor
|
||||
{
|
||||
|
||||
/** @var integer[] A map from tag name to current depth. */
|
||||
protected $depth = array();
|
||||
|
||||
public function visitDocumentElement(\JBBCode\DocumentElement $documentElement)
|
||||
{
|
||||
foreach ($documentElement->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function visitTextNode(\JBBCode\TextNode $textNode)
|
||||
{
|
||||
/* Nothing to do. Text nodes don't have tag names or children. */
|
||||
}
|
||||
|
||||
public function visitElementNode(\JBBCode\ElementNode $elementNode)
|
||||
{
|
||||
$tagName = strtolower($elementNode->getTagName());
|
||||
|
||||
/* Update the current depth for this tag name. */
|
||||
if (isset($this->depth[$tagName])) {
|
||||
$this->depth[$tagName]++;
|
||||
} else {
|
||||
$this->depth[$tagName] = 1;
|
||||
}
|
||||
|
||||
/* Check if $elementNode is nested too deeply. */
|
||||
if ($elementNode->getCodeDefinition()->getNestLimit() != -1 &&
|
||||
$elementNode->getCodeDefinition()->getNestLimit() < $this->depth[$tagName]) {
|
||||
/* This element is nested too deeply. We need to remove it and not visit any
|
||||
* of its children. */
|
||||
$elementNode->getParent()->removeChild($elementNode);
|
||||
} else {
|
||||
/* This element is not nested too deeply. Visit all of its children. */
|
||||
foreach ($elementNode->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we're done visiting this node, decrement the depth. */
|
||||
$this->depth[$tagName]--;
|
||||
}
|
||||
}
|
||||
40
common/vendor/jbbcode/jbbcode/JBBCode/visitors/SmileyVisitor.php
vendored
Normal file
40
common/vendor/jbbcode/jbbcode/JBBCode/visitors/SmileyVisitor.php
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\visitors;
|
||||
|
||||
/**
|
||||
* This visitor is an example of how to implement smiley parsing on the JBBCode
|
||||
* parse graph. It converts :) into image tags pointing to /smiley.png.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since April 2013
|
||||
*/
|
||||
class SmileyVisitor implements \JBBCode\NodeVisitor
|
||||
{
|
||||
public function visitDocumentElement(\JBBCode\DocumentElement $documentElement)
|
||||
{
|
||||
foreach ($documentElement->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function visitTextNode(\JBBCode\TextNode $textNode)
|
||||
{
|
||||
/* Convert :) into an image tag. */
|
||||
$textNode->setValue(str_replace(':)',
|
||||
'<img src="/smiley.png" alt=":)" />',
|
||||
$textNode->getValue()));
|
||||
}
|
||||
|
||||
public function visitElementNode(\JBBCode\ElementNode $elementNode)
|
||||
{
|
||||
/* We only want to visit text nodes within elements if the element's
|
||||
* code definition allows for its content to be parsed.
|
||||
*/
|
||||
if ($elementNode->getCodeDefinition()->parseContent()) {
|
||||
foreach ($elementNode->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
common/vendor/jbbcode/jbbcode/JBBCode/visitors/TagCountingVisitor.php
vendored
Normal file
60
common/vendor/jbbcode/jbbcode/JBBCode/visitors/TagCountingVisitor.php
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace JBBCode\visitors;
|
||||
|
||||
/**
|
||||
* This visitor traverses parse graph, counting the number of times each
|
||||
* tag name occurs.
|
||||
*
|
||||
* @author jbowens
|
||||
* @since January 2013
|
||||
*/
|
||||
class TagCountingVisitor implements \JBBcode\NodeVisitor
|
||||
{
|
||||
protected $frequencies = array();
|
||||
|
||||
public function visitDocumentElement(\JBBCode\DocumentElement $documentElement)
|
||||
{
|
||||
foreach ($documentElement->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function visitTextNode(\JBBCode\TextNode $textNode)
|
||||
{
|
||||
// Nothing to do here, text nodes do not have tag names or children
|
||||
}
|
||||
|
||||
public function visitElementNode(\JBBCode\ElementNode $elementNode)
|
||||
{
|
||||
$tagName = strtolower($elementNode->getTagName());
|
||||
|
||||
// Update this tag name's frequency
|
||||
if (isset($this->frequencies[$tagName])) {
|
||||
$this->frequencies[$tagName]++;
|
||||
} else {
|
||||
$this->frequencies[$tagName] = 1;
|
||||
}
|
||||
|
||||
// Visit all the node's childrens
|
||||
foreach ($elementNode->getChildren() as $child) {
|
||||
$child->accept($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the frequency of the given tag name.
|
||||
*
|
||||
* @param string $tagName the tag name to look up
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getFrequency($tagName)
|
||||
{
|
||||
if (!isset($this->frequencies[$tagName])) {
|
||||
return 0;
|
||||
} else {
|
||||
return $this->frequencies[$tagName];
|
||||
}
|
||||
}
|
||||
}
|
||||
21
common/vendor/jbbcode/jbbcode/LICENSE.md
vendored
Normal file
21
common/vendor/jbbcode/jbbcode/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 Jackson Owens
|
||||
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
70
common/vendor/jbbcode/jbbcode/README.md
vendored
Normal file
70
common/vendor/jbbcode/jbbcode/README.md
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
jBBCode
|
||||
=======
|
||||
[](https://github.com/jbowens/jBBCode/releases)
|
||||
[](LICENSE.md)
|
||||
[](https://travis-ci.org/jbowens/jBBCode)
|
||||
|
||||
jBBCode is a bbcode parser written in php 5.3. It's relatively lightweight and parses
|
||||
bbcodes without resorting to expensive regular expressions.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
For complete documentation and examples visit [jbbcode.com](http://jbbcode.com).
|
||||
|
||||
### A basic example
|
||||
|
||||
jBBCode includes a few optional, default bbcode definitions that may be loaded through the
|
||||
`DefaultCodeDefinitionSet` class. Below is a simple example of using these codes to convert
|
||||
a bbcode string to html.
|
||||
|
||||
```php
|
||||
<?php
|
||||
require_once "/path/to/jbbcode/Parser.php";
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
$parser->addCodeDefinitionSet(new JBBCode\DefaultCodeDefinitionSet());
|
||||
|
||||
$text = "The default codes include: [b]bold[/b], [i]italics[/i], [u]underlining[/u], ";
|
||||
$text .= "[url=http://jbbcode.com]links[/url], [color=red]color![/color] and more.";
|
||||
|
||||
$parser->parse($text);
|
||||
|
||||
print $parser->getAsHtml();
|
||||
```
|
||||
|
||||
### Composer
|
||||
|
||||
You may load jBBCode via composer. In your composer.json file:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"jbbcode/jbbcode": "1.3.*"
|
||||
}
|
||||
```
|
||||
|
||||
In your php file:
|
||||
|
||||
```php
|
||||
require 'vendor/autoloader.php';
|
||||
|
||||
$parser = new JBBCode\Parser();
|
||||
```
|
||||
|
||||
Contribute
|
||||
----------
|
||||
|
||||
I would love help maintaining jBBCode. Look at [open issues](http://github.com/jbowens/jBBCode/issues) for ideas on
|
||||
what needs to be done. Before submitting a pull request, verify that all unit tests still pass.
|
||||
|
||||
#### Running unit tests
|
||||
To run the unit tests,
|
||||
ensure that [phpunit](http://github.com/sebastianbergmann/phpunit) is installed, or install it through the composer
|
||||
dev dependencies. Then run `phpunit` from the project directory. If you're adding new functionality, writing
|
||||
additional unit tests is a great idea.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
The project is under MIT license. Please see the [license file](LICENSE.md) for details.
|
||||
30
common/vendor/jbbcode/jbbcode/composer.json
vendored
Normal file
30
common/vendor/jbbcode/jbbcode/composer.json
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "jbbcode/jbbcode",
|
||||
"type": "library",
|
||||
"description": "A lightweight but extensible BBCode parser written in PHP 5.3.",
|
||||
"keywords": ["BBCode", "BB"],
|
||||
"homepage": "http://jbbcode.com/",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.5.*",
|
||||
"satooshi/php-coveralls": "0.6.*",
|
||||
"friendsofphp/php-cs-fixer": "^2.1"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jackson Owens",
|
||||
"email": "jackson_owens@alumni.brown.edu",
|
||||
"homepage": "http://jbowens.org/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"JBBCode": "."
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable"
|
||||
}
|
||||
24
common/vendor/jbbcode/jbbcode/phpunit.xml.dist
vendored
Normal file
24
common/vendor/jbbcode/jbbcode/phpunit.xml.dist
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit bootstrap="JBBCode/tests/bootstrap.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
stopOnFailure="false"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false">
|
||||
<testsuites>
|
||||
<testsuite name="jBBCode Test Suite">
|
||||
<directory>JBBCode/tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<blacklist>
|
||||
<directory suffix=".php">examples/</directory>
|
||||
<directory suffix=".php">vendor</directory>
|
||||
</blacklist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-clover" target="clover.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
Loading…
Add table
Add a link
Reference in a new issue