@ckeditor/ckeditor5-dev-manual-server 57.4.0 → 59.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,14 @@
7
7
  // Imported as raw strings so they can be adopted into constructable stylesheets.
8
8
  import headerStyles from './manual-header.css?inline';
9
9
  import instructionsStyles from './manual-instructions.css?inline';
10
+ import {
11
+ getFavoriteId,
12
+ loadFavoriteIds,
13
+ saveFavoriteIds,
14
+ toggleFavoriteId,
15
+ updateFavoriteButtonState
16
+ } from './catalog-favorites.js';
17
+ import { createFavoriteIcon } from './favorite-icon.js';
10
18
 
11
19
  const MANUAL_HEADER_DATA_META = 'ck-manual-header';
12
20
 
@@ -19,6 +27,7 @@ const TEMPLATE = /* html */ `
19
27
  <a class="pill back" title="Back to test index">&larr; All tests</a>
20
28
  <span class="divider" aria-hidden="true"></span>
21
29
  <span class="label">
30
+ <button type="button" class="pill favorite" data-action="favorite"></button>
22
31
  <span class="label__name" data-field="name"></span>
23
32
  <span class="label__package" data-field="package"></span>
24
33
  </span>
@@ -47,9 +56,9 @@ const TEMPLATE = /* html */ `
47
56
  /* eslint-enable @stylistic/max-len */
48
57
 
49
58
  /**
50
- * `<ck-manual-header>` renders the manual test chrome: a fixed header bar with the test
51
- * name, package name and a back-to-index link, plus a collapsible instructions panel that
52
- * projects the element's light-DOM children (default slot).
59
+ * `<ck-manual-header>` renders the manual test chrome: a header bar with the test name,
60
+ * package name, back-to-index link and favorite toggle, plus a collapsible instructions
61
+ * panel that projects the element's light-DOM children (default slot).
53
62
  *
54
63
  * The manual test server injects a `<meta name="ck-manual-header">` carrying the package
55
64
  * name and the base-aware catalog href, and the `<script>` that defines this
@@ -61,6 +70,7 @@ const TEMPLATE = /* html */ `
61
70
  */
62
71
  class ManualHeaderElement extends HTMLElement {
63
72
  private _panel!: HTMLElement;
73
+ private _favoriteId!: string;
64
74
 
65
75
  constructor() {
66
76
  super();
@@ -69,6 +79,7 @@ class ManualHeaderElement extends HTMLElement {
69
79
 
70
80
  shadow.adoptedStyleSheets = [ headerStyleSheet ];
71
81
  shadow.innerHTML = TEMPLATE;
82
+ shadow.querySelector<HTMLElement>( '[data-action="favorite"]' )!.append( createFavoriteIcon( 'favorite__icon' ) );
72
83
  }
73
84
 
74
85
  public connectedCallback(): void {
@@ -82,6 +93,10 @@ class ManualHeaderElement extends HTMLElement {
82
93
  const backLink = shadow.querySelector<HTMLAnchorElement>( '.back' )!;
83
94
 
84
95
  backLink.href = data.catalogHref;
96
+ this._favoriteId = getFavoriteId( {
97
+ packageName: data.packageName,
98
+ slug: getSlugFromLocation()
99
+ } );
85
100
 
86
101
  for ( const element of shadow.querySelectorAll<HTMLElement>( '[data-field="name"]' ) ) {
87
102
  element.textContent = this._resolveDisplayName();
@@ -91,6 +106,7 @@ class ManualHeaderElement extends HTMLElement {
91
106
  element.textContent = data.packageName;
92
107
  }
93
108
 
109
+ this._renderFavoriteAction( loadFavoriteIds() );
94
110
  this._setUpInstructions();
95
111
  this._setUpActions( shadow );
96
112
  }
@@ -129,7 +145,9 @@ class ManualHeaderElement extends HTMLElement {
129
145
  return;
130
146
  }
131
147
 
132
- if ( trigger.dataset.action == 'toggle' ) {
148
+ if ( trigger.dataset.action == 'favorite' ) {
149
+ this._toggleFavorite();
150
+ } else if ( trigger.dataset.action == 'toggle' ) {
133
151
  this._toggleInstructions( !this._panel.classList.contains( 'panel--open' ) );
134
152
  } else if ( trigger.dataset.action == 'close' ) {
135
153
  this._toggleInstructions( false );
@@ -143,6 +161,20 @@ class ManualHeaderElement extends HTMLElement {
143
161
  } );
144
162
  }
145
163
 
164
+ private _toggleFavorite(): void {
165
+ const favoriteIds = loadFavoriteIds();
166
+
167
+ toggleFavoriteId( favoriteIds, this._favoriteId );
168
+ saveFavoriteIds( favoriteIds );
169
+ this._renderFavoriteAction( favoriteIds );
170
+ }
171
+
172
+ private _renderFavoriteAction( favoriteIds: Set<string> ): void {
173
+ const trigger = this.shadowRoot!.querySelector<HTMLButtonElement>( '[data-action="favorite"]' )!;
174
+
175
+ updateFavoriteButtonState( trigger, favoriteIds, this._favoriteId );
176
+ }
177
+
146
178
  private _toggleInstructions( isOpen: boolean ): void {
147
179
  const trigger = this.shadowRoot!.querySelector<HTMLElement>( '[data-action="toggle"]' )!;
148
180
 
@@ -11,12 +11,20 @@
11
11
  * reach nested nodes, so instruction typography is scoped here to `ck-manual-header` descendants.
12
12
  */
13
13
 
14
- /* Offset for the fixed header bar injected by the component. */
15
- body {
16
- padding-top: var( --ck-manual-header-height, 44px );
14
+ /*
15
+ * `:where()` keeps zero specificity so anything a test styles itself takes precedence.
16
+ */
17
+ :where(*, *::before, *::after) {
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ :where(body) {
22
+ margin: 0;
23
+ min-height: 100vh;
17
24
  }
18
25
 
19
26
  ck-manual-header {
27
+ margin-bottom: 12px;
20
28
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
21
29
  line-height: 1.6;
22
30
  color: #0a0a0a;
@@ -1,10 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
- import type { Plugin } from "vite";
6
- export interface ManualStaticAssetsPluginOptions {
7
- paths: Array<string>;
8
- include?: Array<string>;
9
- }
10
- export declare function manualStaticAssetsPlugin(options: ManualStaticAssetsPluginOptions): Plugin;
@@ -1,9 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
- import type { IncomingMessage, ServerResponse } from "node:http";
6
- type ManualStaticAssetsMiddleware = (request: IncomingMessage, response: ServerResponse, next: () => void) => void;
7
- export declare function collectManualStaticAssets(patterns: Array<string>, workspaceRoot: string): Map<string, string>;
8
- export declare function createManualStaticAssetsMiddleware(collectStaticAssets: () => Map<string, string>): ManualStaticAssetsMiddleware;
9
- export {};