Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
085b1c7
chore: add pre-commit hook to run lint-staged for code quality
imantsk Feb 18, 2026
b978287
chore: add pre-commit hooks for automatic linting and autofixing
imantsk Feb 18, 2026
1a5ded6
chore: update package.json and package-lock.json to add husky and lin…
imantsk Feb 18, 2026
05804b9
chore: update dependencies
imantsk Feb 18, 2026
737dd08
feat: add linting script for readme.txt to enforce WordPress.org form…
imantsk Feb 18, 2026
abfcb51
feat: add linting script for CHANGELOG.md to ensure formatting consis…
imantsk Feb 18, 2026
648c4ec
chore: add linting scripts for readme.txt and CHANGELOG.md to package…
imantsk Feb 18, 2026
8e78d27
chore: update readme.txt for consistency in section headings
imantsk Feb 18, 2026
450c8dc
feat: enhance linting rules for CHANGELOG.md formatting consistency
imantsk Feb 18, 2026
8db8d71
chore: fix formatting inconsistencies in CHANGELOG.md
imantsk Feb 18, 2026
443be81
chore: add postcss-hsl-legacy and update webpack-css
imantsk Feb 18, 2026
e81a7a1
chore: update devDependencies and lockfile
imantsk Feb 18, 2026
1a91b7c
chore: refactor lint-changelog to satisfy ESLint
imantsk Feb 18, 2026
5bb09aa
chore: refactor lint-readme to satisfy ESLint
imantsk Feb 18, 2026
664aadd
fix: remove unnecessary toString() and fix indentation in SnippetForm…
imantsk Feb 18, 2026
f7b1174
fix: guard against undefined searchResults in CloudSearch
imantsk Feb 18, 2026
bcc7791
fix: use optional chaining in admin-bar pagination update
imantsk Feb 18, 2026
9e496e2
fix: stylelint fixes in admin-bar.scss
imantsk Feb 18, 2026
3106c2a
fix: stylelint fixes in _badges.scss
imantsk Feb 18, 2026
91947c4
fix: stylelint fixes in _toolbar.scss
imantsk Feb 18, 2026
3da7f1e
fix: stylelint fixes in _sidebar.scss
imantsk Feb 18, 2026
7de4636
fix: stylelint fixes in import SCSS files
imantsk Feb 18, 2026
5c87824
fix: stylelint fixes in manage.scss and welcome.scss
imantsk Feb 18, 2026
d6086c8
fix: remove trailing blank line from test-flat-files-hooks.php
imantsk Feb 18, 2026
598cade
fix: remove unused postcss-color-hsl type declaration
imantsk Feb 18, 2026
c4b2223
fix: make .husky/pre-commit executable
imantsk Feb 18, 2026
bef5b8b
chore: remove duplicate eslint override
imantsk Feb 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Run lint-staged (will autofix and stage fixed files).
# Exit non-zero only if non-fixable problems remain.
npx --no-install lint-staged
38 changes: 19 additions & 19 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* Enhanced file based execution support with improved multisite mode compatibility

### Changed
* Updated links to more recent documentation pages
* Updated links to more recent documentation pages

### Fixed
* Fixed multisite capability checks in Plugin class
Expand Down Expand Up @@ -215,10 +215,10 @@

