style: Formatted code with Prettier

pull/155/head
github-actions 2 years ago
parent 9581c33f83
commit db5d94bd08

@ -1,10 +1,9 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '' title: ""
labels: 'bug' labels: "bug"
assignees: '' assignees: ""
--- ---
**Describe the bug** **Describe the bug**
@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
**To Reproduce** **To Reproduce**
Steps to reproduce the behavior: Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):** **Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari] - OS: [e.g. iOS]
- Version [e.g. 22] - Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):** **Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1] - Device: [e.g. iPhone6]
- Browser [e.g. stock browser, safari] - OS: [e.g. iOS8.1]
- Version [e.g. 22] - Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

@ -1,10 +1,9 @@
--- ---
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: '' title: ""
labels: 'enhancement' labels: "enhancement"
assignees: '' assignees: ""
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**

@ -1,14 +1,11 @@
--- ---
name: Question name: Question
about: I have a question about this project about: I have a question about this project
title: '' title: ""
labels: 'question' labels: "question"
assignees: '' assignees: ""
--- ---
**Description** **Description**
A brief description of the question or issue: A brief description of the question or issue:

@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our Examples of behavior that contributes to a positive environment for our
community include: community include:
* Demonstrating empathy and kindness toward other people - Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences - Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback - Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, - Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall - Focusing on what is best not just for us as individuals, but for the overall
community community
Examples of unacceptable behavior include: Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of - The use of sexualized language or imagery, and sexual attention or advances of
any kind any kind
* Trolling, insulting or derogatory comments, and personal or political attacks - Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or email address, - Publishing others' private information, such as a physical or email address,
without their explicit permission without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Enforcement Responsibilities ## Enforcement Responsibilities
@ -119,14 +119,14 @@ version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. [Mozilla's code of conduct enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/faq][faq]. Translations are available at
[https://www.contributor-covenant.org/translations][translations]. [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org [homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity [mozilla coc]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq [faq]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations [translations]: https://www.contributor-covenant.org/translations

@ -8,8 +8,8 @@ Make sure your request is meaningful and you have tested the app locally before
#### Requirements #### Requirements
* [PHP 7.4+](https://www.apachefriends.org/index.html) - [PHP 7.4+](https://www.apachefriends.org/index.html)
* [Composer](https://getcomposer.org) - [Composer](https://getcomposer.org)
#### Linux #### Linux
@ -53,14 +53,17 @@ composer install
### Format and test the code ### Format and test the code
Run the following command to format the code with Prettier: Run the following command to format the code with Prettier:
``` ```
composer run format composer run format
``` ```
Run the following command to check if your code is formatted properly: Run the following command to check if your code is formatted properly:
``` ```
composer run format:check composer run format:check
``` ```
> **Note** You need to have [`prettier`](https://prettier.io/) and the [prettier-php plugin](https://github.com/prettier/plugin-php) installed globally in order to run this command. > **Note** You need to have [`prettier`](https://prettier.io/) and the [prettier-php plugin](https://github.com/prettier/plugin-php) installed globally in order to run this command.
Run the following command to run the PHPUnit test script which will verify that the tested functionality is still working. Run the following command to run the PHPUnit test script which will verify that the tested functionality is still working.

@ -137,7 +137,9 @@ Refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for more details on contributing, i
Made with ❤️ and PHP Made with ❤️ and PHP
<!-- markdownlint-disable MD033 --> <!-- markdownlint-disable MD033 -->
<a href="https://heroku.com/"><img alt="Powered by Heroku" title="Powered by Heroku" src="https://img.shields.io/badge/-Powered%20by%20Heroku-6567a5?style=for-the-badge&logo=heroku&logoColor=white"/></a> <a href="https://heroku.com/"><img alt="Powered by Heroku" title="Powered by Heroku" src="https://img.shields.io/badge/-Powered%20by%20Heroku-6567a5?style=for-the-badge&logo=heroku&logoColor=white"/></a>
<!-- markdownlint-enable MD033 --> <!-- markdownlint-enable MD033 -->
This project uses [Twemoji](https://github.com/twitter/twemoji), published under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by/4.0/) This project uses [Twemoji](https://github.com/twitter/twemoji), published under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by/4.0/)

@ -1,11 +1,10 @@
<?php declare (strict_types = 1); <?php declare(strict_types=1);
/** /**
* Controller for choosing model and rendering SVG outputs * Controller for choosing model and rendering SVG outputs
*/ */
class RendererController class RendererController
{ {
/** /**
* @var RendererModel $model * @var RendererModel $model
*/ */
@ -49,8 +48,8 @@ class RendererController
*/ */
private function redirectToDemo(): void private function redirectToDemo(): void
{ {
header('Location: demo/'); header("Location: demo/");
exit; exit();
} }
/** /**

@ -1,78 +1,76 @@
.loader, .loader,
.loader:before, .loader:before,
.loader:after { .loader:after {
display: none; display: none;
border-radius: 50%; border-radius: 50%;
width: 2.5em; width: 2.5em;
height: 2.5em; height: 2.5em;
-webkit-animation-fill-mode: both; -webkit-animation-fill-mode: both;
animation-fill-mode: both; animation-fill-mode: both;
-webkit-animation: load7 1.8s infinite ease-in-out; -webkit-animation: load7 1.8s infinite ease-in-out;
animation: load7 1.8s infinite ease-in-out; animation: load7 1.8s infinite ease-in-out;
} }
.loader { .loader {
color: var(--blue-light); color: var(--blue-light);
font-size: 10px; font-size: 10px;
margin: 0 0 38px 15px; margin: 0 0 38px 15px;
position: relative; position: relative;
text-indent: -9999em; text-indent: -9999em;
-webkit-transform: translateY(-4px) translateZ(0) scale(0.5); -webkit-transform: translateY(-4px) translateZ(0) scale(0.5);
-ms-transform: translateY(-4px) translateZ(0) scale(0.5); -ms-transform: translateY(-4px) translateZ(0) scale(0.5);
transform: translateY(-4px) translateZ(0) scale(0.5); transform: translateY(-4px) translateZ(0) scale(0.5);
-webkit-animation-delay: -0.16s; -webkit-animation-delay: -0.16s;
animation-delay: -0.16s; animation-delay: -0.16s;
} }
.loader:before, .loader:before,
.loader:after { .loader:after {
content: ''; content: "";
position: absolute; position: absolute;
top: 0; top: 0;
} }
.loader:before { .loader:before {
left: -3.5em; left: -3.5em;
-webkit-animation-delay: -0.32s; -webkit-animation-delay: -0.32s;
animation-delay: -0.32s; animation-delay: -0.32s;
} }
.loader:after { .loader:after {
left: 3.5em; left: 3.5em;
} }
@-webkit-keyframes load7 { @-webkit-keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
0%, 40% {
80%, box-shadow: 0 2.5em 0 0;
100% { }
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
} }
@keyframes load7 { @keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
0%, 40% {
80%, box-shadow: 0 2.5em 0 0;
100% { }
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
} }
.loading + .loader, .loading + .loader,
.loading + .loader:before, .loading + .loader:before,
.loading + .loader:after { .loading + .loader:after {
display: block; display: block;
} }
.loading { .loading {
display: none; display: none;
} }

@ -25,4 +25,4 @@ a.darkmode:hover {
bottom: 1em; bottom: 1em;
right: 1em; right: 1em;
} }
} }

@ -30,7 +30,7 @@
<link rel="icon" type="image/png" href="favicon.png"> <link rel="icon" type="image/png" href="favicon.png">
</head> </head>
<body <?= (isset($_COOKIE["darkmode"]) && $_COOKIE["darkmode"] == "on") ? 'data-theme="dark"' : ""; ?>> <body <?= isset($_COOKIE["darkmode"]) && $_COOKIE["darkmode"] == "on" ? 'data-theme="dark"' : "" ?>>
<h1>⌨️ Readme Typing SVG</h1> <h1>⌨️ Readme Typing SVG</h1>
<!-- GitHub badges/links section --> <!-- GitHub badges/links section -->
@ -155,7 +155,7 @@
</div> </div>
<a href="javascript:toggleTheme()" class="darkmode" title="toggle dark mode"> <a href="javascript:toggleTheme()" class="darkmode" title="toggle dark mode">
<i class="<?= (isset($_COOKIE["darkmode"]) && $_COOKIE["darkmode"] == "on") ? 'gg-sun' : "gg-moon"; ?>"></i> <i class="<?= isset($_COOKIE["darkmode"]) && $_COOKIE["darkmode"] == "on" ? "gg-sun" : "gg-moon" ?>"></i>
</a> </a>
</body> </body>

@ -26,22 +26,20 @@ let preview = {
update: function () { update: function () {
const copyButtons = document.querySelectorAll(".copy-button"); const copyButtons = document.querySelectorAll(".copy-button");
// get parameter values from all .param elements // get parameter values from all .param elements
const params = Array.from(document.querySelectorAll(".param:not([data-index])")).reduce( const params = Array.from(document.querySelectorAll(".param:not([data-index])")).reduce((acc, next) => {
(acc, next) => { // copy accumulator into local object
// copy accumulator into local object let obj = acc;
let obj = acc; let value = next.value;
let value = next.value; // remove hash from any colors and remove "FF" if full opacity
// remove hash from any colors and remove "FF" if full opacity value = value.replace(/^#([A-Fa-f0-9]{6})(?:[Ff]{2})?/, "$1");
value = value.replace(/^#([A-Fa-f0-9]{6})(?:[Ff]{2})?/, "$1"); // add value to reduction accumulator
// add value to reduction accumulator obj[next.id] = value;
obj[next.id] = value; return obj;
return obj; }, {});
}, {}
);
const lineInputs = Array.from(document.querySelectorAll(".param[data-index]")); const lineInputs = Array.from(document.querySelectorAll(".param[data-index]"));
// disable copy button if any line contains semicolon // disable copy button if any line contains semicolon
if (lineInputs.some((el) => el.value.indexOf(";") >= 0)) { if (lineInputs.some((el) => el.value.indexOf(";") >= 0)) {
return copyButtons.forEach((el) => el.disabled = true); return copyButtons.forEach((el) => (el.disabled = true));
} }
// add lines to parameters // add lines to parameters
params.lines = lineInputs params.lines = lineInputs
@ -50,7 +48,7 @@ let preview = {
.join(";"); // join lines with ';' delimiter .join(";"); // join lines with ';' delimiter
// function to URI encode string but keep semicolons as ';' and spaces as '+' // function to URI encode string but keep semicolons as ';' and spaces as '+'
const encode = (str) => { const encode = (str) => {
return encodeURIComponent(str).replace(/%3B/g, ";").replace(/%20/g, "+") return encodeURIComponent(str).replace(/%3B/g, ";").replace(/%20/g, "+");
}; };
// convert parameters to query string // convert parameters to query string
const query = Object.keys(params) const query = Object.keys(params)
@ -77,7 +75,7 @@ let preview = {
mdElement.innerText = md; mdElement.innerText = md;
htmlElement.innerText = html; htmlElement.innerText = html;
// disable copy button if no lines are filled in // disable copy button if no lines are filled in
copyButtons.forEach((el) => el.disabled = !params.lines.length); copyButtons.forEach((el) => (el.disabled = !params.lines.length));
}, },
addLine: function () { addLine: function () {
const parent = document.querySelector(".lines"); const parent = document.querySelector(".lines");
@ -101,11 +99,9 @@ let preview = {
// removal button // removal button
const deleteButton = document.createElement("button"); const deleteButton = document.createElement("button");
deleteButton.className = "delete-line btn"; deleteButton.className = "delete-line btn";
deleteButton.setAttribute( deleteButton.setAttribute("onclick", "return preview.removeLine(this.dataset.index);");
"onclick", deleteButton.innerHTML =
"return preview.removeLine(this.dataset.index);" '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="0.85em" width="0.85em" xmlns="http://www.w3.org/2000/svg"> <path d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"> </path> </svg>';
);
deleteButton.innerHTML = '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="0.85em" width="0.85em" xmlns="http://www.w3.org/2000/svg"> <path d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"> </path> </svg>';
deleteButton.dataset.index = index; deleteButton.dataset.index = index;
// add elements // add elements
@ -124,40 +120,35 @@ let preview = {
index = Number(index); index = Number(index);
const parent = document.querySelector(".lines"); const parent = document.querySelector(".lines");
// remove all elements for given property // remove all elements for given property
parent parent.querySelectorAll(`[data-index="${index}"]`).forEach((el) => {
.querySelectorAll(`[data-index="${index}"]`) parent.removeChild(el);
.forEach((el) => { });
parent.removeChild(el);
});
// update index numbers // update index numbers
const labels = parent.querySelectorAll("label"); const labels = parent.querySelectorAll("label");
labels labels.forEach((label) => {
.forEach((label) => { const labelIndex = Number(label.dataset.index);
const labelIndex = Number(label.dataset.index); if (labelIndex > index) {
if (labelIndex > index) { label.dataset.index = labelIndex - 1;
label.dataset.index = labelIndex - 1; label.setAttribute("for", `line-${labelIndex - 1}`);
label.setAttribute("for", `line-${labelIndex - 1}`); label.innerText = `Line ${labelIndex - 1}`;
label.innerText = `Line ${labelIndex - 1}`; }
} });
});
const inputs = parent.querySelectorAll(".param"); const inputs = parent.querySelectorAll(".param");
inputs inputs.forEach((input) => {
.forEach((input) => { const inputIndex = Number(input.dataset.index);
const inputIndex = Number(input.dataset.index); if (inputIndex > index) {
if (inputIndex > index) { input.dataset.index = inputIndex - 1;
input.dataset.index = inputIndex - 1; input.setAttribute("id", `line-${inputIndex - 1}`);
input.setAttribute("id", `line-${inputIndex - 1}`); input.setAttribute("name", `line-${inputIndex - 1}`);
input.setAttribute("name", `line-${inputIndex - 1}`); }
} });
});
const buttons = parent.querySelectorAll(".delete-line.btn"); const buttons = parent.querySelectorAll(".delete-line.btn");
buttons buttons.forEach((button) => {
.forEach((button) => { const buttonIndex = Number(button.dataset.index);
const buttonIndex = Number(button.dataset.index); if (buttonIndex > index) {
if (buttonIndex > index) { button.dataset.index = buttonIndex - 1;
button.dataset.index = buttonIndex - 1; }
} });
});
// disable button if only 1 // disable button if only 1
buttons[0].disabled = buttons.length == 1; buttons[0].disabled = buttons.length == 1;
// update and exit // update and exit

@ -1,7 +1,5 @@
// enable dark mode on load if user prefers dark themes and has not used the toggle // enable dark mode on load if user prefers dark themes and has not used the toggle
getCookie("darkmode") === null && getCookie("darkmode") === null && window.matchMedia("(prefers-color-scheme: dark)").matches && darkmode();
window.matchMedia("(prefers-color-scheme: dark)").matches &&
darkmode();
function toggleTheme() { function toggleTheme() {
// turn on dark mode // turn on dark mode

@ -1,6 +1,6 @@
<?php declare (strict_types = 1); <?php declare(strict_types=1);
require '../vendor/autoload.php'; require "../vendor/autoload.php";
// load environment variables if .env exists // load environment variables if .env exists
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__); $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);

@ -1,4 +1,4 @@
<?php declare (strict_types = 1); <?php declare(strict_types=1);
/** /**
* Model for error messages * Model for error messages

@ -14,11 +14,13 @@ class GoogleFontConverter
*/ */
public static function fetchFontCSS($font, $text) public static function fetchFontCSS($font, $text)
{ {
$url = "https://fonts.googleapis.com/css2?" . http_build_query([ $url =
"family" => $font, "https://fonts.googleapis.com/css2?" .
"text" => $text, http_build_query([
"display" => "fallback", "family" => $font,
]); "text" => $text,
"display" => "fallback",
]);
try { try {
// get the CSS for the font // get the CSS for the font
$response = self::curlGetContents($url); $response = self::curlGetContents($url);

@ -50,7 +50,7 @@ class RendererModel
public $template; public $template;
/** @var array<string, string> $DEFAULTS */ /** @var array<string, string> $DEFAULTS */
private $DEFAULTS = array( private $DEFAULTS = [
"font" => "monospace", "font" => "monospace",
"color" => "#36BCF7", "color" => "#36BCF7",
"background" => "#00000000", "background" => "#00000000",
@ -62,7 +62,7 @@ class RendererModel
"multiline" => "false", "multiline" => "false",
"duration" => "5000", "duration" => "5000",
"pause" => "0", "pause" => "0",
); ];
/** /**
* Construct RendererModel * Construct RendererModel
@ -99,7 +99,7 @@ class RendererModel
if (!$lines) { if (!$lines) {
throw new InvalidArgumentException("Lines parameter must be set."); throw new InvalidArgumentException("Lines parameter must be set.");
} }
$trimmed_lines = rtrim($lines, ';'); $trimmed_lines = rtrim($lines, ";");
$exploded = explode(";", $trimmed_lines); $exploded = explode(";", $trimmed_lines);
// escape special characters to prevent code injection // escape special characters to prevent code injection
return array_map("htmlspecialchars", $exploded); return array_map("htmlspecialchars", $exploded);

@ -5,38 +5,43 @@
style='background-color: <?= $background ?>;' style='background-color: <?= $background ?>;'
width='<?= $width ?>px' height='<?= $height ?>px'> width='<?= $width ?>px' height='<?= $height ?>px'>
<?= preg_replace("/\n/", "\n\t", $fontCSS); ?> <?= preg_replace("/\n/", "\n\t", $fontCSS) ?>
<?php $previousId = "d" . (count($lines) - 1);?> <?php $previousId = "d" . (count($lines) - 1); ?>
<?php for ($i = 0; $i < count($lines); ++$i): ?> <?php for ($i = 0; $i < count($lines); ++$i): ?>
<path id='path<?= $i ?>'> <path id='path<?= $i ?>'>
<?php if (!$multiline): ?> <?php if (!$multiline): ?>
<animate id='d<?= $i ?>' attributeName='d' begin='<?= ($i == 0 ? "0s;" : "") . $previousId ?>.end' dur='<?= $duration + $pause ?>ms' <animate id='d<?= $i ?>' attributeName='d' begin='<?= ($i == 0 ? "0s;" : "") .
values='m0,<?= $height / 2 ?> h0 ; m0,<?= $height / 2 ?> h<?= $width ?> ; m0,<?= $height / 2 ?> h<?= $width ?> ; m0,<?= $height / 2 ?> h0' $previousId ?>.end' dur='<?= $duration + $pause ?>ms'
keyTimes='0;<?= 0.8 * $duration / ($duration + $pause) ?>;<?= (0.8 * $duration + $pause) / ($duration + $pause) ?>;1' /> values='m0,<?= $height / 2 ?> h0 ; m0,<?= $height / 2 ?> h<?= $width ?> ; m0,<?= $height /
2 ?> h<?= $width ?> ; m0,<?= $height / 2 ?> h0'
keyTimes='0;<?= (0.8 * $duration) / ($duration + $pause) ?>;<?= (0.8 * $duration + $pause) /
($duration + $pause) ?>;1' />
<?php else: ?> <?php else: ?>
<?php $lineHeight = $size + 5;?> <?php $lineHeight = $size + 5; ?>
<animate id='d<?= $i ?>' attributeName='d' dur='<?= ($duration + $pause) * ($i + 1) ?>ms' fill="freeze" <animate id='d<?= $i ?>' attributeName='d' dur='<?= ($duration + $pause) * ($i + 1) ?>ms' fill="freeze"
begin='0s;<?= "d" . (count($lines) - 1) ?>.end' keyTimes="0;<?= $i / ($i + 1); ?>;<?= $i / ($i + 1) + $duration / (($duration + $pause) * ($i + 1)); ?>;1" begin='0s;<?= "d" . (count($lines) - 1) ?>.end' keyTimes="0;<?= $i / ($i + 1) ?>;<?= $i / ($i + 1) +
values='m0,<?= ($i + 1) * $lineHeight ?> h0 ; m0,<?= ($i + 1) * $lineHeight ?> h0 ; m0,<?= ($i + 1) * $lineHeight ?> h<?= $width ?> ; m0,<?= ($i + 1) * $lineHeight ?> h<?= $width ?>' /> $duration / (($duration + $pause) * ($i + 1)) ?>;1"
<?php endif;?> values='m0,<?= ($i + 1) * $lineHeight ?> h0 ; m0,<?= ($i + 1) * $lineHeight ?> h0 ; m0,<?= ($i + 1) *
$lineHeight ?> h<?= $width ?> ; m0,<?= ($i + 1) * $lineHeight ?> h<?= $width ?>' />
<?php endif; ?>
</path> </path>
<text font-family='"<?= $font ?>", monospace' fill='<?= $color ?>' font-size='<?= $size ?>' <text font-family='"<?= $font ?>", monospace' fill='<?= $color ?>' font-size='<?= $size ?>'
<?php if ($vCenter): ?> <?php if ($vCenter): ?>
dominant-baseline='middle' dominant-baseline='middle'
<?php else: ?> <?php else: ?>
dominant-baseline='auto' dominant-baseline='auto'
<?php endif;?> <?php endif; ?>
<?php if ($center): ?> <?php if ($center): ?>
x='50%' text-anchor='middle'> x='50%' text-anchor='middle'>
<?php else: ?> <?php else: ?>
x='0%' text-anchor='start'> x='0%' text-anchor='start'>
<?php endif;?> <?php endif; ?>
<textPath xlink:href='#path<?= $i ?>'> <textPath xlink:href='#path<?= $i ?>'>
<?= $lines[$i] . "\n" ?> <?= $lines[$i] . "\n" ?>
</textPath> </textPath>
</text> </text>
<?php $previousId = "d" . $i;?> <?php $previousId = "d" . $i; ?>
<?php endfor;?> <?php endfor; ?>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -1,4 +1,4 @@
<?php declare (strict_types = 1); <?php declare(strict_types=1);
/** /**
* View for rendering error messages * View for rendering error messages

@ -1,4 +1,4 @@
<?php declare (strict_types = 1); <?php declare(strict_types=1);
/** /**
* View for rendering typing SVG * View for rendering typing SVG
@ -26,7 +26,7 @@ class RendererView
public function render() public function render()
{ {
// import variables into symbol table // import variables into symbol table
extract(array( extract([
"lines" => $this->model->lines, "lines" => $this->model->lines,
"font" => $this->model->font, "font" => $this->model->font,
"color" => $this->model->color, "color" => $this->model->color,
@ -40,7 +40,7 @@ class RendererView
"fontCSS" => $this->model->fontCSS, "fontCSS" => $this->model->fontCSS,
"duration" => $this->model->duration, "duration" => $this->model->duration,
"pause" => $this->model->pause, "pause" => $this->model->pause,
)); ]);
// render SVG with output buffering // render SVG with output buffering
ob_start(); ob_start();
include $this->model->template; include $this->model->template;

@ -4,11 +4,10 @@ declare(strict_types=1);
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
require 'vendor/autoload.php'; require "vendor/autoload.php";
final class OptionsTest extends TestCase final class OptionsTest extends TestCase
{ {
/** /**
* Test exception thrown when missing 'lines' parameter * Test exception thrown when missing 'lines' parameter
*/ */
@ -16,11 +15,11 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("Lines parameter must be set."); $this->expectExceptionMessage("Lines parameter must be set.");
$params = array( $params = [
"center" => "true", "center" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
@ -29,10 +28,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidFont(): void public function testValidFont(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"font" => "Open Sans", "font" => "Open Sans",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("Open Sans", $model->font); $this->assertEquals("Open Sans", $model->font);
} }
@ -42,10 +41,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidFontColor(): void public function testValidFontColor(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"color" => "000000", "color" => "000000",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("#000000", $model->color); $this->assertEquals("#000000", $model->color);
} }
@ -55,10 +54,10 @@ final class OptionsTest extends TestCase
*/ */
public function testInvalidFontColor(): void public function testInvalidFontColor(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"color" => "00000", "color" => "00000",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("#36BCF7", $model->color); $this->assertEquals("#36BCF7", $model->color);
} }
@ -68,10 +67,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidBackgroundColor(): void public function testValidBackgroundColor(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"background" => "00000033", "background" => "00000033",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("#00000033", $model->background); $this->assertEquals("#00000033", $model->background);
} }
@ -81,10 +80,10 @@ final class OptionsTest extends TestCase
*/ */
public function testInvalidBackgroundColor(): void public function testInvalidBackgroundColor(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"background" => "00000", "background" => "00000",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("#00000000", $model->background); $this->assertEquals("#00000000", $model->background);
} }
@ -94,10 +93,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidFontSize(): void public function testValidFontSize(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"size" => "18", "size" => "18",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(18, $model->size); $this->assertEquals(18, $model->size);
} }
@ -109,10 +108,10 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("Font size must be a positive number."); $this->expectExceptionMessage("Font size must be a positive number.");
$params = array( $params = [
"lines" => "text", "lines" => "text",
"size" => "0", "size" => "0",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
@ -121,10 +120,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidHeight(): void public function testValidHeight(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"height" => "80", "height" => "80",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(80, $model->height); $this->assertEquals(80, $model->height);
} }
@ -136,10 +135,10 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("Height must be a positive number."); $this->expectExceptionMessage("Height must be a positive number.");
$params = array( $params = [
"lines" => "text", "lines" => "text",
"height" => "x", "height" => "x",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
@ -148,10 +147,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidWidth(): void public function testValidWidth(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"width" => "500", "width" => "500",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(500, $model->width); $this->assertEquals(500, $model->width);
} }
@ -163,10 +162,10 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("Width must be a positive number."); $this->expectExceptionMessage("Width must be a positive number.");
$params = array( $params = [
"lines" => "text", "lines" => "text",
"width" => "-1", "width" => "-1",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
@ -175,10 +174,10 @@ final class OptionsTest extends TestCase
*/ */
public function testCenterIsTrue(): void public function testCenterIsTrue(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"center" => "true", "center" => "true",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(true, $model->center); $this->assertEquals(true, $model->center);
} }
@ -188,10 +187,10 @@ final class OptionsTest extends TestCase
*/ */
public function testCenterIsNotTrue(): void public function testCenterIsNotTrue(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"center" => "other", "center" => "other",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(false, $model->center); $this->assertEquals(false, $model->center);
} }
@ -201,10 +200,10 @@ final class OptionsTest extends TestCase
*/ */
public function testVCenterIsTrue(): void public function testVCenterIsTrue(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"vCenter" => "true", "vCenter" => "true",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(true, $model->vCenter); $this->assertEquals(true, $model->vCenter);
} }
@ -214,10 +213,10 @@ final class OptionsTest extends TestCase
*/ */
public function testVCenterIsNotTrue(): void public function testVCenterIsNotTrue(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"vCenter" => "other", "vCenter" => "other",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(false, $model->vCenter); $this->assertEquals(false, $model->vCenter);
} }
@ -227,10 +226,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidDuration(): void public function testValidDuration(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"duration" => "500", "duration" => "500",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(500, $model->duration); $this->assertEquals(500, $model->duration);
} }
@ -242,10 +241,10 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("duration must be a positive number."); $this->expectExceptionMessage("duration must be a positive number.");
$params = array( $params = [
"lines" => "text", "lines" => "text",
"duration" => "-1", "duration" => "-1",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
@ -254,10 +253,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidPause(): void public function testValidPause(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"pause" => "500", "pause" => "500",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(500, $model->pause); $this->assertEquals(500, $model->pause);
} }
@ -267,10 +266,10 @@ final class OptionsTest extends TestCase
*/ */
public function testValidPauseZero(): void public function testValidPauseZero(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"pause" => "0", "pause" => "0",
); ];
$model = new RendererModel("src/templates/main.php", $params); $model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(0, $model->pause); $this->assertEquals(0, $model->pause);
} }
@ -282,10 +281,10 @@ final class OptionsTest extends TestCase
{ {
$this->expectException("InvalidArgumentException"); $this->expectException("InvalidArgumentException");
$this->expectExceptionMessage("pause must be a non-negative number."); $this->expectExceptionMessage("pause must be a non-negative number.");
$params = array( $params = [
"lines" => "text", "lines" => "text",
"pause" => "-1", "pause" => "-1",
); ];
print_r(new RendererModel("src/templates/main.php", $params)); print_r(new RendererModel("src/templates/main.php", $params));
} }
} }

@ -4,47 +4,46 @@ declare(strict_types=1);
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
require 'vendor/autoload.php'; require "vendor/autoload.php";
final class RendererTest extends TestCase final class RendererTest extends TestCase
{ {
/** /**
* Test normal card render * Test normal card render
*/ */
public function testCardRender(): void public function testCardRender(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_normal.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_normal.svg"), $controller->render());
} }
public function testMultilineCardRender(): void public function testMultilineCardRender(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "200", "height" => "200",
"multiline" => "true", "multiline" => "true",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_multiline.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_multiline.svg"), $controller->render());
} }
@ -55,12 +54,12 @@ final class RendererTest extends TestCase
public function testErrorCardRender(): void public function testErrorCardRender(): void
{ {
// missing lines // missing lines
$params = array( $params = [
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_missing_lines.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_missing_lines.svg"), $controller->render());
} }
@ -70,10 +69,10 @@ final class RendererTest extends TestCase
*/ */
public function testLoadingGoogleFont(): void public function testLoadingGoogleFont(): void
{ {
$params = array( $params = [
"lines" => "text", "lines" => "text",
"font" => "Roboto", "font" => "Roboto",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$expected = preg_replace("/\/\*(.*?)\*\//", "", file_get_contents("tests/svg/test_fonts.svg")); $expected = preg_replace("/\/\*(.*?)\*\//", "", file_get_contents("tests/svg/test_fonts.svg"));
$actual = preg_replace("/\/\*(.*?)\*\//", "", $controller->render()); $actual = preg_replace("/\/\*(.*?)\*\//", "", $controller->render());
@ -85,18 +84,18 @@ final class RendererTest extends TestCase
*/ */
public function testInvalidGoogleFont(): void public function testInvalidGoogleFont(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"font" => "Not-A-Font", "font" => "Not-A-Font",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$expected = str_replace('"monospace"', '"Not-A-Font"', file_get_contents("tests/svg/test_normal.svg")); $expected = str_replace('"monospace"', '"Not-A-Font"', file_get_contents("tests/svg/test_normal.svg"));
$this->assertEquals($expected, $controller->render()); $this->assertEquals($expected, $controller->render());
@ -107,19 +106,19 @@ final class RendererTest extends TestCase
*/ */
public function testLineTrimming(): void public function testLineTrimming(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
"", "",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_normal.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_normal.svg"), $controller->render());
} }
@ -129,17 +128,17 @@ final class RendererTest extends TestCase
*/ */
public function testNormalVerticalAlignment(): void public function testNormalVerticalAlignment(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_normal_vertical_alignment.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_normal_vertical_alignment.svg"), $controller->render());
} }
@ -149,19 +148,19 @@ final class RendererTest extends TestCase
*/ */
public function testPauseParameter(): void public function testPauseParameter(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "50", "height" => "50",
"pause" => "1000", "pause" => "1000",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_pause.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_pause.svg"), $controller->render());
} }
@ -171,20 +170,20 @@ final class RendererTest extends TestCase
*/ */
public function testPauseMultiline(): void public function testPauseMultiline(): void
{ {
$params = array( $params = [
"lines" => implode(";", array( "lines" => implode(";", [
"Full-stack web and app developer", "Full-stack web and app developer",
"Self-taught UI/UX Designer", "Self-taught UI/UX Designer",
"10+ years of coding experience", "10+ years of coding experience",
"Always learning new things", "Always learning new things",
)), ]),
"center" => "true", "center" => "true",
"vCenter" => "true", "vCenter" => "true",
"width" => "380", "width" => "380",
"height" => "200", "height" => "200",
"multiline" => "true", "multiline" => "true",
"pause" => "1000", "pause" => "1000",
); ];
$controller = new RendererController($params); $controller = new RendererController($params);
$this->assertEquals(file_get_contents("tests/svg/test_pause_multiline.svg"), $controller->render()); $this->assertEquals(file_get_contents("tests/svg/test_pause_multiline.svg"), $controller->render());
} }

Loading…
Cancel
Save