monaco-editor icon indicating copy to clipboard operation
monaco-editor copied to clipboard

[Bug] Color picker / provider broken (not showing)

Open letmaik opened this issue 3 years ago • 1 comments

Reproducible in vscode.dev or in VS Code Desktop?

  • [X] Not reproducible in vscode.dev or VS Code Desktop

Reproducible in the monaco editor playground?

Monaco Editor Playground Code

// NOTE: This is copied directly from the Color Provider example:
// https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-color-provider-example

monaco.languages.register({
	id: 'colorLanguage'
});

monaco.editor.create(document.getElementById('container'), {
	value: 'red\nblue\ngreen',
	language: 'colorLanguage',
	colorDecorators: true
});

monaco.languages.registerColorProvider('colorLanguage', {
	provideColorPresentations: (model, colorInfo) => {
		var color = colorInfo.color;
		var red256 = Math.round(color.red * 255);
		var green256 = Math.round(color.green * 255);
		var blue256 = Math.round(color.blue * 255);
		var label;
		if (color.alpha === 1) {
			label = 'rgb(' + red256 + ', ' + green256 + ', ' + blue256 + ')';
		} else {
			label = 'rgba(' + red256 + ', ' + green256 + ', ' + blue256 + ', ' + color.alpha + ')';
		}

		return [
			{
				label: label
			}
		];
	},

	provideDocumentColors: () => {
		return [
			{
				color: { red: 1, blue: 0, green: 0, alpha: 1 },
				range: {
					startLineNumber: 1,
					startColumn: 0,
					endLineNumber: 1,
					endColumn: 0
				}
			},
			{
				color: { red: 0, blue: 1, green: 0, alpha: 1 },
				range: {
					startLineNumber: 2,
					startColumn: 0,
					endLineNumber: 2,
					endColumn: 0
				}
			},
			{
				color: { red: 0, blue: 0, green: 1, alpha: 1 },
				range: {
					startLineNumber: 3,
					startColumn: 0,
					endLineNumber: 3,
					endColumn: 0
				}
			}
		];
	}
});

Actual Behavior

The color picker is not displayed.

Expected Behavior

The color picker should pop up on hover.

Additional Context

No response

letmaik avatar Jan 06 '22 15:01 letmaik

This broke first in 0.31.0-dev.20211210

The issue is that the ranges are empty.

hediet avatar Jul 28 '22 18:07 hediet

Blame points to https://github.com/microsoft/vscode/compare/15415b6de68f3fcfefcd264ac37cc3c3d54a378b...a1842c8f633237d6d850ada5772359ad32480655

I think it could be https://github.com/microsoft/vscode/commit/5f75c4a41091ac36faea06bf86965d507ce77fa8

alexdima avatar Mar 31 '23 00:03 alexdima

Hey, I was experimenting with this example as well, and through some experiments, I figured out that the missing color indicators are related to the ranges returned as part of the IColorInformation from provideDocumentColors. Seemingly, the start- and end column values are the cause of the error.

In fact, it seems that there has to be at least a difference of 1 between the start- and end column values to display any color indicators, and if the startColumn = 0, then a difference of two (endColumn at least 2) is required.

I am not sure what exactly changed within the Monaco code to cause this, or whether this is intentional, but I hope this pointer can help people with the same issue :)

Here is a modified version of the code that works up to the current latest stable release 0.40.0 (beyond that it's untested):

monaco.languages.register({
	id: "colorLanguage",
});

monaco.editor.create(document.getElementById("container"), {
	value: "red\nblue\ngreen",
	language: "colorLanguage",
	colorDecorators: true,
});

monaco.languages.registerColorProvider("colorLanguage", {
	provideColorPresentations: (model, colorInfo) => {
		var color = colorInfo.color;
		var red256 = Math.round(color.red * 255);
		var green256 = Math.round(color.green * 255);
		var blue256 = Math.round(color.blue * 255);
		var label;
		if (color.alpha === 1) {
			label = "rgb(" + red256 + ", " + green256 + ", " + blue256 + ")";
		} else {
			label =
				"rgba(" +
				red256 +
				", " +
				green256 +
				", " +
				blue256 +
				", " +
				color.alpha +
				")";
		}

		return [
			{
				label: label,
			},
		];
	},

	provideDocumentColors: () => {
		return [
			{
				color: { red: 1, blue: 0, green: 0, alpha: 1 },
				range: {
					startLineNumber: 1,
					startColumn: 1,
					endLineNumber: 1,
					endColumn: 4,
				},
			},
			{
				color: { red: 0, blue: 1, green: 0, alpha: 1 },
				range: {
					startLineNumber: 2,
					startColumn: 1,
					endLineNumber: 2,
					endColumn: 5,
				},
			},
			{
				color: { red: 0, blue: 0, green: 1, alpha: 1 },
				range: {
					startLineNumber: 3,
					startColumn: 1,
					endLineNumber: 3,
					endColumn: 6,
				},
			},
		];
	},
});

I would like to further highlight that in the current configuration the replacement of text when choosing a new color is a bit weird, as color names are converted to rgb(red, green, blue) strings, and change iteratively with every new replacement, and that the placement of color indicators is static to the original string in the editor. But I assume this is due to the simplicity of the example. Just a heads-up for everyone trying to build from here.

mayer-maximilian avatar Jul 20 '23 12:07 mayer-maximilian