@elementor/editor-site-navigation 0.4.0 → 0.4.2

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.4.2](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.4.1...@elementor/editor-site-navigation@0.4.2) (2023-05-30)
7
+
8
+ **Note:** Version bump only for package @elementor/editor-site-navigation
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.4.1](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.4.0...@elementor/editor-site-navigation@0.4.1) (2023-05-23)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **site-navigation:** render special chars [ED-10809] ([#42](https://github.com/elementor/elementor-packages/issues/42)) ([a276cf3](https://github.com/elementor/elementor-packages/commit/a276cf36e4f428da3b109f0bcd4e83ca3501e793))
20
+
21
+
22
+
23
+
24
+
6
25
  # [0.4.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.3.0...@elementor/editor-site-navigation@0.4.0) (2023-05-21)
7
26
 
8
27
 
package/dist/index.js CHANGED
@@ -138,12 +138,27 @@ function DocTypeChip({ postType, docType, label }) {
138
138
  var import_ui3 = require("@elementor/ui");
139
139
  var React3 = __toESM(require("react"));
140
140
  var import_editor_documents = require("@elementor/editor-documents");
141
+
142
+ // src/hooks/use-reverse-html-entities.ts
143
+ var import_react2 = require("react");
144
+ function useReverseHtmlEntities(escapedHTML = "") {
145
+ return (0, import_react2.useMemo)(() => {
146
+ const textarea = document.createElement("textarea");
147
+ textarea.innerHTML = escapedHTML;
148
+ const { value } = textarea;
149
+ textarea.remove();
150
+ return value;
151
+ }, [escapedHTML]);
152
+ }
153
+
154
+ // src/components/top-bar/post-list-item.tsx
141
155
  function PostListItem({ post, closePopup }) {
142
156
  const navigateToDocument = (0, import_editor_documents.useNavigateToDocument)();
157
+ const postTitle = useReverseHtmlEntities(post.title);
143
158
  return /* @__PURE__ */ React3.createElement(import_ui3.MenuItem, { dense: true, sx: { width: "100%" }, onClick: () => {
144
159
  closePopup();
145
160
  navigateToDocument(post.id);
146
- } }, post.title, /* @__PURE__ */ React3.createElement(DocTypeChip, { postType: post.type.post_type, docType: post.type.doc_type, label: post.type.label }));
161
+ } }, postTitle, /* @__PURE__ */ React3.createElement(DocTypeChip, { postType: post.type.post_type, docType: post.type.doc_type, label: post.type.label }));
147
162
  }
148
163
 
149
164
  // src/components/top-bar/create-post-list-item.tsx
@@ -152,10 +167,10 @@ var React4 = __toESM(require("react"));
152
167
 
153
168
  // src/hooks/use-create-page.ts
154
169
  var import_api_fetch2 = __toESM(require("@wordpress/api-fetch"));
155
- var import_react2 = require("react");
170
+ var import_react3 = require("react");
156
171
  var endpointPath2 = "/elementor/v1/site-navigation/add-new-post";
