Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@typescript-eslint/eslint-plugin": "^8.44.1",
"@typescript-eslint/parser": "^8.44.1",
"@types/node": "^24.5.2",
"chalk": "4.1.2",
"cross-env": "^10.0.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.1.8",
Expand All @@ -98,8 +99,7 @@
"htmlparser2": "^9.1.0",
"is-url": "^1.2.4",
"pretty-bytes": "^6.1.1",
"prismjs": "^1.30.0",
"validate-color": "https://gitpkg.now.sh/dreamyguy/validate-color/src/validate-color"
"prismjs": "^1.30.0"
},
"packageManager": "yarn@1.22.22"
}
2 changes: 1 addition & 1 deletion resources/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Next-gen Clipboard manager for Gnome Shell\n\nYou need libgda and gsound for this extension to work.\n\nFedora: sudo dnf install libgda libgda-sqlite\nArch Linux: sudo pacman -S libgda (libgda6 for gnome-43 or later)\nUbuntu/Debian: sudo apt install gir1.2-gda-5.0 gir1.2-gsound-1.0\nopenSUSE: sudo zypper install libgda-6_0-sqlite typelib-1_0-Gda-6_0 typelib-1_0-GSound-1_0",
"uuid": "pano@elhan.io",
"gettext-domain": "pano@elhan.io",
"version": 1004,
"version": 1005,
"donations": {
"github": "oae"
},
Expand Down
1 change: 0 additions & 1 deletion rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ const thirdParty = [
'hex-color-converter',
'is-url',
'pretty-bytes',
'validate-color',
'highlight.js/lib/core',
'highlight.js/lib/languages/bash',
'highlight.js/lib/languages/c',
Expand Down
6 changes: 5 additions & 1 deletion src/utils/panoItemFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ import {
playAudio,
} from '@pano/utils/shell';
import { notify } from '@pano/utils/ui';
import {
validateHTMLColorHex,
validateHTMLColorName,
validateHTMLColorRgb,
} from '@pano/utils/validators/colorValidator';
import convert from 'hex-color-converter';
import hljs from 'highlight.js/lib/core';
import bash from 'highlight.js/lib/languages/bash';
Expand Down Expand Up @@ -54,7 +59,6 @@ import typescript from 'highlight.js/lib/languages/typescript';
import yaml from 'highlight.js/lib/languages/yaml';
import isUrl from 'is-url';
import prettyBytes from 'pretty-bytes';
import { validateHTMLColorHex, validateHTMLColorName, validateHTMLColorRgb } from 'validate-color';

hljs.registerLanguage('python', python);
hljs.registerLanguage('markdown', markdown);
Expand Down
111 changes: 111 additions & 0 deletions src/utils/validators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Color Validators

This module provides color validation utilities as a replacement for the `validate-color` npm package.

## Why This Replacement?

The original `validate-color` package (v2.2.4) uses a webpack-bundled CommonJS format that caused compatibility issues with Rollup's ES module bundling:

- **Error**: `SyntaxError: ambiguous indirect export: validateHTMLColorHex`
- **Root Cause**: The package's webpack bundle made it difficult for Rollup to properly extract named exports
- **Solution**: Implement the validation logic locally using simple regex patterns

## Benefits

✅ **No bundling issues** - Native ES modules work perfectly with Rollup
✅ **Smaller bundle size** - Only includes what we need
✅ **Easier to maintain** - Simple, readable regex patterns
✅ **No external dependencies** - One less package to worry about
✅ **Better performance** - Direct regex checks without library overhead

## API

### `validateHTMLColorHex(color: string): boolean`

Validates hexadecimal color format.

**Supported formats:**
- `#RGB` (e.g., `#f00`)
- `#RRGGBB` (e.g., `#ff0000`)
- `#RGBA` (e.g., `#ff0000ff`)
- `#RRGGBBAA` (e.g., `#ff0000ff`)

**Examples:**
```typescript
validateHTMLColorHex('#ff0000') // true
validateHTMLColorHex('#f00') // true
validateHTMLColorHex('#ff0000ff') // true
validateHTMLColorHex('red') // false
validateHTMLColorHex('rgb(255,0,0)') // false
```

### `validateHTMLColorRgb(color: string): boolean`

Validates RGB/RGBA color format.

**Supported formats:**
- `rgb(r, g, b)` - with or without spaces
- `rgba(r, g, b, a)` - with or without spaces
- Supports percentages (e.g., `rgb(100%, 0%, 0%)`)
- Supports modern CSS syntax with `/` separator

**Examples:**
```typescript
validateHTMLColorRgb('rgb(255, 0, 0)') // true
validateHTMLColorRgb('rgba(255, 0, 0, 1)') // true
validateHTMLColorRgb('rgb(100%, 0%, 0%)') // true
validateHTMLColorRgb('rgba(255 0 0 / 0.5)') // true
validateHTMLColorRgb('#ff0000') // false
```

### `validateHTMLColorName(color: string): boolean`

Validates HTML color names (case-insensitive).

**Supports:**
- All 147 standard HTML/CSS color names (e.g., `red`, `blue`, `cornflowerblue`)
- CSS special keywords: `transparent`, `currentcolor`, `inherit`

**Examples:**
```typescript
validateHTMLColorName('red') // true
validateHTMLColorName('CornflowerBlue') // true
validateHTMLColorName('transparent') // true
validateHTMLColorName('#ff0000') // false
validateHTMLColorName('notacolor') // false
```

## Usage in Pano

These validators are used in `panoItemFactory.ts` to detect when copied text is a color value:

1. When text is copied to clipboard, Pano checks if it's a valid color
2. If valid, it creates a `COLOR` type item instead of a `TEXT` item
3. The color item gets special visual treatment (color swatch preview)
4. Notifications display the actual color when a color is copied

## Limitations

This implementation focuses on the most common color formats used in web development:
- ✅ Hex colors (`#RGB`, `#RRGGBB`, `#RGBA`, `#RRGGBBAA`)
- ✅ RGB/RGBA colors
- ✅ Named colors (147 standard HTML/CSS names)
- ❌ HSL/HSLA colors (not currently needed)
- ❌ HWB colors (not currently needed)
- ❌ LAB/LCH colors (not currently needed)

If additional color formats are needed in the future, they can be easily added following the same pattern.

## Migration Notes

**Before (using validate-color package):**
```typescript
import { validateHTMLColorHex, validateHTMLColorName, validateHTMLColorRgb } from 'validate-color';
```

**After (using local validators):**
```typescript
import { validateHTMLColorHex, validateHTMLColorName, validateHTMLColorRgb } from '@pano/utils/validators/colorValidator';
```

The API is identical, so no code changes were needed beyond the import statement.
188 changes: 188 additions & 0 deletions src/utils/validators/colorValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/**
* Color validation utilities
* Replacement for the validate-color package to avoid bundling issues
*/

/**
* Validates hexadecimal color format
* Supports: #RGB, #RRGGBB, #RGBA, #RRGGBBAA
*/
export const validateHTMLColorHex = (color: string): boolean => {
if (!color || typeof color !== 'string') return false;
return /^#([0-9A-Fa-f]{3}){1,2}$|^#([0-9A-Fa-f]{4}){1,2}$/i.test(color);
};

/**
* Validates RGB/RGBA color format
* Supports: rgb(r, g, b), rgba(r, g, b, a)
*/
export const validateHTMLColorRgb = (color: string): boolean => {
if (!color || typeof color !== 'string') return false;
return /^rgba?\(\s*\d+%?\s*,?\s*\d+%?\s*,?\s*\d+%?\s*(,?\s*\/?\s*[\d.]+%?\s*)?\)$/i.test(color);
};

/**
* Standard HTML color names (CSS Color Module Level 3)
*/
const HTML_COLOR_NAMES = new Set([
'aliceblue',
'antiquewhite',
'aqua',
'aquamarine',
'azure',
'beige',
'bisque',
'black',
'blanchedalmond',
'blue',
'blueviolet',
'brown',
'burlywood',
'cadetblue',
'chartreuse',
'chocolate',
'coral',
'cornflowerblue',
'cornsilk',
'crimson',
'cyan',
'darkblue',
'darkcyan',
'darkgoldenrod',
'darkgray',
'darkgrey',
'darkgreen',
'darkkhaki',
'darkmagenta',
'darkolivegreen',
'darkorange',
'darkorchid',
'darkred',
'darksalmon',
'darkseagreen',
'darkslateblue',
'darkslategray',
'darkslategrey',
'darkturquoise',
'darkviolet',
'deeppink',
'deepskyblue',
'dimgray',
'dimgrey',
'dodgerblue',
'firebrick',
'floralwhite',
'forestgreen',
'fuchsia',
'gainsboro',
'ghostwhite',
'gold',
'goldenrod',
'gray',
'grey',
'green',
'greenyellow',
'honeydew',
'hotpink',
'indianred',
'indigo',
'ivory',
'khaki',
'lavender',
'lavenderblush',
'lawngreen',
'lemonchiffon',
'lightblue',
'lightcoral',
'lightcyan',
'lightgoldenrodyellow',
'lightgray',
'lightgrey',
'lightgreen',
'lightpink',
'lightsalmon',
'lightseagreen',
'lightskyblue',
'lightslategray',
'lightslategrey',
'lightsteelblue',
'lightyellow',
'lime',
'limegreen',
'linen',
'magenta',
'maroon',
'mediumaquamarine',
'mediumblue',
'mediumorchid',
'mediumpurple',
'mediumseagreen',
'mediumslateblue',
'mediumspringgreen',
'mediumturquoise',
'mediumvioletred',
'midnightblue',
'mintcream',
'mistyrose',
'moccasin',
'navajowhite',
'navy',
'oldlace',
'olive',
'olivedrab',
'orange',
'orangered',
'orchid',
'palegoldenrod',
'palegreen',
'paleturquoise',
'palevioletred',
'papayawhip',
'peachpuff',
'peru',
'pink',
'plum',
'powderblue',
'purple',
'rebeccapurple',
'red',
'rosybrown',
'royalblue',
'saddlebrown',
'salmon',
'sandybrown',
'seagreen',
'seashell',
'sienna',
'silver',
'skyblue',
'slateblue',
'slategray',
'slategrey',
'snow',
'springgreen',
'steelblue',
'tan',
'teal',
'thistle',
'tomato',
'turquoise',
'violet',
'wheat',
'white',
'whitesmoke',
'yellow',
'yellowgreen',
// CSS special keywords
'transparent',
'currentcolor',
'inherit',
]);

/**
* Validates HTML color names
*/
export const validateHTMLColorName = (color: string): boolean => {
if (!color || typeof color !== 'string') return false;
return HTML_COLOR_NAMES.has(color.toLowerCase());
};
4 changes: 0 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4026,10 +4026,6 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==

"validate-color@https://gitpkg.now.sh/dreamyguy/validate-color/src/validate-color":
version "0.0.0"
resolved "https://gitpkg.now.sh/dreamyguy/validate-color/src/validate-color#9e890cb48fed5e22027a67d98750232c4ce780f6"

vinyl@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-3.0.0.tgz#11e14732bf56e2faa98ffde5157fe6c13259ff30"
Expand Down