Skip to content
This repository was archived by the owner on Nov 16, 2022. It is now read-only.

Commit d71ab1a

Browse files
Merge pull request deanblackborough#27 from deanblackborough/v1.00.0
V1.00.0
2 parents 226548f + bf0fd71 commit d71ab1a

File tree

6 files changed

+127
-12
lines changed

6 files changed

+127
-12
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
Full changelog for PHP Quill Renderer
55

6+
## 1.00.0 - 2017-08-31
7+
8+
* Added support for ordered and unordered lists.
9+
* Updated README, notes on version 2.00.0
10+
611
## v0.90 - 2017-06-06
712

813
* Added support for paragraph breaks, converts double newlines from quill insert into a new p tag, the

README.md

+10-6
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99

1010
## Description
1111

12-
Simple Quill delta insert renderer, currently it only supports the attributes listed below, I will add support for additional attributes as I need them in Dlayer.
12+
Quill deltas renderer, converts deltas to HTML, the attributes supported by version 1.00.0 are listed below.
13+
Version 2.00.0 is in development, I'm working on support for additional Quill attributes, markdown support and a
14+
full rewrite of the parser, version 2.00.0 will only support PHP7+.
1315

14-
Created for use in [Dlayer](https://github.com/Dlayer/dlayer) but works as a stand-alone tool.
16+
Created for use within [Dlayer](https://github.com/Dlayer/dlayer) but works as a stand-alone tool.
1517

1618
## Installation
1719

@@ -60,14 +62,16 @@ Script:Super | `<sup>`
6062
Underline | `<u>`
6163
Header | `<h[n]>`
6264
Image | `<img>`
65+
List | `<ul>` `<ol>`
6366

64-
## Planned features
67+
## Planned features for version 2.00.0
6568

69+
* Parser logic rework
6670
* Markdown support
67-
* Lists (Bullets and Ordered)
6871
* Formatting options (justification etc.)
69-
* Remaining toolbar options
70-
* Missing tests (options)
72+
* Remaining Quill toolbar options
73+
* Full options management
74+
* Tests
7175

7276
## Warnings
7377

src/Parser/Html.php

+63-2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ protected function defaultAttributeOptions()
9595
'href' => null
9696
)
9797
),
98+
'list' => array(
99+
'ordered' => array(
100+
'tag' => 'li',
101+
'type' => 'block',
102+
'assign' => 'previous',
103+
'parent_tag' => 'ol'
104+
),
105+
'unordered' => array(
106+
'tag' => 'li',
107+
'type' => 'block',
108+
'assign' => 'previous',
109+
'parent_tag' => 'ul'
110+
)
111+
),
98112
'script' => array(
99113
'sub' => array(
100114
'type' => 'inline',
@@ -136,6 +150,7 @@ private function getTagAndAttributes($attribute, $value)
136150
break;
137151

138152
case 'header':
153+
case 'list':
139154
case 'script':
140155
return $this->options['attributes'][$attribute][$value];
141156
break;
@@ -281,10 +296,19 @@ private function assignTags()
281296
$tag_counter = $i - 1;
282297
}
283298

299+
$parent_tags = array('open' => null, 'close' => null);
300+
if (array_key_exists('parent_tag', $tag) === true) {
301+
$parent_tags = array (
302+
'open' => '<' . $tag['parent_tag'] . '>',
303+
'close' => '</' . $tag['parent_tag'] . '>',
304+
);
305+
}
306+
284307
$this->content[$tag_counter]['tags'][] = array(
285308
'open' => $open,
286309
'close' => '</' . $tag['tag'] . '>',
287-
'type' => $tag['type']
310+
'type' => $tag['type'],
311+
'parent_tags' => $parent_tags
288312
);
289313
}
290314
}
@@ -357,7 +381,8 @@ private function convertBreaks()
357381
/**
358382
* Loops through the deltas object and generate the contents array
359383
*
360-
* @todo Not keen on the close and remove methods, need to go through logic and try to remove need for them
384+
* @todo Not keen on the close*() and remove*() methods, I need to go through the logic and try to
385+
* remove the need for them by moving the logic into the assign tags function
361386
*
362387
* @return boolean
363388
*/
@@ -379,6 +404,8 @@ public function parse()
379404

380405
$this->convertBreaks();
381406

