Keep the space of the line-break note under the image box.

An invisible copy of the note sits under the image box, so the page
does not jump when the tabs change.
This commit is contained in:
tim
2026-09-26 15:27:51 +02:00
parent f5b41a09d6
commit 4657088d23
3 changed files with 30 additions and 7 deletions
+9 -5
View File
@@ -146,8 +146,10 @@ div.note {
* that the box keeps its size when the tabs change: at most 450px wide, * that the box keeps its size when the tabs change: at most 450px wide,
* and 337px high. That is the 300px writing area, the 35px toolbar (26px * and 337px high. That is the 300px writing area, the 35px toolbar (26px
* buttons, 1px margins, 3px padding and a 1px line) and the 2px border. * buttons, 1px margins, 3px padding and a 1px line) and the 2px border.
* An invisible copy of the note under the editor takes the same space
* under the box.
*/ */
#uploadparent { #uploadparent > .upload {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
max-width: 450px; max-width: 450px;
@@ -155,11 +157,13 @@ div.note {
overflow: auto; overflow: auto;
border: 1px solid #b8c9be; border: 1px solid #b8c9be;
border-radius: 8px; border-radius: 8px;
margin-bottom: 10px;
} }
#uploadparent>div { #uploadparent > .upload > div {
padding: 10px; padding: 10px;
} }
#uploadparent > .spacer {
visibility: hidden;
}
.yes { .yes {
font-weight: bold; font-weight: bold;
@@ -336,7 +340,7 @@ ul.error-box li {
} }
/* On a phone the editor toolbar wraps onto two lines of 42px (40px /* On a phone the editor toolbar wraps onto two lines of 42px (40px
buttons and 1px margins), so the editor is 393px high */ buttons and 1px margins), so the editor is 393px high */
#uploadparent { #uploadparent > .upload {
max-width: none; max-width: none;
height: 393px; height: 393px;
} }
@@ -396,7 +400,7 @@ ul.error-box li {
* (300px), so it wraps onto three lines and the editor is 435px high. * (300px), so it wraps onto three lines and the editor is 435px high.
*/ */
@media (max-width: 345px) { @media (max-width: 345px) {
#uploadparent { #uploadparent > .upload {
height: 435px; height: 435px;
} }
} }
+7 -2
View File
@@ -50,14 +50,16 @@ if (count($validate) !== 0) {
<span id="uploadtab" class="tab<?= isset($validate['upload']) ? ' red' : '' ?>" onclick="showHide('upload');">Image:</span> <span id="uploadtab" class="tab<?= isset($validate['upload']) ? ' red' : '' ?>" onclick="showHide('upload');">Image:</span>
<span id="wordcounter" class="counter" style="display: none;">0 words</span> <span id="wordcounter" class="counter" style="display: none;">0 words</span>
</div> </div>
<?php $line_break_note = '(To get line-breaks&mdash;as in poetry&mdash;instead of paragraph breaks, hit shift-enter instead of enter.)'; ?>
<div class="textarea rightcolumn"> <div class="textarea rightcolumn">
<div id="textparent"> <div id="textparent">
<textarea name="story" id="story" rows="20" cols="50"><?php <textarea name="story" id="story" rows="20" cols="50"><?php
echo (isset($story) ? form_value($story) : '') echo (isset($story) ? form_value($story) : '')
?></textarea> ?></textarea>
<div class="note">(To get line-breaks&mdash;as in poetry&mdash;instead of paragraph breaks, hit shift-enter instead of enter.)</div> <div class="note"><?= $line_break_note ?></div>
</div> </div>
<div class="upload" id="uploadparent" style="display: none;"><div> <div id="uploadparent" style="display: none;">
<div class="upload"><div>
<?php <?php
if (isset($file_src) || isset($img)) { if (isset($file_src) || isset($img)) {
if (isset($file_src)) { if (isset($file_src)) {
@@ -85,6 +87,9 @@ if (isset($file_src) || isset($img)) {
} }
?> ?>
</div></div> </div></div>
<!-- An invisible copy of the note under the story keeps the page height -->
<div class="note spacer" aria-hidden="true"><?= $line_break_note ?></div>
</div>
</div> </div>
<?php if ($is_admin) { ?> <?php if ($is_admin) { ?>
+14
View File
@@ -28,6 +28,20 @@ class SubmitTest extends PageTestCase {
$this->assertStringContainsString('<script type="text/javascript" src="../publish/editor.js"></script>', $page['body']); $this->assertStringContainsString('<script type="text/javascript" src="../publish/editor.js"></script>', $page['body']);
} }
public function testTheImageTabKeepsTheSpaceOfTheNote(): void {
$html = new \DOMDocument();
$html->loadHTML($this->get('/publish')['body'], LIBXML_NOERROR);
$xpath = new \DOMXPath($html);
$note = $xpath->query('//div[@id="textparent"]/div[@class="note"]');
$spacer = $xpath->query('//div[@id="uploadparent"]/div[@class="note spacer"][@aria-hidden="true"]');
$this->assertCount(1, $note);
$this->assertCount(1, $spacer);
$this->assertSame($note[0]->textContent, $spacer[0]->textContent);
$this->assertCount(1, $xpath->query('//div[@id="uploadparent"]/div[@class="upload"]//input[@id="upload"]'));
// Both tabs sit in the same column
$this->assertCount(2, $xpath->query('//div[@class="textarea rightcolumn"]/div[@id="textparent" or @id="uploadparent"]'));
}
public function testEditorsGetNoCaptcha(): void { public function testEditorsGetNoCaptcha(): void {
$this->loginAs(); $this->loginAs();
$body = $this->get('/publish')['body']; $body = $this->get('/publish')['body'];