|
356 | 356 | <input class="ctl-button" type="button" name="demo_btn" value="Action" /> |
357 | 357 | </div> |
358 | 358 | </div> |
| 359 | +
|
| 360 | +<div class="page-break"></div> |
| 361 | +<h2>14) Shorthand Normalization Edge Cases</h2> |
| 362 | +<p>This section tests shorthand CSS normalization patterns that occur in real-world documents, |
| 363 | +ensuring margin, padding, border and background properties are properly expanded to longhands.</p> |
| 364 | +<style> |
| 365 | +.edge-case { margin: 3mm 0 3mm 0; padding: 2mm; border: 0.3mm solid #333; margin-bottom: 2mm; } |
| 366 | +.edge-single { margin: 0; padding: 3pt; border: 0.2mm dotted #666; } |
| 367 | +.edge-four-value { margin-top: 2pt; margin-right: 4pt; margin-bottom: 2pt; margin-left: 4pt; } |
| 368 | +.edge-border-shorthand { border: 0.5pt solid #999; padding: 4pt; } |
| 369 | +.edge-background-single { background: #f0f0f0; padding: 3pt; } |
| 370 | +</style> |
| 371 | +
|
| 372 | +<div class="edge-case"> |
| 373 | + <strong>Case 1: Four-value margin</strong> |
| 374 | + <code>margin: 3mm 0 3mm 0;</code> |
| 375 | + This should expand to T=3mm, R=0, B=3mm, L=0. The box should have vertical margins but no horizontal margins. |
| 376 | +</div> |
| 377 | +
|
| 378 | +<div class="edge-single"> |
| 379 | + <strong>Case 2: Single-value shorthand</strong> |
| 380 | + <code>margin: 0; padding: 3pt;</code> |
| 381 | + All sides should be 0 for margin, 3pt for padding. |
| 382 | +</div> |
| 383 | +
|
| 384 | +<div class="edge-four-value"> |
| 385 | + <strong>Case 3: Individual longhand properties</strong> |
| 386 | + <code>margin-top: 2pt; margin-right: 4pt; margin-bottom: 2pt; margin-left: 4pt;</code> |
| 387 | + Should render with alternating 2pt/4pt margins (simulating different rhythms). |
| 388 | +</div> |
| 389 | +
|
| 390 | +<div class="edge-border-shorthand"> |
| 391 | + <strong>Case 4: Border shorthand expansion</strong> |
| 392 | + <code>border: 0.5pt solid #999; padding: 4pt;</code> |
| 393 | + All four border sides should be solid, 0.5pt width, #999 color. Padding should be 4pt on all sides. |
| 394 | +</div> |
| 395 | +
|
| 396 | +<div class="edge-background-single"> |
| 397 | + <strong>Case 5: Single-value background</strong> |
| 398 | + <code>background: #f0f0f0;</code> |
| 399 | + Background color should be light gray across the entire box. |
| 400 | +</div> |
| 401 | +
|
| 402 | +<div class="page-break"></div> |
| 403 | +<h2>15) Invoice-Style Shorthand Patterns</h2> |
| 404 | +<p>This section replicates the CSS patterns from the real-world invoice_statement test case to verify |
| 405 | +that all shorthand normalization edge cases render correctly.</p> |
| 406 | +<style> |
| 407 | +.inv-header { border-bottom: 1pt solid #444; margin-bottom: 8pt; padding-bottom: 4pt; } |
| 408 | +.inv-meta { float: right; text-align: right; } |
| 409 | +.inv-table { width: 100%; border-collapse: collapse; } |
| 410 | +.inv-table th, .inv-table td { border: 0.5pt solid #999; padding: 4pt; } |
| 411 | +.inv-total { font-weight: bold; background: #f0f0f0; } |
| 412 | +</style> |
| 413 | +
|
| 414 | +<div class="inv-header"> |
| 415 | + <div class="inv-meta">Invoice #INV-2048<br/>Date: 2026-05-10</div> |
| 416 | + <h3 style="margin: 0; font-size: 12pt;">Blue Finch Supply</h3> |
| 417 | + <p style="margin: 2pt 0 0 0;">Monthly service statement</p> |
| 418 | +</div> |
| 419 | +
|
| 420 | +<table class="inv-table"> |
| 421 | + <tr><th>Description</th><th>Qty</th><th>Unit Price</th><th>Amount</th></tr> |
| 422 | + <tr><td>Monitoring subscription</td><td>1</td><td>49.00</td><td>49.00</td></tr> |
| 423 | + <tr><td>Priority support</td><td>2</td><td>15.00</td><td>30.00</td></tr> |
| 424 | + <tr class="inv-total"><td colspan="3">Total</td><td>79.00</td></tr> |
| 425 | +</table> |
| 426 | +
|
| 427 | +<p style="margin-top: 4pt; font-size: 9pt; color: #666;"> |
| 428 | + Edge cases tested: border-bottom shorthand, margin-bottom, padding-bottom, |
| 429 | + border shorthand on table cells, background shorthand on row, and margin values in inline styles. |
| 430 | +</p> |
| 431 | +
|
| 432 | +<div class="page-break"></div> |
| 433 | +<h2>16) Non-Font Shorthand Expansion Checks</h2> |
| 434 | +<p>This section isolates non-font shorthand properties that can be normalized conservatively in invoice-like pages. |
| 435 | +It helps visually verify border-color/style/width and background shorthands without engine workarounds.</p> |
| 436 | +<style> |
| 437 | +.nf-grid { border: 0.4pt solid #a8b3be; padding: 5pt; background: #fbfdff; } |
| 438 | +.nf-case { margin-bottom: 6pt; padding: 4pt; border: 0.4pt solid #aab5c2; } |
| 439 | +.nf-border-color { |
| 440 | + border-style: solid; |
| 441 | + border-width: 1pt; |
| 442 | + border-color: #cc0000 #0077cc #228b22 #a35f00; |
| 443 | +} |
| 444 | +.nf-border-style { |
| 445 | + border-width: 1pt; |
| 446 | + border-style: dotted dashed solid double; |
| 447 | + border-color: #666; |
| 448 | +} |
| 449 | +.nf-border-width { |
| 450 | + border-style: solid; |
| 451 | + border-width: 0.5pt 1.2pt 2pt 3pt; |
| 452 | + border-color: #444; |
| 453 | +} |
| 454 | +.nf-border-mixed { |
| 455 | + border-top: 2pt solid #004f9f; |
| 456 | + border-right: 1pt dashed #2f8f2f; |
| 457 | + border-bottom: 1.5pt dotted #9c3f00; |
| 458 | + border-left: 0.7pt solid #555; |
| 459 | + background: #f6f8fa; |
| 460 | +} |
| 461 | +.nf-bg-hex { background: #f0f0f0; } |
| 462 | +.nf-bg-name { background: silver; } |
| 463 | +</style> |
| 464 | +
|
| 465 | +<div class="nf-grid"> |
| 466 | + <div class="nf-case nf-border-color"> |
| 467 | + <strong>Case A: border-color 4-values</strong> |
| 468 | + <code>border-color: #cc0000 #0077cc #228b22 #a35f00;</code> |
| 469 | + Top/right/bottom/left borders should show distinct colors. |
| 470 | + </div> |
| 471 | +
|
| 472 | + <div class="nf-case nf-border-style"> |
| 473 | + <strong>Case B: border-style 4-values</strong> |
| 474 | + <code>border-style: dotted dashed solid double;</code> |
| 475 | + Border pattern should vary by side. |
| 476 | + </div> |
| 477 | +
|
| 478 | + <div class="nf-case nf-border-width"> |
| 479 | + <strong>Case C: border-width 4-values</strong> |
| 480 | + <code>border-width: 0.5pt 1.2pt 2pt 3pt;</code> |
| 481 | + Border thickness should visibly differ by side. |
| 482 | + </div> |
| 483 | +
|
| 484 | + <div class="nf-case nf-border-mixed"> |
| 485 | + <strong>Case D: per-side border shorthand</strong> |
| 486 | + <code>border-top/right/bottom/left: ...</code> |
| 487 | + Each side should preserve its own width/style/color tuple. |
| 488 | + </div> |
| 489 | +
|
| 490 | + <div class="nf-case nf-bg-hex"> |
| 491 | + <strong>Case E: background shorthand (hex color)</strong> |
| 492 | + <code>background: #f0f0f0;</code> |
| 493 | + Block should render with a light gray fill. |
| 494 | + </div> |
| 495 | +
|
| 496 | + <div class="nf-case nf-bg-name"> |
| 497 | + <strong>Case F: background shorthand (named color)</strong> |
| 498 | + <code>background: silver;</code> |
| 499 | + Block should render with named color fill. |
| 500 | + </div> |
| 501 | +</div> |
| 502 | +
|
| 503 | +<div class="page-break"></div> |
| 504 | +<h2>17) Non-Font Shorthand Stress Cases</h2> |
| 505 | +<p>This section focuses on shorthand combinations that are often normalized conservatively in static PDF renderers. |
| 506 | +The primary target here is complex <code>background</code> shorthand token ordering and mixed token sets.</p> |
| 507 | +<style> |
| 508 | +.nf2-wrap { border: 0.4pt solid #9fb0be; padding: 5pt; background: #fcfdff; } |
| 509 | +.nf2-case { margin-bottom: 6pt; padding: 4pt; border: 0.4pt solid #a6b2bf; } |
| 510 | +.nf2-bg-order-a { background: #e8f2ff no-repeat left top; } |
| 511 | +.nf2-bg-order-b { background: no-repeat right top #ffeedd; } |
| 512 | +.nf2-bg-order-c { background: left bottom #eaf9ea no-repeat; } |
| 513 | +.nf2-bg-with-image-token { background: #f5eefc url("missing-resource.png") no-repeat center top; } |
| 514 | +.nf2-bg-transparent { background: transparent; } |
| 515 | +.nf2-margin-pad-a { margin: 2pt 8pt; padding: 1pt 3pt 5pt; } |
| 516 | +.nf2-margin-pad-b { margin: 4pt 2pt 1pt; padding: 2pt; } |
| 517 | +</style> |
| 518 | +
|
| 519 | +<div class="nf2-wrap"> |
| 520 | + <div class="nf2-case nf2-bg-order-a"> |
| 521 | + <strong>Case A: background order (color first)</strong> |
| 522 | + <code>background: #e8f2ff no-repeat left top;</code> |
| 523 | + Expect light blue fill. |
| 524 | + </div> |
| 525 | +
|
| 526 | + <div class="nf2-case nf2-bg-order-b"> |
| 527 | + <strong>Case B: background order (color last)</strong> |
| 528 | + <code>background: no-repeat right top #ffeedd;</code> |
| 529 | + Expect peach fill. |
| 530 | + </div> |
| 531 | +
|
| 532 | + <div class="nf2-case nf2-bg-order-c"> |
| 533 | + <strong>Case C: background order (position first)</strong> |
| 534 | + <code>background: left bottom #eaf9ea no-repeat;</code> |
| 535 | + Expect pale green fill. |
| 536 | + </div> |
| 537 | +
|
| 538 | + <div class="nf2-case nf2-bg-with-image-token"> |
| 539 | + <strong>Case D: background with image token</strong> |
| 540 | + <code>background: #f5eefc url("missing-resource.png") no-repeat center top;</code> |
| 541 | + Even if image token is ignored, fallback lavender color should still fill the block. |
| 542 | + </div> |
| 543 | +
|
| 544 | + <div class="nf2-case nf2-bg-transparent"> |
| 545 | + <strong>Case E: transparent background</strong> |
| 546 | + <code>background: transparent;</code> |
| 547 | + Should not paint an opaque fill. |
| 548 | + </div> |
| 549 | +
|
| 550 | + <div class="nf2-case nf2-margin-pad-a"> |
| 551 | + <strong>Case F: mixed margin/padding shorthand (2 + 3 values)</strong> |
| 552 | + <code>margin: 2pt 8pt; padding: 1pt 3pt 5pt;</code> |
| 553 | + Horizontal margins should be wider than vertical, with asymmetric bottom padding. |
| 554 | + </div> |
| 555 | +
|
| 556 | + <div class="nf2-case nf2-margin-pad-b"> |
| 557 | + <strong>Case G: mixed margin/padding shorthand (3 + 1 values)</strong> |
| 558 | + <code>margin: 4pt 2pt 1pt; padding: 2pt;</code> |
| 559 | + Top margin should be largest; padding should be uniform. |
| 560 | + </div> |
| 561 | +</div> |
| 562 | +
|
| 563 | +<div class="page-break"></div> |
| 564 | +<h2>18) Shorthand vs Longhand Override Order</h2> |
| 565 | +<p>This section checks cascade order interactions where shorthand and matching longhands appear |
| 566 | +in different declaration orders. Later declarations should win.</p> |
| 567 | +<style> |
| 568 | +.ord-wrap { border: 0.4pt solid #9eacb8; padding: 5pt; background: #fcfdff; } |
| 569 | +.ord-case { margin-bottom: 6pt; padding: 4pt; border: 0.4pt solid #a9b5c1; } |
| 570 | +
|
| 571 | +.ord-bg-longhand-wins { |
| 572 | + background: #ddeeff; |
| 573 | + background-color: #ffe6e6; |
| 574 | +} |
| 575 | +.ord-bg-shorthand-wins { |
| 576 | + background-color: #ffe6e6; |
| 577 | + background: #ddeeff; |
| 578 | +} |
| 579 | +
|
| 580 | +.ord-border-width-longhand-wins { |
| 581 | + border: 0.6pt solid #446; |
| 582 | + border-left-width: 3pt; |
| 583 | +} |
| 584 | +.ord-border-width-shorthand-wins { |
| 585 | + border-left-width: 3pt; |
| 586 | + border: 0.6pt solid #446; |
| 587 | +} |
| 588 | +
|
| 589 | +.ord-border-color-longhand-wins { |
| 590 | + border: 0.8pt solid #999; |
| 591 | + border-right-color: #cc0000; |
| 592 | +} |
| 593 | +.ord-border-color-shorthand-wins { |
| 594 | + border-right-color: #cc0000; |
| 595 | + border: 0.8pt solid #999; |
| 596 | +} |
| 597 | +</style> |
| 598 | +
|
| 599 | +<div class="ord-wrap"> |
| 600 | + <div class="ord-case ord-bg-longhand-wins"> |
| 601 | + <strong>Case A: background then background-color</strong> |
| 602 | + <code>background: #ddeeff; background-color: #ffe6e6;</code> |
| 603 | + Expected fill: pink (#ffe6e6). |
| 604 | + </div> |
| 605 | +
|
| 606 | + <div class="ord-case ord-bg-shorthand-wins"> |
| 607 | + <strong>Case B: background-color then background</strong> |
| 608 | + <code>background-color: #ffe6e6; background: #ddeeff;</code> |
| 609 | + Expected fill: light blue (#ddeeff). |
| 610 | + </div> |
| 611 | +
|
| 612 | + <div class="ord-case ord-border-width-longhand-wins"> |
| 613 | + <strong>Case C: border then border-left-width</strong> |
| 614 | + <code>border: 0.6pt solid #446; border-left-width: 3pt;</code> |
| 615 | + Left border should be much thicker than other sides. |
| 616 | + </div> |
| 617 | +
|
| 618 | + <div class="ord-case ord-border-width-shorthand-wins"> |
| 619 | + <strong>Case D: border-left-width then border</strong> |
| 620 | + <code>border-left-width: 3pt; border: 0.6pt solid #446;</code> |
| 621 | + Left border should revert to same thickness as other sides. |
| 622 | + </div> |
| 623 | +
|
| 624 | + <div class="ord-case ord-border-color-longhand-wins"> |
| 625 | + <strong>Case E: border then border-right-color</strong> |
| 626 | + <code>border: 0.8pt solid #999; border-right-color: #cc0000;</code> |
| 627 | + Right border should be red; other sides gray. |
| 628 | + </div> |
| 629 | +
|
| 630 | + <div class="ord-case ord-border-color-shorthand-wins"> |
| 631 | + <strong>Case F: border-right-color then border</strong> |
| 632 | + <code>border-right-color: #cc0000; border: 0.8pt solid #999;</code> |
| 633 | + All sides should be gray (right red override should be overwritten). |
| 634 | + </div> |
| 635 | +</div> |
359 | 636 | HTML; |
360 | 637 |
|
361 | 638 | $pdf->addHTMLCell($html, 15, 18, 180, 0); |
|
0 commit comments