407+
$this->removeRedundantParentTags();
408+
382409
return true;
383410
} else {
384411
return false;
@@ -518,9 +545,43 @@ public function setAttributeOption($option, $value)
518545
break;
519546
case 'header':
520547
case 'link':
548+
case 'list':
521549
return false;
522550
break;
523551

524552
}
525553
}
554+
555+
/**
556+
* Remove any redundant parent tags. Using lists as an example, each LI will have open and close
557+
* parent tags assigned to it.
558+
*
559+
* @return void
560+
*/
561+
private function removeRedundantParentTags()
562+
{
563+
$existing_content = $this->content;
564+
$this->content = array();
565+
foreach ($existing_content as $k => $content) {
566+
if ($k !== 0 &&
567+
array_key_exists('tags', $content) === true &&
568+
count($content['tags']) === 1 &&
569+
array_key_exists('parent_tags', $content['tags'][0]) === true) {
570+
/**
571+
* Check the preview content item, if it has parent tags, remove the close and
572+
* remove the parent tag open from the current item before assigning back to the
573+
* new content array
574+
*/
575+
if (array_key_exists('tags', $this->content[($k-1)]) === true &&
576+
count($this->content[($k-1)]['tags']) === 1 &&
577+
array_key_exists('parent_tags', $this->content[($k-1)]['tags'][0]) === true) {
578+
579+
$this->content[($k-1)]['tags'][0]['parent_tags']['close'] = null;
580+
$content['tags'][0]['parent_tags']['open'] = null;
581+
}
582+
}
583+
584+
$this->content[] = $content;
585+
}
586+
}
526587
}

src/Parser/Parse.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,30 @@ protected function isAttributeValid($attribute, $value)
107107
$valid = true;
108108
}
109109
break;
110-
case 'script':
110+
case 'link':
111111
if (array_key_exists('attributes', $this->options) === true &&
112112
array_key_exists($attribute, $this->options['attributes']) === true &&
113-
in_array($value, array('sub', 'super')) === true) {
113+
strlen($value) > 0) {
114114

115115
$valid = true;
116116
}
117117
break;
118-
case 'link':
118+
case 'list':
119119
if (array_key_exists('attributes', $this->options) === true &&
120120
array_key_exists($attribute, $this->options['attributes']) === true &&
121-
strlen($value) > 0) {
121+
in_array($value, array('ordered', 'unordered')) === true) {
122122

123123
$valid = true;
124124
}
125125
break;
126+
case 'script':
127+
if (array_key_exists('attributes', $this->options) === true &&
128+
array_key_exists($attribute, $this->options['attributes']) === true &&
129+
in_array($value, array('sub', 'super')) === true) {
126130

131+
$valid = true;
132+
}
133+
break;
127134

128135
default:
129136
// Do nothing, valid already set to false

src/Renderer/Html.php

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public function render()
3939
{
4040
foreach ($this->content as $content) {
4141
foreach ($content['tags'] as $tag) {
42+
if (array_key_exists('parent_tags', $tag) === true && $tag['parent_tags'] !== null &&
43+
array_key_exists('open', $tag['parent_tags']) && $tag['parent_tags']['open'] !== null) {
44+
$this->html .= $tag['parent_tags']['open'];
45+
}
46+
4247
if (array_key_exists('open', $tag) === true && $tag['open'] !== null) {
4348
$this->html .= $tag['open'];
4449
}
@@ -54,6 +59,11 @@ public function render()
5459
if (array_key_exists('close', $tag) === true && $tag['close'] !== null) {
5560
$this->html .= $tag['close'];
5661
}
62+
63+
if (array_key_exists('parent_tags', $tag) === true && $tag['parent_tags'] !== null &&
64+
array_key_exists('close', $tag['parent_tags']) && $tag['parent_tags']['close'] !== null) {
65+
$this->html .= $tag['parent_tags']['close'];
66+
}
5767
}
5868
}
5969

tests/ListTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
require_once __DIR__ . '../../src/Render.php';
4+
require_once __DIR__ . '../../src/Renderer/Render.php';
5+
require_once __DIR__ . '../../src/Renderer/Html.php';
6+
require_once __DIR__ . '../../src/Parser/Parse.php';
7+
require_once __DIR__ . '../../src/Parser/Html.php';
8+
9+
final class ListTest extends \PHPUnit\Framework\TestCase
10+
{
11+
public function testSimpleOrderedList()
12+
{
13+
$delta = '{"ops":[{"insert":"Item 1"},{"attributes":{"list":"ordered"},"insert":"\n"},{"insert":"Item 2"},{"attributes":{"list":"ordered"},"insert":"\n"},{"insert":"Item 3"},{"attributes":{"list":"ordered"},"insert":"\n"}]}';
14+
$expected = '<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>';
15+
16+
$quill = new \DBlackborough\Quill\Render($delta);
17+
$this->assertEquals($expected, $quill->render());
18+
}
19+
20+
public function testSimpleUnorderedList()
21+
{
22+
$delta = '{"ops":[{"insert":"Item 1"},{"attributes":{"list":"unordered"},"insert":"\n"},{"insert":"Item 2"},{"attributes":{"list":"unordered"},"insert":"\n"},{"insert":"Item 3"},{"attributes":{"list":"unordered"},"insert":"\n"}]}';
23+
$expected = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
24+
25+
$quill = new \DBlackborough\Quill\Render($delta);
26+
$this->assertEquals($expected, $quill->render());
27+
}
28+
}

0 commit comments

Comments
 (0)