157
172
  function useCreatePage() {
158
- const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
173
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
159
174
  return {
160
175
  create: () => {
161
176
  setIsLoading(true);
@@ -190,13 +205,14 @@ function CreatePostListItem({ closePopup }) {
190
205
  function RecentlyEdited() {
191
206
  const activeDocument = (0, import_editor_documents3.useActiveDocument)();
192
207
  const hostDocument = (0, import_editor_documents3.useHostDocument)();
193
- const document = activeDocument && activeDocument.type.value !== "kit" ? activeDocument : hostDocument;
194
- const { recentPosts } = useRecentPosts(document?.id);
208
+ const document2 = activeDocument && activeDocument.type.value !== "kit" ? activeDocument : hostDocument;
209
+ const { recentPosts } = useRecentPosts(document2?.id);
195
210
  const popupState = (0, import_ui5.usePopupState)({
196
211
  variant: "popover",
197
212
  popupId: "elementor-v2-top-bar-recently-edited"
198
213
  });
199
- if (!document) {
214
+ const documentTitle = useReverseHtmlEntities(document2?.title);
215
+ if (!document2) {
200
216
  return null;
201
217
  }
202
218
  return /* @__PURE__ */ React5.createElement(import_ui5.Box, { sx: { cursor: "default" } }, /* @__PURE__ */ React5.createElement(
@@ -210,8 +226,8 @@ function RecentlyEdited() {
210
226
  /* @__PURE__ */ React5.createElement(
211
227
  Indicator,
212
228
  {
213
- title: document.title,
214
- status: document.status
229
+ title: documentTitle,
230
+ status: document2.status
215
231
  }
216
232
  )
217
233
  ), /* @__PURE__ */ React5.createElement(
package/dist/index.mjs CHANGED
@@ -120,12 +120,27 @@ function DocTypeChip({ postType, docType, label }) {
120
120
  import { MenuItem } from "@elementor/ui";
121
121
  import * as React3 from "react";
122
122
  import { useNavigateToDocument } from "@elementor/editor-documents";
123
+
124
+ // src/hooks/use-reverse-html-entities.ts
125
+ import { useMemo } from "react";
126
+ function useReverseHtmlEntities(escapedHTML = "") {
127
+ return useMemo(() => {
128
+ const textarea = document.createElement("textarea");
129
+ textarea.innerHTML = escapedHTML;
130
+ const { value } = textarea;
131
+ textarea.remove();
132
+ return value;
133
+ }, [escapedHTML]);
134
+ }
135
+
136
+ // src/components/top-bar/post-list-item.tsx
123
137
  function PostListItem({ post, closePopup }) {
124
138
  const navigateToDocument = useNavigateToDocument();
139
+ const postTitle = useReverseHtmlEntities(post.title);
125
140
  return /* @__PURE__ */ React3.createElement(MenuItem, { dense: true, sx: { width: "100%" }, onClick: () => {
126
141
  closePopup();
127
142
  navigateToDocument(post.id);
128
- } }, post.title, /* @__PURE__ */ React3.createElement(DocTypeChip, { postType: post.type.post_type, docType: post.type.doc_type, label: post.type.label }));
143
+ } }, postTitle, /* @__PURE__ */ React3.createElement(DocTypeChip, { postType: post.type.post_type, docType: post.type.doc_type, label: post.type.label }));
129
144
  }
130
145
 
131
146
  // src/components/top-bar/create-post-list-item.tsx
@@ -172,13 +187,14 @@ function CreatePostListItem({ closePopup }) {
172
187
  function RecentlyEdited() {
173
188
  const activeDocument = useActiveDocument();
174
189
  const hostDocument = useHostDocument();
175
- const document = activeDocument && activeDocument.type.value !== "kit" ? activeDocument : hostDocument;
176
- const { recentPosts } = useRecentPosts(document?.id);
190
+ const document2 = activeDocument && activeDocument.type.value !== "kit" ? activeDocument : hostDocument;
191
+ const { recentPosts } = useRecentPosts(document2?.id);
177
192
  const popupState = usePopupState({
178
193
  variant: "popover",
179
194
  popupId: "elementor-v2-top-bar-recently-edited"
180
195
  });
181
- if (!document) {
196
+ const documentTitle = useReverseHtmlEntities(document2?.title);
197
+ if (!document2) {
182
198
  return null;
183
199
  }
184
200
  return /* @__PURE__ */ React5.createElement(Box, { sx: { cursor: "default" } }, /* @__PURE__ */ React5.createElement(
@@ -192,8 +208,8 @@ function RecentlyEdited() {
192
208
  /* @__PURE__ */ React5.createElement(
193
209
  Indicator,
194
210
  {
195
- title: document.title,
196
- status: document.status
211
+ title: documentTitle,
212
+ status: document2.status
197
213
  }
198
214
  )
199
215
  ), /* @__PURE__ */ React5.createElement(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-site-navigation",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -32,8 +32,8 @@
32
32
  "dev": "tsup src/index.ts --format esm --clean"
33
33
  },
34
34
  "dependencies": {
35
- "@elementor/editor-app-bar": "^0.4.0",
36
- "@elementor/editor-documents": "^0.4.0",
35
+ "@elementor/editor-app-bar": "^0.4.1",
36
+ "@elementor/editor-documents": "^0.5.0",
37
37
  "@elementor/icons": "^0.2.1",
38
38
  "@elementor/ui": "^1.4.50",
39
39
  "@wordpress/api-fetch": "^6.27.0",
@@ -46,5 +46,5 @@
46
46
  "elementor": {
47
47
  "type": "extension"
48
48
  },
49
- "gitHead": "45afd449fda346eea0f8a431ebca7d6c1d518dd1"
49
+ "gitHead": "2299a390624d60ea9d1e35e7d8dcc4208816d555"
50
50
  }
@@ -177,6 +177,61 @@ describe( '@elementor/recently-edited - Top bar Recently Edited', () => {
177
177
  expect( getByText( 'Test post' ) ).toBeInTheDocument();
178
178
  } );
179
179
 
180
+ it( 'should render titles with HTML entities', () => {
181
+ // Arrange.
182
+ jest.mocked( useActiveDocument ).mockImplementation( () =>
183
+ createMockDocument( {
184
+ id: 1,
185
+ title: 'Header title with special char ¥',
186
+ type: {
187
+ value: 'header',
188
+ label: 'Header',
189
+ },
190
+ } )
191
+ );
192
+
193
+ const isLoading = false;
194
+ const recentPosts: Post[] = [
195
+ {
196
+ id: 1,
197
+ title: 'Post title with <h1>HTML</h1>',
198
+ edit_url: 'some_url',
199
+ type: {
200
+ post_type: 'post',
201
+ doc_type: 'wp-post',
202
+ label: 'Post',
203
+ },
204
+ date_modified: 123,
205
+ },
206
+ {
207
+ id: 2,
208
+ title: 'Post title with &lt;HTML entities&gt;',
209
+ edit_url: 'some_url_2',
210
+ type: {
211
+ post_type: 'post',
212
+ doc_type: 'wp-post',
213
+ label: 'Post 2',
214
+ },
215
+ date_modified: 1234,
216
+ },
217
+ ];
218
+
219
+ jest.mocked( useRecentPosts ).mockReturnValue( { isLoading, recentPosts } );
220
+
221
+ // Act.
222
+ const { getByText, getByRole } = render( <RecentlyEdited /> );
223
+
224
+ // Assert - the document title should be rendered with the HTML entity.
225
+ expect( getByText( 'Header title with special char ¥' ) ).toBeInTheDocument();
226
+
227
+ // Open the posts list.
228
+ getByRole( 'button' ).click();
229
+
230
+ // Assert - the post title should be rendered with the HTML entity.
231
+ expect( getByText( 'Post title with <h1>HTML</h1>' ) ).toBeInTheDocument();
232
+ expect( getByText( 'Post title with <HTML entities>' ) ).toBeInTheDocument();
233
+ } );
234
+
180
235
  it( 'should navigate to document on click', () => {
181
236
  // Arrange.
182
237
  const navigateToDocument = jest.fn();
@@ -3,6 +3,7 @@ import { MenuItem, MenuItemProps } from '@elementor/ui';
3
3
  import * as React from 'react';
4
4
  import { Post } from '../../hooks/use-recent-posts';
5
5
  import { useNavigateToDocument } from '@elementor/editor-documents';
6
+ import { useReverseHtmlEntities } from '../../hooks/use-reverse-html-entities';
6
7
 
7
8
  type Props = MenuItemProps & {
8
9
  post: Post;
@@ -11,13 +12,14 @@ type Props = MenuItemProps & {
11
12
 
12
13
  export function PostListItem( { post, closePopup }: Props ) {
13
14
  const navigateToDocument = useNavigateToDocument();
15
+ const postTitle = useReverseHtmlEntities( post.title );
14
16
 
15
17
  return (
16
18
  <MenuItem dense sx={ { width: '100%' } } onClick={ () => {
17
19
  closePopup();
18
20
  navigateToDocument( post.id );
19
21
  } }>
20
- { post.title }
22
+ { postTitle }
21
23
  <DocTypeChip postType={ post.type.post_type } docType={ post.type.doc_type } label={ post.type.label } />
22
24
  </MenuItem>
23
25
  );
@@ -17,6 +17,7 @@ import useRecentPosts from '../../hooks/use-recent-posts';
17
17
  import { __ } from '@wordpress/i18n';
18
18
  import { PostListItem } from './post-list-item';
19
19
  import { CreatePostListItem } from './create-post-list-item';
20
+ import { useReverseHtmlEntities } from '../../hooks/use-reverse-html-entities';
20
21
 
21
22
  export default function RecentlyEdited() {
22
23
  const activeDocument = useActiveDocument();
@@ -32,6 +33,8 @@ export default function RecentlyEdited() {
32
33
  popupId: 'elementor-v2-top-bar-recently-edited',
33
34
  } );
34
35
 
36
+ const documentTitle = useReverseHtmlEntities( document?.title );
37
+
35
38
  if ( ! document ) {
36
39
  return null;
37
40
  }
@@ -45,7 +48,7 @@ export default function RecentlyEdited() {
45
48
  { ...bindTrigger( popupState ) }
46
49
  >
47
50
  <Indicator
48
- title={ document.title }
51
+ title={ documentTitle }
49
52
  status={ document.status }
50
53
  />
51
54
  </Button>
@@ -0,0 +1,14 @@
1
+ import { useMemo } from 'react';
2
+
3
+ export function useReverseHtmlEntities( escapedHTML = '' ) {
4
+ return useMemo( () => {
5
+ const textarea = document.createElement( 'textarea' );
6
+ textarea.innerHTML = escapedHTML;
7
+
8
+ const { value } = textarea;
9
+
10
+ textarea.remove();
11
+
12
+ return value;
13
+ }, [ escapedHTML ] );
14
+ }