Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Prototype of Find in HtmlPreviewPart #22918

Closed
wants to merge 1 commit into from
Closed
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
18 changes: 9 additions & 9 deletions src/vs/editor/contrib/find/browser/findWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ export interface IFindController {
replaceAll(): void;
}

const NLS_FIND_INPUT_LABEL = nls.localize('label.find', "Find");
const NLS_FIND_INPUT_PLACEHOLDER = nls.localize('placeholder.find', "Find");
const NLS_PREVIOUS_MATCH_BTN_LABEL = nls.localize('label.previousMatchButton', "Previous match");
const NLS_NEXT_MATCH_BTN_LABEL = nls.localize('label.nextMatchButton', "Next match");
export const NLS_FIND_INPUT_LABEL = nls.localize('label.find', "Find");
export const NLS_FIND_INPUT_PLACEHOLDER = nls.localize('placeholder.find', "Find");
export const NLS_PREVIOUS_MATCH_BTN_LABEL = nls.localize('label.previousMatchButton', "Previous match");
export const NLS_NEXT_MATCH_BTN_LABEL = nls.localize('label.nextMatchButton', "Next match");
const NLS_TOGGLE_SELECTION_FIND_TITLE = nls.localize('label.toggleSelectionFind', "Find in selection");
const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close");
export const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close");
const NLS_REPLACE_INPUT_LABEL = nls.localize('label.replace', "Replace");
const NLS_REPLACE_INPUT_PLACEHOLDER = nls.localize('placeholder.replace', "Replace");
const NLS_REPLACE_BTN_LABEL = nls.localize('label.replaceButton', "Replace");
const NLS_REPLACE_ALL_BTN_LABEL = nls.localize('label.replaceAllButton', "Replace All");
const NLS_TOGGLE_REPLACE_MODE_BTN_LABEL = nls.localize('label.toggleReplaceButton', "Toggle Replace mode");
const NLS_MATCHES_COUNT_LIMIT_TITLE = nls.localize('title.matchesCountLimit', "Only the first 999 results are highlighted, but all find operations work on the entire text.");
const NLS_MATCHES_LOCATION = nls.localize('label.matchesLocation', "{0} of {1}");
const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");
export const NLS_MATCHES_LOCATION = nls.localize('label.matchesLocation', "{0} of {1}");
export const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");

let MAX_MATCHES_COUNT_WIDTH = 69;
const WIDGET_FIXED_WIDTH = 411 - 69;
Expand Down Expand Up @@ -714,14 +714,14 @@ class SimpleCheckbox extends Widget {
}
}