### Changed
* Updated CSS to use latest Sass features.
* Moved theme selector to just above editor preview on settings page (thanks to [brandonjp]). ([#206](https://github.com/codesnippetspro/code-snippets/issues/206))
* Moved theme selector to just above editor preview on settings page (thanks to [brandonjp]). ([#206](https://github.com/codesnippetspro/code-snippets/issues/206))
* `[code_snippet]` shortcodes can now be nested within each other. ([#198](https://github.com/codesnippetspro/code-snippets/issues/198))

### Fixed
### Fixed
* Save buttons above editor did not follow usual validation process in Pro. (PRO) ([#197](https://github.com/codesnippetspro/code-snippets/issues/197))
* Minor inconsistencies in consistent UI elements between Core and Pro.
* Tags input not allowing input. ([#211](https://github.com/codesnippetspro/code-snippets/issues/211))
Expand All @@ -242,13 +242,13 @@
* Action hook `code_snippets/admin/manage` now includes the currently viewed type.

### Fixed
* Memory issue from checking aggregate posts while loading front-end syntax highlighter.
* Memory issue from checking aggregate posts while loading front-end syntax highlighter.
* Translation functions being called too early on upgrade, resulting in localisation loading errors.
* Bug preventing the 'share on network' status of network snippets from correctly updating.
* Incorrect logic controlling when to display 'Save Changes' or 'Save Changes and Activate' buttons.
* Old notices persisting when switching between editing and creating snippets.

## 3.6.5.1 (2024-05-24)
## [3.6.5.1] (2024-05-24)

* Redeployment of [v3.6.5](#365-2024-05-24) to overcome issue with initial build.

Expand Down Expand Up @@ -376,11 +376,11 @@

### Changed
* Better compatibility with modern versions of PHP (7.0+).
* Converted Edit/Add New Snippet page to use React.
* Converted action buttons to asynchronously use REST API endpoints through AJAX.
* Load page components dynamically through React.
* Added action notice queue system.
* Replaced native alert dialog with proper React modal.
* Converted Edit/Add New Snippet page to use React:
- Converted action buttons to asynchronously use REST API endpoints through AJAX.
- Load page components dynamically through React.
- Added action notice queue system
- Replaced native alert dialog with proper React modal.
* Catch snippet execution errors to prevent site from crashing.
* Display recent snippet errors in admin dashboard instead.
* Updated editor block to use new REST API endpoints. (PRO)
Expand Down Expand Up @@ -564,9 +564,9 @@

### Added
* Added translations:
* Spanish by [Ibidem Group](https://www.ibidemgroup.com)
* Urdu by [Samuel Badree](https://mobilemall.pk/)
* Greek by [Toni Bishop from Jrop](https://www.jrop.com/)
- Spanish by [Ibidem Group](https://www.ibidemgroup.com)
- Urdu by [Samuel Badree](https://mobilemall.pk/)
- Greek by [Toni Bishop from Jrop](https://www.jrop.com/)
* Support for `:class` syntax to the code validator.
* PHP8 support to the code linter.
* Color picker feature to the code editor.
Expand Down Expand Up @@ -1307,12 +1307,12 @@

### Changed
* Updated CodeMirror to version 2.33.
* Updated the 'Manage Snippets' page to use the WP_List_Table class.
* Added 'Screen Options' tab to 'Manage Snippets' page.
* Added search capability to 'Manage Snippets' page.
* Added views to easily filter activated, deactivated and recently activated snippets.
* Added ID column to 'Manage Snippets' page.
* Added sortable name and ID column on 'Manage Snippets' page ([#](https://wordpress.org/support/topic/plugin-code-snippets-suggestion-sort-by-snippet-name))
* Updated the 'Manage Snippets' page to use the WP_List_Table class:
- Added 'Screen Options' tab to 'Manage Snippets' page.
- Added search capability to 'Manage Snippets' page.
- Added views to easily filter activated, deactivated and recently activated snippets.
- Added ID column to 'Manage Snippets' page.
- Added sortable name and ID column on 'Manage Snippets' page ([#](https://wordpress.org/support/topic/plugin-code-snippets-suggestion-sort-by-snippet-name))
* Improved API.
* Lengthened snippet name field to 64 characters. ([#](https://wordpress.org/support/topic/plugin-code-snippets-snippet-title-limited-to-36-characters))

Expand Down
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,44 @@ command:
npm run watch
```

## Pre-commit hooks (automatic linting & autofix) 🔧

We use Husky + lint-staged to run linters only on the files being committed. The hook will:

- Run the appropriate autofix for the changed files (PHP, JS/TS, CSS/SCSS).
- Automatically stage any files that were fixed so the fixes are included in the same commit.
- Block the commit only if non-fixable linter errors remain.

Files → actions (configured in this repository):

- `*.php` → `npm run lint:php:fix` (phpcbf)
- `*.{js,ts,jsx,tsx}` → `npm run lint:js:fix` (ESLint --fix)
- `*.{css,scss}` → `npm run lint:styles:fix` (Stylelint --fix)

Setup

1. Install node deps (this will also prepare Husky via the `prepare` script):

```shell
npm install
```

2. If you already have the repo checked out, activate the Git hooks (run once):

```shell
npm run prepare
```

Usage notes

- To bypass hooks in an emergency: `git commit --no-verify` (not recommended).
- To run the same checks locally on staged files: `npx lint-staged`.
- If fixes were applied by the hook they will be included automatically in the commit; the commit is only blocked when
a non-autofixable problem remains.

If you need to change which linters run for a filetype, see `package.json` -> `lint-staged`.


## Managing Composer dependencies

Code Snippets uses the [Imposter plugin](https://github.com/TypistTech/imposter) to namespace-prefix all vendor
Expand Down
4 changes: 0 additions & 4 deletions config/modules/postcss-color-hsl.d.ts

This file was deleted.

208 changes: 208 additions & 0 deletions config/postcss-hsl-legacy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
interface HslMatch {
fn: 'hsl' | 'hsla'
h: string
s: string
l: string
alpha?: string
}

interface DeclarationLike {
value?: string
}

const GRAD_TO_DEG = 0.9
const DEG_PER_TURN = 360
const DEG_PER_PI = 180
const PERCENT_DIVISOR = 100
const ROUNDING_MULTIPLIER = 1000

const hslArgsRegex = new RegExp(
[
String.raw`(?<fn>hsl)a?\s*\(\s*`,
String.raw`(?<hue>\d*\.?\d+(?:deg|grad|rad|turn)?)`,
String.raw`(?:\s+|(?:\s*,\s*))`,
String.raw`(?<s>\d*\.?\d+%)`,
String.raw`(?:\s+|(?:\s*,\s*))`,
String.raw`(?<l>\d*\.?\d+%)`,
String.raw`(?:\s*(?:\/|,)\s*(?<alpha>\d*\.?\d+%?))?`,
String.raw`\s*\)`
].join(''),
'g'
)

const hueWithUnitRegex = /^(?<value>\d*\.?\d+)(?<unit>deg|grad|rad|turn)$/

const convertHueToDeg = (hue: string): string => {
const match = hueWithUnitRegex.exec(hue)
if (!match?.groups) {
return hue
}

const value = Number(match.groups.value)
const unit = match.groups.unit

const degrees =
'deg' === unit
? value
: 'grad' === unit
? value * GRAD_TO_DEG
: 'rad' === unit
? value * DEG_PER_PI / Math.PI
: value * DEG_PER_TURN

return String(Math.round(degrees * ROUNDING_MULTIPLIER) / ROUNDING_MULTIPLIER)
}

const normalizeAlpha = (alpha: string): string => {
if (alpha.includes('%')) {
const value = Number(alpha.slice(0, -1)) / PERCENT_DIVISOR
alpha = String(value)
}

return alpha.replace(/^0\./, '.')
}

const toLegacyHsl = (colorFn: string): HslMatch | null => {
hslArgsRegex.lastIndex = 0
const match = hslArgsRegex.exec(colorFn)
if (!match?.groups) {
return null
}

const alpha = match.groups.alpha

return {
fn: alpha ? 'hsla' : 'hsl',
h: convertHueToDeg(match.groups.hue),
s: match.groups.s,
l: match.groups.l,
alpha: alpha ? normalizeAlpha(alpha) : undefined
}
}

const isIdentChar = (char: string | undefined): boolean => Boolean(char && /[a-zA-Z0-9_-]/.test(char))

const isUnescapedQuote = (value: string, index: number, quote: '"' | "'"): boolean =>
quote === value[index] && '\\' !== value[index - 1]

const findFunctionEnd = (value: string, openParenIndex: number): number | null => {
let depth = 0
let index = openParenIndex

while (index < value.length) {
const char = value[index]

if ('(' === char) {
depth += 1
} else if (')' === char) {
depth -= 1
if (0 === depth) {
return index
}
}

index += 1
}

return null
}

const legacyHslString = (fnText: string): string | null => {
const legacy = toLegacyHsl(fnText)
if (!legacy) {
return null
}

if ('hsl' === legacy.fn) {
return `hsl(${legacy.h}, ${legacy.s}, ${legacy.l})`
}

return `hsla(${legacy.h}, ${legacy.s}, ${legacy.l}, ${legacy.alpha})`
}

const replaceHslAtIndex = (
value: string,
index: number
): { nextIndex: number; text: string } | null => {
const isStart = value.startsWith('hsl', index) || value.startsWith('hsla', index)
if (!isStart || isIdentChar(value[index - 1])) {
return null
}

const name = value.startsWith('hsla', index) ? 'hsla' : 'hsl'
let afterNameIndex = index + name.length

while (afterNameIndex < value.length && /\s/.test(value[afterNameIndex])) {
afterNameIndex += 1
}

if ('(' !== value[afterNameIndex]) {
return null
}

const endIndex = findFunctionEnd(value, afterNameIndex)
if (null === endIndex) {
return { nextIndex: value.length, text: value.slice(index) }
}

const fnText = value.slice(index, endIndex + 1)
return { nextIndex: endIndex + 1, text: legacyHslString(fnText) ?? fnText }
}

const transformHslFunctions = (value: string): string => {
let result = ''
let index = 0

let inSingle = false
let inDouble = false

while (index < value.length) {
const char = value[index]

if (!inDouble && isUnescapedQuote(value, index, "'")) {
inSingle = !inSingle
result += char
index += 1
continue
}

if (!inSingle && isUnescapedQuote(value, index, '"')) {
inDouble = !inDouble
result += char
index += 1
continue
}

if (inSingle || inDouble) {
result += char
index += 1
continue
}

const replacement = replaceHslAtIndex(value, index)
if (!replacement) {
result += char
index += 1
continue
}

result += replacement.text
index = replacement.nextIndex
}

return result
}

const postcssHslLegacy = () => ({
postcssPlugin: 'postcss-hsl-legacy',
Declaration(decl: DeclarationLike) {
if (!decl.value || !decl.value.includes('hsl(') && !decl.value.includes('hsla(')) {
return
}
decl.value = transformHslFunctions(decl.value)
}
})

postcssHslLegacy.postcss = true

export default postcssHslLegacy
2 changes: 1 addition & 1 deletion config/webpack-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import libsass from 'sass'
import cssnano from 'cssnano'
import autoprefixer from 'autoprefixer'
import rgbaCompat from 'postcss-hexrgba'
import hslCompat from 'postcss-color-hsl'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import RemoveEmptyScriptsPlugin from 'webpack-remove-empty-scripts'
import { glob } from 'glob'
import hslCompat from './postcss-hsl-legacy'
import type { Configuration, EntryObject } from 'webpack'
import type { Config as PostCssConfig } from 'postcss-load-config'

Expand Down
Loading