PluginProbe
Parse.ly / 3.24.2
Parse.ly v3.24.2
3.24.2 3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 3.20.2 All 106 releases
wp-parsely / src / content-helper / common / utils / functions.ts

functions.ts in Parse.ly 3.24.2, at src/content-helper/common/utils/functions.ts

191 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { select, subscribe } from '@wordpress/data';
2
3 /**
4 * Escapes special characters in a string for use in a regular expression.
5 *
6 * @since 3.14.0
7 * @since 3.14.1 Moved from `editor-sidebar/smart-linking/utils.ts` to `common/utils/functions.ts`.
8 *
9 * @param {string} string The string to be escaped.
10 *
11 * @return {string} The escaped string.
12 */
13 export function escapeRegExp( string: string ): string {
14 return string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); // $& means the whole matched string.
15 }
16
17 /**
18 * Generates both http and https versions of a URL.
19 *
20 * @since 3.14.3
21 *
22 * @param {string} url The URL to generate protocol variants for.
23 *
24 * @return {string[]} An array containing both http and https versions of the URL.
25 */
26 export function generateProtocolVariants( url: string ): string[] {
27 const strippedUrl = url.replace( /^https?:\/\//i, '' );
28
29 const httpUrl = 'http://' + strippedUrl;
30 const httpsUrl = 'https://' + strippedUrl;
31
32 return [ httpUrl, httpsUrl ];
33 }
34
35 /**
36 * Checks if the editor is ready to be interacted with.
37 * It waits for the editor to be clean or to have at least one block, and it resolves when it's ready.
38 *
39 * @since 3.14.0
40 * @since 3.16.0 Moved from `editor-sidebar/smart-linking/component-block-change.tsx`
41 * to `common/utils/functions.ts`.
42 */
43 export async function isEditorReady(): Promise<void> {
44 return new Promise( ( resolve ) => {
45 const unsubscribeEditorReady = subscribe( () => {
46 if ( select( 'core/editor' ).isCleanNewPost() || select( 'core/block-editor' ).getBlockCount() > 0 ) {
47 unsubscribeEditorReady();
48 resolve();
49 }
50 } );
51 } );
52 }
53
54 /**
55 * Returns the document holding the Editor canvas.
56 *
57 * The Post Editor is always iframed as of WordPress 7.1, and conditionally
58 * iframed before it. Falls back to the admin document when not iframed.
59 *
60 * @since 3.23.6
61 *
62 * @return {Document} The document holding the Editor canvas.
63 */
64 export function getEditorCanvasDocument(): Document {
65 // WordPress 6.5 and later name the canvas iframe.
66 const namedCanvas = document.querySelector<HTMLIFrameElement>(
67 'iframe[name="editor-canvas"]'
68 );
69
70 if ( namedCanvas?.contentDocument ) {
71 return namedCanvas.contentDocument;
72 }
73
74 // WordPress 6.3 and 6.4 iframe the canvas without naming the iframe, so it
75 // gets identified by the Editor markup it holds.
76 const iframes = Array.from(
77 document.querySelectorAll<HTMLIFrameElement>( 'iframe' )
78 );
79
80 for ( const iframe of iframes ) {
81 // Reading contentDocument returns null for cross-origin iframes.
82 const iframeDocument = iframe.contentDocument;
83
84 if ( iframeDocument?.querySelector( '.editor-styles-wrapper, .block-editor-block-list__layout' ) ) {
85 return iframeDocument;
86 }
87 }
88
89 return document;
90 }
91
92 /**
93 * Waits for an element to exist in the Editor canvas, which is populated
94 * asynchronously after the Editor reports itself as ready.
95 *
96 * @since 3.23.6
97 *
98 * @param {string} selector The selector to wait for.
99 * @param {number} timeoutMs How long to wait before giving up, in milliseconds.
100 *
101 * @return {Promise<HTMLElement|null>} The matched element, or null on timeout.
102 */
103 export function waitForEditorCanvasElement(
104 selector: string,
105 timeoutMs: number = 5000
106 ): Promise<HTMLElement | null> {
107 return new Promise( ( resolve ) => {
108 const deadline = Date.now() + timeoutMs;
109
110 const poll = (): void => {
111 const element =
112 getEditorCanvasDocument().querySelector<HTMLElement>( selector );
113
114 if ( element ) {
115 resolve( element );
116 return;
117 }
118
119 if ( Date.now() >= deadline ) {
120 resolve( null );
121 return;
122 }
123
124 setTimeout( poll, 100 );
125 };
126
127 poll();
128 } );
129 }
130
131 /**
132 * Adds ITM parameters to a URL.
133 *
134 * @since 3.19.0
135 *
136 * @param {string} url The URL to add ITM parameters to.
137 * @param {Object} itmParams The ITM parameters to add to the URL.
138 * @param {string} itmParams.campaign The campaign parameter.
139 * @param {string} itmParams.source The source parameter.
140 * @param {string} itmParams.medium The medium parameter.
141 * @param {string} itmParams.content The content parameter.
142 * @param {string} itmParams.term The term parameter.
143 *
144 * @return {string} The URL with ITM parameters added.
145 */
146 export function addITMParamsToURL( url: string, itmParams: {
147 campaign: string;
148 source?: string;
149 medium?: string;
150 content?: string;
151 term?: string;
152 } ): string {
153 const urlObj = new URL( url );
154 urlObj.searchParams.set( 'itm_campaign', itmParams.campaign );
155
156 if ( itmParams.source ) {
157 urlObj.searchParams.set( 'itm_source', itmParams.source );
158 }
159 if ( itmParams.medium ) {
160 urlObj.searchParams.set( 'itm_medium', itmParams.medium );
161 }
162 if ( itmParams.content ) {
163 urlObj.searchParams.set( 'itm_content', itmParams.content );
164 }
165 if ( itmParams.term ) {
166 urlObj.searchParams.set( 'itm_term', itmParams.term );
167 }
168
169 return urlObj.toString();
170 }
171
172 /**
173 * Removes ITM parameters from a URL.
174 *
175 * @since 3.19.0
176 *
177 * @param {string} url The URL to remove ITM parameters from.
178 *
179 * @return {string} The URL with ITM parameters removed.
180 */
181 export function removeITMParamsFromURL( url: string ): string {
182 const urlObj = new URL( url );
183 urlObj.searchParams.delete( 'itm_campaign' );
184 urlObj.searchParams.delete( 'itm_source' );
185 urlObj.searchParams.delete( 'itm_medium' );
186 urlObj.searchParams.delete( 'itm_content' );
187 urlObj.searchParams.delete( 'itm_term' );
188
189 return urlObj.toString();
190 }
191