PluginProbe
Code Snippets / trunk
Code Snippets vtrunk
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
← All changes | js/utils/snippets/snippets.ts +99 -4 3.9.6 → trunk View file →
@@ -1,13 +1,64 @@
1 -import { __ } from '@wordpress/i18n'
1 +import { __, sprintf } from '@wordpress/i18n'
2 +import { isLicensed, isNetworkAdmin } from '../screen'
3 +import { buildUrl } from '../urls'
2 4 import { parseSnippetObject } from './objects'
3 -import type { Snippet, SnippetType } from '../../types/Snippet'
5 +import type { CloudSnippetSchema } from '../../types/schema/CloudSnippetSchema'
6 +import type { SnippetSchema } from '../../types/schema/SnippetSchema'
7 +import type { Snippet, SnippetCodeScope, SnippetScope, SnippetType } from '../../types/Snippet'
4 8
5 9 const PRO_TYPES = new Set<SnippetType>(['css', 'js', 'cond'])
6 10
7 -export const createSnippetObject = (fields: unknown): Snippet =>
11 +export const SNIPPET_TYPE_LABELS: Record<SnippetType, string> = {
12 + php: __('Functions', 'code-snippets'),
13 + html: __('Content', 'code-snippets'),
14 + css: __('Styles', 'code-snippets'),
15 + js: __('Scripts', 'code-snippets'),
16 + cond: __('Conditions', 'code-snippets')
17 +}
18 +
19 +export const SNIPPET_SCOPE_ICONS: Record<SnippetCodeScope, string> = {
20 + 'global': 'admin-site',
21 + 'admin': 'admin-tools',
22 + 'front-end': 'admin-appearance',
23 + 'single-use': 'clock',
24 + 'content': 'shortcode',
25 + 'head-content': 'editor-code',
26 + 'body-content': 'editor-code',
27 + 'footer-content': 'editor-code',
28 + 'admin-css': 'dashboard',
29 + 'site-css': 'admin-customizer',
30 + 'site-head-js': 'media-code',
31 + 'site-footer-js': 'media-code'
32 +}
33 +
34 +export const SNIPPET_SCOPE_DESCRIPTIONS: Record<SnippetCodeScope, string> = {
35 + 'global': __('Run everywhere', 'code-snippets'),
36 + 'admin': __('Only run in administration area', 'code-snippets'),
37 + 'front-end': __('Only run on site front-end', 'code-snippets'),
38 + 'single-use': __('Only run once', 'code-snippets'),
39 + 'content': __('Where inserted in editor', 'code-snippets'),
40 + 'head-content': __('In site header (<head> section)', 'code-snippets'),
41 + 'body-content': __('In site content (start of <body>)', 'code-snippets'),
42 + 'footer-content': __('In site footer (end of <body>)', 'code-snippets'),
43 + 'site-css': __('Site front-end', 'code-snippets'),
44 + 'admin-css': __('Administration area', 'code-snippets'),
45 + 'site-head-js': __('In site header (<head> section)', 'code-snippets'),
46 + 'site-footer-js': __('In site footer (end of <body>)', 'code-snippets')
47 +}
48 +
49 +export const createSnippetObject = (fields?: Partial<Snippet> | Partial<SnippetSchema>): Snippet =>
8 50 parseSnippetObject(fields)
9 51
52 +export const cloneSnippetObject = (snippet: Snippet): Snippet =>
53 + createSnippetObject({
54 + ...snippet,
55 + id: 0,
56 + active: false,
57 + // translators: %s: snippet title.
58 + name: sprintf(__('%s [CLONE]', 'code-snippets'), snippet.name)
59 + })
60 +
10 61 export const getSnippetType = ({ scope }: Pick<Snippet, 'scope'>): SnippetType => {
11 62 switch (true) {
12 63 case scope.endsWith('-css'):
13 64 return 'css'
@@ -25,8 +76,24 @@
25 76 return 'php'
26 77 }
27 78 }
28 79
80 +export const getSnippetEditUrl = (snippet?: Pick<Snippet, 'id'>): string | undefined =>
81 + snippet?.id
82 + ? buildUrl(window.CODE_SNIPPETS?.urls.edit, { id: snippet.id })
83 + : window.CODE_SNIPPETS?.urls.addNew
84 +
85 +export const getSnippetAddNewUrl = (type?: SnippetType): string | undefined =>
86 + type && (isLicensed() || !isProType(type))
87 + ? buildUrl(window.CODE_SNIPPETS?.urls.addNew, { type })
88 + : window.CODE_SNIPPETS?.urls.addNew
89 +
90 +export const getSnippetDisplayName = (snippet: Pick<Snippet, 'name' | 'id' | 'scope'>): string =>
91 + '' === snippet.name.trim()
92 + // translators: %s: snippet identifier.
93 + ? sprintf(isCondition(snippet) ? __('Condition #%d', 'code-snippets') : __('Snippet #%d', 'code-snippets'), snippet.id)
94 + : snippet.name
95 +
29 96 export const validateSnippet = (snippet: Snippet): undefined | string => {
30 97 const missingTitle = '' === snippet.name.trim()
31 98 const missingCode = '' === snippet.code.trim()
32 99
@@ -44,9 +111,9 @@
44 111 return undefined
45 112 }
46 113 }
47 114
48 -export const isCondition = (snippet: Pick<Snippet, 'scope'>): boolean =>
115 +export const isCondition = (snippet: { scope?: SnippetScope }): boolean =>
49 116 'condition' === snippet.scope
50 117
51 118 export const isProSnippet = (snippet: Pick<Snippet, 'scope'>): boolean =>
52 119 PRO_TYPES.has(getSnippetType(snippet))
@@ -52,4 +119,32 @@
52 119 PRO_TYPES.has(getSnippetType(snippet))
53 120
54 121 export const isProType = (type: SnippetType): boolean =>
55 122 PRO_TYPES.has(type)
123 +
124 +export const isSnippetActive = (
125 + snippet: Snippet,
126 + activeByCondition: Map<Snippet['id'], Snippet[]>
127 +): boolean =>
128 + 'cond' === getSnippetType(snippet)
129 + ? 0 < (activeByCondition.get(snippet.id)?.length ?? 0)
130 + : snippet.active
131 +
132 +/**
133 + * Whether the snippet belongs to the network and is not shared with subsites,
134 + * making it read-only outside the network admin.
135 + */
136 +export const isNetworkOnlySnippet = (snippet: Snippet): boolean =>
137 + !isNetworkAdmin() && snippet.network && !snippet.shared_network
138 +
139 +/**
140 + * Whether the current user is able to modify the snippet, either directly or
141 + * through actions such as cloning and trashing.
142 + */
143 +export const canModifySnippet = (snippet: Snippet): boolean =>
144 + !isNetworkOnlySnippet(snippet) &&
145 + !(snippet.shared_network && !window.CODE_SNIPPETS_MANAGE?.hasNetworkCap)
146 +
147 +export const isCloudSnippetDownloadable = (
148 + snippet: Pick<CloudSnippetSchema, 'scope' | 'local_id'>
149 +): boolean =>
150 + !snippet.local_id && (!isProSnippet(snippet) || isLicensed())