interface ISimpleButtonOpts {
export interface ISimpleButtonOpts {
label: string;
className: string;
onTrigger: () => void;
onKeyDown: (e: IKeyboardEvent) => void;
}

class SimpleButton extends Widget {
export class SimpleButton extends Widget {

private _opts: ISimpleButtonOpts;
private _domNode: HTMLElement;
Expand Down
93 changes: 89 additions & 4 deletions src/vs/workbench/parts/html/browser/htmlPreviewPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,24 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
import { ITextModelResolverService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
import { Parts, IPartService } from 'vs/workbench/services/part/common/partService';

import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { CommonEditorRegistry, Command } from 'vs/editor/common/editorCommonExtensions';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ContextKeyExpr, IContextKey, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';

import Webview from './webview';
import { SimpleFindWidget } from './simpleFindWidget';
import { FindModelBoundToWebview } from './simpleFindModel';
import { SimpleFindState } from './simpleFindState';

// --- Register Context Keys

/** A context key that is set when an html preview has focus. */
export const KEYBINDING_CONTEXT_HTML_PREVIEW_FOCUS = new RawContextKey<boolean>('htmlPreviewFocus', undefined);
/** A context key that is set when an html preview does not have focus. */
export const KEYBINDING_CONTEXT_HTML_PREVIEW_NOT_FOCUSED: ContextKeyExpr = KEYBINDING_CONTEXT_HTML_PREVIEW_FOCUS.toNegated();


/**
* An implementation of editor for showing HTML content in an IFrame by leveraging the HTML input.
Expand All @@ -36,7 +53,12 @@ export class HtmlPreviewPart extends BaseEditor {
private _openerService: IOpenerService;
private _webview: Webview;
private _webviewDisposables: IDisposable[];
private _findModel: FindModelBoundToWebview;
private _findState: SimpleFindState;
private _container: HTMLDivElement;
// private headerContainer: HTMLElement;
private _findWidget: SimpleFindWidget;
private _htmlPreviewFocusContexKey: IContextKey<boolean>;

private _baseUrl: URI;

Expand All @@ -51,13 +73,17 @@ export class HtmlPreviewPart extends BaseEditor {
@IWorkbenchThemeService protected themeService: IWorkbenchThemeService,
@IOpenerService openerService: IOpenerService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IPartService private partService: IPartService
@IPartService private partService: IPartService,
@IInstantiationService private instantiationService: IInstantiationService,
@IContextKeyService private _contextKeyService: IContextKeyService
) {
super(HtmlPreviewPart.ID, telemetryService, themeService);

this._textModelResolverService = textModelResolverService;
this._openerService = openerService;
this._baseUrl = contextService.toResource('/');

this._htmlPreviewFocusContexKey = KEYBINDING_CONTEXT_HTML_PREVIEW_FOCUS.bindTo(this._contextKeyService);
}

dispose(): void {
Expand All @@ -68,6 +94,10 @@ export class HtmlPreviewPart extends BaseEditor {
this._themeChangeSubscription.dispose();
this._modelChangeSubscription.dispose();

if (this._findWidget) {
this._findWidget.dispose();
}

// dipose model ref
dispose(this._modelRef);
super.dispose();
Expand All @@ -78,18 +108,38 @@ export class HtmlPreviewPart extends BaseEditor {
this._container.style.paddingLeft = '20px';
this._container.style.position = 'absolute';
this._container.style.zIndex = '300';
this._container.style.overflow = 'hidden';
parent.getHTMLElement().appendChild(this._container);
this._findState = this._register(new SimpleFindState());
this._findState.addChangeListener((e) => {
if (e.isRevealed) {
if (!this._findState.isRevealed) {
this.webview.focus();
}
}
});
this._findWidget = this._register(this.instantiationService.createInstance(SimpleFindWidget, this._container, this._findState));
}

private get webview(): Webview {
if (!this._webview) {
this._webview = new Webview(this._container, this.partService.getContainer(Parts.EDITOR_PART));
this._webview = new Webview(this._container, this.partService.getContainer(Parts.EDITOR_PART), this._htmlPreviewFocusContexKey);
this._webview.baseUrl = this._baseUrl && this._baseUrl.toString(true);

this._webviewDisposables = [
this._webview,
this._webview.onDidClickLink(uri => this._openerService.open(uri)),
this._webview.onDidLoadContent(data => this.telemetryService.publicLog('previewHtml', data.stats))
this._webview.onDidLoadContent(data => {
this.telemetryService.publicLog('previewHtml', data.stats);
if (this._findModel) {
this._findModel.dispose();
}
this._findModel = this._register(new FindModelBoundToWebview(this._webview, this._findState));
this._findWidget.findModel = this._findModel;
// Ideally, we would resume the find when re-focusing the editor.
// However, this returns no results as the content hasn't fully loaded yet.
// this._findModel.startFind();
})
];
}
return this._webview;
Expand Down Expand Up @@ -120,7 +170,9 @@ export class HtmlPreviewPart extends BaseEditor {
this.webview.style(this.themeService.getColorTheme());

if (this._hasValidModel()) {
this._modelChangeSubscription = this.model.onDidChangeContent(() => this.webview.contents = this.model.getLinesContent());
this._modelChangeSubscription = this.model.onDidChangeContent(() => {
this.webview.contents = this.model.getLinesContent();
});
this.webview.contents = this.model.getLinesContent();
}
}
Expand All @@ -135,12 +187,21 @@ export class HtmlPreviewPart extends BaseEditor {
// we take the padding we set on create into account
this._container.style.width = `${Math.max(width - 20, 0)}px`;
this._container.style.height = `${height}px`;

if (this._findWidget) {
this._findWidget.layout(width);
}
}

public focus(): void {
this.webview.focus();
}

public activateFind(): void {
this._findState.change({ isRevealed: true });
this._findWidget.activate();
}

public clearInput(): void {
dispose(this._modelRef);
this._modelRef = undefined;
Expand Down Expand Up @@ -192,3 +253,27 @@ export class HtmlPreviewPart extends BaseEditor {
});
}
}

class StartSearchHtmlPreviewPartCommand extends Command {

public runCommand(accessor: ServicesAccessor, args: any): void {
const htmlPreviewPart = this.getHtmlPreviewPart(accessor);
if (htmlPreviewPart) {
htmlPreviewPart.activateFind();
}
}

private getHtmlPreviewPart(accessor: ServicesAccessor): HtmlPreviewPart {
const activeEditor = accessor.get(IWorkbenchEditorService).getActiveEditor();
if (activeEditor instanceof HtmlPreviewPart) {
return activeEditor;
}
return null;
}
}
CommonEditorRegistry.registerEditorCommand(new StartSearchHtmlPreviewPartCommand({
id: 'htmlPreview.action.search',
precondition: ContextKeyExpr.and(KEYBINDING_CONTEXT_HTML_PREVIEW_FOCUS),
kbOpts: { primary: KeyMod.CtrlCmd | KeyCode.KEY_F }
}));

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/vs/workbench/parts/html/browser/images/close-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/vs/workbench/parts/html/browser/images/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/vs/workbench/parts/html/browser/images/next-inverse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/vs/workbench/parts/html/browser/images/next.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/vs/workbench/parts/html/browser/images/previous.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/vs/workbench/parts/html/browser/images/replace-all-inverse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/vs/workbench/parts/html/browser/images/replace-all.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/vs/workbench/parts/html/browser/images/replace-inverse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/vs/workbench/parts/html/browser/images/replace.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading