提交 e0cf2207 编写于 作者: M Martin Aeschlimann

Remove color decorator contribution

上级 11d949aa
......@@ -11,7 +11,6 @@ import 'vs/editor/browser/widget/diffEditorWidget';
import 'vs/editor/contrib/accessibility/browser/accessibility';
import 'vs/editor/contrib/clipboard/browser/clipboard';
import 'vs/editor/contrib/codelens/browser/codelens';
import 'vs/editor/contrib/color/browser/color';
import 'vs/editor/contrib/comment/common/comment';
import 'vs/editor/contrib/contextmenu/browser/contextmenu';
import 'vs/editor/contrib/diffNavigator/common/diffNavigator';
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-editor .inline-color-decoration:before {
margin: 0.1em 0.2em 0 0.2em;
content:" ";
display:inline-block;
height:0.8em;
width:0.8em;
line-height:1em;
border:0.1em solid #000;
}
.monaco-editor.vs-dark .inline-color-decoration:before {
border-color: #eee;
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./color';
import {RunOnceScheduler} from 'vs/base/common/async';
import {onUnexpectedError} from 'vs/base/common/errors';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import * as strings from 'vs/base/common/strings';
import {TPromise} from 'vs/base/common/winjs.base';
import * as dom from 'vs/base/browser/dom';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions';
import {Range} from 'vs/editor/common/core/range';
class ColorDecoration {
public static createRenderingDecoration(range:editorCommon.IRange, inlineClassName:string): editorCommon.IModelDeltaDecoration {
return {
range: {
startLineNumber: range.startLineNumber,
startColumn: range.startColumn,
endLineNumber: range.startLineNumber,
endColumn: range.startColumn + 1
},
options: {
inlineClassName: 'inline-color-decoration ' + inlineClassName,
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges
}
};
}
public static createTrackingDecoration(range:editorCommon.IRange): editorCommon.IModelDeltaDecoration {
return {
range: range,
options: {
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges
}
};
}
public trackingDecorationId:string;
public renderingDecorationId:string;
constructor(renderingDecorationId:string, trackingDecorationId:string) {
this.renderingDecorationId = renderingDecorationId;
this.trackingDecorationId = trackingDecorationId;
}
public getColorValue(model:editorCommon.IModel): string {
var range = model.getDecorationRange(this.trackingDecorationId);
if (range) {
return model.getValueInRange(range);
}
return '';
}
}
interface IFunction {
(): void;
}
export class ColorContribution implements editorCommon.IEditorContribution {
public static ID = 'css.editor.colorContribution';
private static INSTANCE_COUNT = 0;
private _instanceCount:number;
private _editor:editorCommon.ICommonCodeEditor;
private _contentChangedScheduler:RunOnceScheduler;
private _decorationsChangedScheduler:RunOnceScheduler;
private _callOnDispose:IDisposable[];
private _callOnModelChange:IDisposable[];
private _currentFindColorDeclarationsPromise:TPromise<{range:editorCommon.IRange; value:string; }[]>;
private _currentDecorations:ColorDecoration[];
private _currentDynamicColors:string[];
private _style:HTMLStyleElement;
constructor(editor:editorCommon.ICommonCodeEditor) {
this._instanceCount = (++ColorContribution.INSTANCE_COUNT);
this._editor = editor;
this._callOnDispose = [];
this._callOnModelChange = [];
this._currentDecorations = [];
this._currentDynamicColors = [];
this._contentChangedScheduler = new RunOnceScheduler(null, 250);
this._decorationsChangedScheduler = new RunOnceScheduler(() => this.onDecorationsChanged(), 250);
this._currentFindColorDeclarationsPromise = null;
this._callOnDispose.push(this._contentChangedScheduler);
this._callOnDispose.push(this._decorationsChangedScheduler);
this._callOnDispose.push(this._editor.onDidChangeModel(() => this.onModelChange()));
this._callOnDispose.push(this._editor.onDidChangeModelMode(() => this.onModelChange()));
this._callOnDispose.push(this._editor.onDidChangeModelModeSupport((e: editorCommon.IModeSupportChangedEvent) => {
this.onModelChange();
}));
this._style = dom.createStyleSheet();
this.onModelChange();
}
public dispose(): void {
if (this._currentDecorations.length > 0) {
this._editor.changeDecorations((changeAccessor:editorCommon.IModelDecorationsChangeAccessor) => {
let oldDecorations: string[] = [];
for (let i = 0, len = this._currentDecorations.length; i < len; i++) {
oldDecorations.push(this._currentDecorations[i].renderingDecorationId);
oldDecorations.push(this._currentDecorations[i].trackingDecorationId);
}
changeAccessor.deltaDecorations(oldDecorations, []);
this._currentDecorations = null;
});
}
this._style.parentNode.removeChild(this._style);
this._style = null;
this._callOnDispose = dispose(this._callOnDispose);
}
public getId():string {
return ColorContribution.ID;
}
private onModelChange(): void {
this._callOnModelChange = dispose(this._callOnModelChange);
var model = <editorCommon.IModel> this._editor.getModel();
if(!model) {
return;
}
var rawMode = model.getMode();
if(typeof rawMode['findColorDeclarations'] !== 'function') {
return;
}
this._contentChangedScheduler.setRunner(() => {
if (this._currentFindColorDeclarationsPromise) {
this._currentFindColorDeclarationsPromise.cancel();
}
this._currentFindColorDeclarationsPromise = rawMode['findColorDeclarations'](model.uri);
var myModelVersion = this._editor.getModel().getVersionId();
this._currentFindColorDeclarationsPromise.then((result) => {
if (myModelVersion !== this._editor.getModel().getVersionId()) {
return;
}
this.renderAndTrackColors(result);
}, (error) => {
onUnexpectedError(error);
});
});
this._contentChangedScheduler.schedule();
this._callOnModelChange.push({
dispose: () => {
this._contentChangedScheduler.cancel();
this._decorationsChangedScheduler.cancel();
}
});
this._callOnModelChange.push({
dispose: () => {
if (this._currentFindColorDeclarationsPromise) {
this._currentFindColorDeclarationsPromise.cancel();
}
this._currentFindColorDeclarationsPromise = null;
}
});
this._callOnModelChange.push(this._editor.onDidChangeModelContent((event) => this._contentChangedScheduler.schedule()));
this._callOnModelChange.push(model.onDidChangeDecorations((event) => this._decorationsChangedScheduler.schedule()));
}
private renderAndTrackColors(colors:{range:editorCommon.IRange; value:string; }[]): void {
// Reduce to a maximum of 500 colors
colors = colors.slice(0, 500);
this._editor.changeDecorations((changeAccessor:editorCommon.IModelDecorationsChangeAccessor) => {
let oldDecorations: string[] = [];
for (let i = 0, len = this._currentDecorations.length; i < len; i++) {
oldDecorations.push(this._currentDecorations[i].renderingDecorationId);
oldDecorations.push(this._currentDecorations[i].trackingDecorationId);
}
let newDecorations: editorCommon.IModelDeltaDecoration[] = [];
for (let i = 0, len = colors.length; i < len; i++) {
newDecorations.push(ColorDecoration.createRenderingDecoration(colors[i].range, this.getCSSRuleName(i)));
newDecorations.push(ColorDecoration.createTrackingDecoration(colors[i].range));
}
let decorations = changeAccessor.deltaDecorations(oldDecorations, newDecorations);
this._currentDecorations = [];
for (let i = 0, len = colors.length; i < len; i++) {
this._currentDecorations.push(new ColorDecoration(decorations[2*i], decorations[2*i+1]));
}
});
this.onDecorationsChanged();
}
private onDecorationsChanged(): void {
var model = this._editor.getModel(),
i:number,
len:number,
range:Range,
renderingRange:Range,
desiredRenderingRange:editorCommon.IRange,
decoration: ColorDecoration,
desiredColors: string[] = [];
this._editor.changeDecorations((changeAccessor:editorCommon.IModelDecorationsChangeAccessor) => {
for (i = 0, len = this._currentDecorations.length; i < len; i++) {
decoration = this._currentDecorations[i];
range = model.getDecorationRange(decoration.trackingDecorationId);
if (range && !range.isEmpty()) {
// Collect color for this decoration
desiredColors[i] = model.getValueInRange(range).replace(/[^%#a-z0-9.,()]/gi, '');
// Prevent rendering decorations from growing too much
renderingRange = model.getDecorationRange(decoration.renderingDecorationId);
desiredRenderingRange = model.validateRange({
startLineNumber: range.startLineNumber,
startColumn: range.startColumn,
endLineNumber: range.startLineNumber,
endColumn: range.startColumn + 1
});
if (!renderingRange || !renderingRange.equalsRange(desiredRenderingRange)) {
changeAccessor.changeDecoration(decoration.renderingDecorationId, desiredRenderingRange);
}
} else {
desiredColors[i] = '';
}
}
this.ensureColors(desiredColors);
});
}
private getCSSRuleName(index:number): string {
if (index < 0) {
return '.monaco-css-dynamic-' + this._instanceCount + '-';
}
return '.monaco-css-dynamic-' + this._instanceCount + '-' + index + ':before';
}
private _changeCost(desiredColors:string[]): number {
if (this._currentDynamicColors.length !== desiredColors.length) {
return Number.MAX_VALUE;
}
var modifiedCnt = 0;
for (var i = 0; i < desiredColors.length; i++) {
if (desiredColors[i] !== this._currentDynamicColors[i]) {
modifiedCnt++;
}
}
return modifiedCnt;
}
private ensureColors(desiredColors:string[]): void {
var i:number,
changeCost = this._changeCost(desiredColors);
if (changeCost === 0) {
// Nothing to change
return;
}
if (changeCost < 10) {
// Simply modify up to 10 rules (lengths will match for sure)
for (i = 0; i < desiredColors.length; i++) {
if (desiredColors[i] !== this._currentDynamicColors[i]) {
var rule = dom.getCSSRule(this.getCSSRuleName(i), this._style);
if (rule) {
rule.style.backgroundColor = desiredColors[i];
}
}
}
} else {
// .innerHTML is the friend here
var result:string[] = [];
for (i = 0; i < desiredColors.length; i++) {
result.push(this.getCSSRuleName(i));
result.push('{');
result.push(this.getCSSText(desiredColors[i]));
result.push('}');
}
this._style.innerHTML = result.join('');
}
this._currentDynamicColors = desiredColors;
}
private getCSSText(color:string): string {
// Variants:
return strings.format('background-color:{0};', color);
}
}
CommonEditorRegistry.registerEditorContribution(ColorContribution);
......@@ -512,8 +512,4 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode impl
return this._worker((w) => w.provideCompletionItems(resource, position));
}
static $findColorDeclarations = OneWorkerAttr(HTMLMode, HTMLMode.prototype.findColorDeclarations);
public findColorDeclarations(resource:URI):winjs.TPromise<{range:editorCommon.IRange; value:string; }[]> {
return this._worker((w) => w.findColorDeclarations(resource));
}
}
......@@ -168,24 +168,6 @@ export class HTMLWorker {
});
}
public findColorDeclarations(resource:URI):winjs.TPromise<{range:editorCommon.IRange; value:string; }[]> {
return this._delegateToAllModes(resource, (models) => {
let allPromises: winjs.TPromise<IColorRange[]>[] = [];
allPromises = models
.filter((model) => (typeof model.getMode()['findColorDeclarations'] === 'function'))
.map((model) => model.getMode()['findColorDeclarations'](model.uri));
return winjs.TPromise.join(allPromises).then((results:IColorRange[][]) => {
let result:IColorRange[] = [];
results.forEach((oneResult) => result = result.concat(oneResult));
return result;
});
});
}
private findMatchingOpenTag(scanner: IHTMLScanner) : string {
let closedTags : { [name:string]: number } = {};
let tagClosed = false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册