From 19dea4730a126a3c06509748ae26c8e7856c505f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 4 Sep 2018 08:07:57 +0200 Subject: [PATCH] :tada: debt - remove builder :tada: --- src/vs/base/browser/builder.css | 8 - src/vs/base/browser/builder.ts | 1428 ----------------- src/vs/base/browser/dom.ts | 1 - src/vs/base/test/browser/builder.test.ts | 1323 --------------- src/vs/workbench/browser/composite.ts | 2 +- .../parts/debug/browser/debugActionsWidget.ts | 2 + test/smoke/src/areas/debug/debug.ts | 2 +- 7 files changed, 4 insertions(+), 2762 deletions(-) delete mode 100644 src/vs/base/browser/builder.css delete mode 100644 src/vs/base/browser/builder.ts delete mode 100644 src/vs/base/test/browser/builder.test.ts diff --git a/src/vs/base/browser/builder.css b/src/vs/base/browser/builder.css deleted file mode 100644 index e440d5cf994..00000000000 --- a/src/vs/base/browser/builder.css +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.monaco-builder-hidden { - display: none !important; -} \ No newline at end of file diff --git a/src/vs/base/browser/builder.ts b/src/vs/base/browser/builder.ts deleted file mode 100644 index 6abfaece89d..00000000000 --- a/src/vs/base/browser/builder.ts +++ /dev/null @@ -1,1428 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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!./builder'; -import * as types from 'vs/base/common/types'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; -import * as strings from 'vs/base/common/strings'; -import * as assert from 'vs/base/common/assert'; -import * as DOM from 'vs/base/browser/dom'; - -/** - * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - * - * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - */ -export interface QuickBuilder { - (): Builder; - (builders: Builder[]): Builder; - (element: HTMLElement): Builder; - (element: HTMLElement[]): Builder; - (window: Window): Builder; - (htmlOrQuerySyntax: string): Builder; // Or, MultiBuilder - (name: string, args?: any, fn?: (builder: Builder) => any): Builder; - (one: string, two: string, three: string): Builder; - (builder: Builder): Builder; -} - -// --- Implementation starts here - -let MS_DATA_KEY = '_msDataKey'; -let DATA_BINDING_ID = '__$binding'; -let LISTENER_BINDING_ID = '__$listeners'; -let VISIBILITY_BINDING_ID = '__$visibility'; - -function data(element: any): any { - if (!element[MS_DATA_KEY]) { - element[MS_DATA_KEY] = {}; - } - - return element[MS_DATA_KEY]; -} - -function hasData(element: any): boolean { - return !!element[MS_DATA_KEY]; -} - -/** - * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - * - * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - */ -export class Builder implements IDisposable { - private currentElement: HTMLElement; - private offdom: boolean; - private container: HTMLElement; - private createdElements: HTMLElement[]; - private toDispose: { [type: string]: IDisposable[]; }; - private captureToDispose: { [type: string]: IDisposable[]; }; - - constructor(element?: HTMLElement, offdom?: boolean) { - this.offdom = offdom; - - this.container = element; - - this.currentElement = element; - this.createdElements = []; - - this.toDispose = {}; - this.captureToDispose = {}; - } - - /** - * Returns a new builder that lets the current HTML Element of this builder be the container - * for future additions on the builder. - */ - asContainer(): Builder { - return withBuilder(this, this.offdom); - } - - /** - * Clones the builder providing the same properties as this one. - */ - clone(): Builder { - let builder = new Builder(this.container, this.offdom); - builder.currentElement = this.currentElement; - builder.createdElements = this.createdElements; - builder.captureToDispose = this.captureToDispose; - builder.toDispose = this.toDispose; - - return builder; - } - - /** - * Inserts all created elements of this builder as children to the given container. If the - * container is not provided, the element that was passed into the Builder at construction - * time is being used. The caller can provide the index of insertion, or omit it to append - * at the end. - * This method is a no-op unless the builder was created with the offdom option to be true. - */ - build(container?: Builder, index?: number): Builder; - build(container?: HTMLElement, index?: number): Builder; - build(container?: any, index?: number): Builder { - assert.ok(this.offdom, 'This builder was not created off-dom, so build() can not be called.'); - - // Use builders own container if present - if (!container) { - container = this.container; - } - - // Handle case of passed in Builder - else if (container instanceof Builder) { - container = (container).getHTMLElement(); - } - - assert.ok(container, 'Builder can only be build() with a container provided.'); - assert.ok(DOM.isHTMLElement(container), 'The container must either be a HTMLElement or a Builder.'); - - let htmlContainer = container; - - // Append - let i: number, len: number; - let childNodes = htmlContainer.childNodes; - if (types.isNumber(index) && index < childNodes.length) { - for (i = 0, len = this.createdElements.length; i < len; i++) { - htmlContainer.insertBefore(this.createdElements[i], childNodes[index++]); - } - } else { - for (i = 0, len = this.createdElements.length; i < len; i++) { - htmlContainer.appendChild(this.createdElements[i]); - } - } - - return this; - } - - /** - * Similar to #build, but does not require that the builder is off DOM, and instead - * attached the current element. If the current element has a parent, it will be - * detached from that parent. - */ - appendTo(container?: Builder, index?: number): Builder; - appendTo(container?: HTMLElement, index?: number): Builder; - appendTo(container?: any, index?: number): Builder { - - // Use builders own container if present - if (!container) { - container = this.container; - } - - // Handle case of passed in Builder - else if (container instanceof Builder) { - container = (container).getHTMLElement(); - } - - assert.ok(container, 'Builder can only be build() with a container provided.'); - assert.ok(DOM.isHTMLElement(container), 'The container must either be a HTMLElement or a Builder.'); - - let htmlContainer = container; - - // Remove node from parent, if needed - if (this.currentElement.parentNode) { - this.currentElement.parentNode.removeChild(this.currentElement); - } - - let childNodes = htmlContainer.childNodes; - if (types.isNumber(index) && index < childNodes.length) { - htmlContainer.insertBefore(this.currentElement, childNodes[index]); - } else { - htmlContainer.appendChild(this.currentElement); - } - - return this; - } - - /** - * Performs the exact reverse operation of #append. - * Doing `a.append(b)` is the same as doing `b.appendTo(a)`, with the difference - * of the return value being the builder which called the operation (`a` in the - * first case; `b` in the second case). - */ - append(child: HTMLElement, index?: number): Builder; - append(child: Builder, index?: number): Builder; - append(child: any, index?: number): Builder { - assert.ok(child, 'Need a child to append'); - - if (DOM.isHTMLElement(child)) { - child = _withElement(child); - } - - assert.ok(child instanceof Builder || child instanceof MultiBuilder, 'Need a child to append'); - - (child).appendTo(this, index); - - return this; - } - - /** - * Removes the current element of this builder from its parent node. - */ - offDOM(): Builder { - if (this.currentElement.parentNode) { - this.currentElement.parentNode.removeChild(this.currentElement); - } - - return this; - } - - /** - * Returns the HTML Element the builder is currently active on. - */ - getHTMLElement(): HTMLElement { - return this.currentElement; - } - - /** - * Returns the HTML Element the builder is building in. - */ - getContainer(): HTMLElement { - return this.container; - } - - // HTML Elements - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - div(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('div', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - p(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('p', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - ul(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('ul', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - li(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('li', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - span(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('span', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - img(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('img', attributes, fn); - } - - /** - * Creates a new element of this kind as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - a(attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement('a', attributes, fn); - } - - /** - * Creates a new element of given tag name as child of the current element or parent. - * Accepts an object literal as first parameter that can be used to describe the - * attributes of the element. - * Accepts a function as second parameter that can be used to create child elements - * of the element. The function will be called with a new builder created with the - * provided element. - */ - element(name: string, attributes?: any, fn?: (builder: Builder) => void): Builder { - return this.doElement(name, attributes, fn); - } - - private doElement(name: string, attributesOrFn?: any, fn?: (builder: Builder) => void): Builder { - - // Create Element - let element = document.createElement(name); - this.currentElement = element; - - // Off-DOM: Remember in array of created elements - if (this.offdom) { - this.createdElements.push(element); - } - - // Object (apply properties as attributes to HTML element) - if (types.isObject(attributesOrFn)) { - this.attr(attributesOrFn); - } - - // Support second argument being function - if (types.isFunction(attributesOrFn)) { - fn = attributesOrFn; - } - - // Apply Functions (Elements created in Functions will be added as child to current element) - if (types.isFunction(fn)) { - let builder = new Builder(element); - fn.call(builder, builder); // Set both 'this' and the first parameter to the new builder - } - - // Add to parent - if (!this.offdom) { - this.container.appendChild(element); - } - - return this; - } - - /** - * Calls focus() on the current HTML element; - */ - domFocus(): Builder { - this.currentElement.focus(); - - return this; - } - - /** - * Calls blur() on the current HTML element; - */ - domBlur(): Builder { - this.currentElement.blur(); - - return this; - } - - /** - * Registers listener on event types on the current element. - */ - on(type: string, fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder; - on(typeArray: string[], fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder; - on(arg1: any, fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder { - - // Event Type Array - if (types.isArray(arg1)) { - arg1.forEach((type: string) => { - this.on(type, fn, listenerToDisposeContainer, useCapture); - }); - } - - // Single Event Type - else { - let type = arg1; - - // Add Listener - let unbind: IDisposable = DOM.addDisposableListener(this.currentElement, type, (e) => { - fn(e, this, unbind); // Pass in Builder as Second Argument - }, useCapture || false); - - // Remember for off() use - if (useCapture) { - if (!this.captureToDispose[type]) { - this.captureToDispose[type] = []; - } - this.captureToDispose[type].push(unbind); - } else { - if (!this.toDispose[type]) { - this.toDispose[type] = []; - } - this.toDispose[type].push(unbind); - } - - // Bind to Element - let listenerBinding: IDisposable[] = this.getProperty(LISTENER_BINDING_ID, []); - listenerBinding.push(unbind); - this.setProperty(LISTENER_BINDING_ID, listenerBinding); - - // Add to Array if passed in - if (listenerToDisposeContainer && types.isArray(listenerToDisposeContainer)) { - listenerToDisposeContainer.push(unbind); - } - } - - return this; - } - - /** - * Removes all listeners from all elements created by the builder for the given event type. - */ - off(type: string, useCapture?: boolean): Builder; - off(typeArray: string[], useCapture?: boolean): Builder; - off(arg1: any, useCapture?: boolean): Builder { - - // Event Type Array - if (types.isArray(arg1)) { - arg1.forEach((type: string) => { - this.off(type); - }); - } - - // Single Event Type - else { - let type = arg1; - if (useCapture) { - if (this.captureToDispose[type]) { - this.captureToDispose[type] = dispose(this.captureToDispose[type]); - } - } else { - if (this.toDispose[type]) { - this.toDispose[type] = dispose(this.toDispose[type]); - } - } - } - - return this; - } - - /** - * Registers listener on event types on the current element and removes - * them after first invocation. - */ - once(type: string, fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder; - once(typesArray: string[], fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder; - once(arg1: any, fn: (e: E, builder: Builder, unbind: IDisposable) => void, listenerToDisposeContainer?: IDisposable[], useCapture?: boolean): Builder { - - // Event Type Array - if (types.isArray(arg1)) { - arg1.forEach((type: string) => { - this.once(type, fn); - }); - } - - // Single Event Type - else { - let type = arg1; - - // Add Listener - let unbind: IDisposable = DOM.addDisposableListener(this.currentElement, type, (e) => { - fn(e, this, unbind); // Pass in Builder as Second Argument - unbind.dispose(); - }, useCapture || false); - - // Add to Array if passed in - if (listenerToDisposeContainer && types.isArray(listenerToDisposeContainer)) { - listenerToDisposeContainer.push(unbind); - } - } - - return this; - } - - /** - * This method has different characteristics based on the parameter provided: - * a) a single string passed in as argument will return the attribute value using the - * string as key from the current element of the builder. - * b) two strings passed in will set the value of an attribute identified by the first - * parameter to match the second parameter - * c) an object literal passed in will apply the properties of the literal as attributes - * to the current element of the builder. - */ - attr(name: string): string; - attr(name: string, value: string): Builder; - attr(name: string, value: boolean): Builder; - attr(name: string, value: number): Builder; - attr(attributes: any): Builder; - attr(firstP: any, secondP?: any): any { - - // Apply Object Literal to Attributes of Element - if (types.isObject(firstP)) { - for (let prop in firstP) { - if (firstP.hasOwnProperty(prop)) { - let value = firstP[prop]; - this.doSetAttr(prop, value); - } - } - - return this; - } - - // Get Attribute Value - if (types.isString(firstP) && !types.isString(secondP)) { - return this.currentElement.getAttribute(firstP); - } - - // Set Attribute Value - if (types.isString(firstP)) { - if (!types.isString(secondP)) { - secondP = String(secondP); - } - this.doSetAttr(firstP, secondP); - } - - return this; - } - - private doSetAttr(prop: string, value: any): void { - if (prop === 'class') { - prop = 'addClass'; // Workaround for the issue that a function name can not be 'class' in ES - } - - if ((this)[prop]) { - if (types.isArray(value)) { - (this)[prop].apply(this, value); - } else { - (this)[prop].call(this, value); - } - } else { - this.currentElement.setAttribute(prop, value); - } - } - - /** - * Removes an attribute by the given name. - */ - removeAttribute(prop: string): void { - this.currentElement.removeAttribute(prop); - } - - /** - * Sets the id attribute to the value provided for the current HTML element of the builder. - */ - id(id: string): Builder { - this.currentElement.setAttribute('id', id); - - return this; - } - - /** - * Sets the title attribute to the value provided for the current HTML element of the builder. - */ - title(title: string): Builder { - this.currentElement.setAttribute('title', title); - - return this; - } - - /** - * Sets the type attribute to the value provided for the current HTML element of the builder. - */ - type(type: string): Builder { - this.currentElement.setAttribute('type', type); - - return this; - } - - /** - * Sets the value attribute to the value provided for the current HTML element of the builder. - */ - value(value: string): Builder { - this.currentElement.setAttribute('value', value); - - return this; - } - - /** - * Sets the tabindex attribute to the value provided for the current HTML element of the builder. - */ - tabindex(index: number): Builder { - this.currentElement.setAttribute('tabindex', index.toString()); - - return this; - } - - /** - * This method has different characteristics based on the parameter provided: - * a) a single string passed in as argument will return the style value using the - * string as key from the current element of the builder. - * b) two strings passed in will set the style value identified by the first - * parameter to match the second parameter. The second parameter can be null - * to unset a style - * c) an object literal passed in will apply the properties of the literal as styles - * to the current element of the builder. - */ - style(name: string): string; - style(name: string, value: string): Builder; - style(attributes: any): Builder; - style(firstP: any, secondP?: any): any { - - // Apply Object Literal to Styles of Element - if (types.isObject(firstP)) { - for (let prop in firstP) { - if (firstP.hasOwnProperty(prop)) { - let value = firstP[prop]; - this.doSetStyle(prop, value); - } - } - - return this; - } - - const hasFirstP = types.isString(firstP); - - // Get Style Value - if (hasFirstP && types.isUndefined(secondP)) { - return this.currentElement.style[this.cssKeyToJavaScriptProperty(firstP)]; - } - - // Set Style Value - else if (hasFirstP) { - this.doSetStyle(firstP, secondP); - } - - return this; - } - - private doSetStyle(key: string, value: string): void { - if (key.indexOf('-') >= 0) { - let segments = key.split('-'); - key = segments[0]; - for (let i = 1; i < segments.length; i++) { - let segment = segments[i]; - key = key + segment.charAt(0).toUpperCase() + segment.substr(1); - } - } - - this.currentElement.style[this.cssKeyToJavaScriptProperty(key)] = value; - } - - private cssKeyToJavaScriptProperty(key: string): string { - // Automagically convert dashes as they are not allowed when programmatically - // setting a CSS style property - - if (key.indexOf('-') >= 0) { - let segments = key.split('-'); - key = segments[0]; - for (let i = 1; i < segments.length; i++) { - let segment = segments[i]; - key = key + segment.charAt(0).toUpperCase() + segment.substr(1); - } - } - - // Float is special too - else if (key === 'float') { - key = 'cssFloat'; - } - - return key; - } - - /** - * Returns the computed CSS style for the current HTML element of the builder. - */ - getComputedStyle(): CSSStyleDeclaration { - return DOM.getComputedStyle(this.currentElement); - } - - /** - * Adds the variable list of arguments as class names to the current HTML element of the builder. - */ - addClass(...classes: string[]): Builder { - classes.forEach((nameValue: string) => { - let names = nameValue.split(' '); - names.forEach((name: string) => { - DOM.addClass(this.currentElement, name); - }); - }); - - return this; - } - - /** - * Sets the class name of the current HTML element of the builder to the provided className. - * If shouldAddClass is provided - for true class is added, for false class is removed. - */ - setClass(className: string, shouldAddClass: boolean = null): Builder { - if (shouldAddClass === null) { - this.currentElement.className = className; - } else if (shouldAddClass) { - this.addClass(className); - } else { - this.removeClass(className); - } - - return this; - } - - /** - * Returns whether the current HTML element of the builder has the provided class assigned. - */ - hasClass(className: string): boolean { - return DOM.hasClass(this.currentElement, className); - } - - /** - * Removes the variable list of arguments as class names from the current HTML element of the builder. - */ - removeClass(...classes: string[]): Builder { - classes.forEach((nameValue: string) => { - let names = nameValue.split(' '); - names.forEach((name: string) => { - DOM.removeClass(this.currentElement, name); - }); - }); - - return this; - } - - /** - * Adds or removes the provided className for the current HTML element of the builder. - */ - toggleClass(className: string): Builder { - if (this.hasClass(className)) { - this.removeClass(className); - } else { - this.addClass(className); - } - - return this; - } - - /** - * Sets the CSS property color. - */ - color(color: string): Builder { - this.currentElement.style.color = color; - - return this; - } - - /** - * Sets the CSS property padding. - */ - padding(padding: string): Builder; - padding(top: number, right?: number, bottom?: number, left?: number): Builder; - padding(top: string, right?: string, bottom?: string, left?: string): Builder; - padding(top: any, right?: any, bottom?: any, left?: any): Builder { - if (types.isString(top) && top.indexOf(' ') >= 0) { - return this.padding.apply(this, top.split(' ')); - } - - if (!types.isUndefinedOrNull(top)) { - this.currentElement.style.paddingTop = this.toPixel(top); - } - - if (!types.isUndefinedOrNull(right)) { - this.currentElement.style.paddingRight = this.toPixel(right); - } - - if (!types.isUndefinedOrNull(bottom)) { - this.currentElement.style.paddingBottom = this.toPixel(bottom); - } - - if (!types.isUndefinedOrNull(left)) { - this.currentElement.style.paddingLeft = this.toPixel(left); - } - - return this; - } - - /** - * Sets the CSS property margin. - */ - margin(margin: string): Builder; - margin(top: number, right?: number, bottom?: number, left?: number): Builder; - margin(top: string, right?: string, bottom?: string, left?: string): Builder; - margin(top: any, right?: any, bottom?: any, left?: any): Builder { - if (types.isString(top) && top.indexOf(' ') >= 0) { - return this.margin.apply(this, top.split(' ')); - } - - if (!types.isUndefinedOrNull(top)) { - this.currentElement.style.marginTop = this.toPixel(top); - } - - if (!types.isUndefinedOrNull(right)) { - this.currentElement.style.marginRight = this.toPixel(right); - } - - if (!types.isUndefinedOrNull(bottom)) { - this.currentElement.style.marginBottom = this.toPixel(bottom); - } - - if (!types.isUndefinedOrNull(left)) { - this.currentElement.style.marginLeft = this.toPixel(left); - } - - return this; - } - - /** - * Sets the CSS property position. - */ - position(position: string): Builder; - position(top: number, right?: number, bottom?: number, left?: number, position?: string): Builder; - position(top: string, right?: string, bottom?: string, left?: string, position?: string): Builder; - position(top: any, right?: any, bottom?: any, left?: any, position?: string): Builder { - if (types.isString(top) && top.indexOf(' ') >= 0) { - return this.position.apply(this, top.split(' ')); - } - - if (!types.isUndefinedOrNull(top)) { - this.currentElement.style.top = this.toPixel(top); - } - - if (!types.isUndefinedOrNull(right)) { - this.currentElement.style.right = this.toPixel(right); - } - - if (!types.isUndefinedOrNull(bottom)) { - this.currentElement.style.bottom = this.toPixel(bottom); - } - - if (!types.isUndefinedOrNull(left)) { - this.currentElement.style.left = this.toPixel(left); - } - - if (!position) { - position = 'absolute'; - } - - this.currentElement.style.position = position; - - return this; - } - - /** - * Sets the CSS property size. - */ - size(size: string): Builder; - size(width: number, height?: number): Builder; - size(width: string, height?: string): Builder; - size(width: any, height?: any): Builder { - if (types.isString(width) && width.indexOf(' ') >= 0) { - return this.size.apply(this, width.split(' ')); - } - - if (!types.isUndefinedOrNull(width)) { - this.currentElement.style.width = this.toPixel(width); - } - - if (!types.isUndefinedOrNull(height)) { - this.currentElement.style.height = this.toPixel(height); - } - - return this; - } - - /** - * Sets the CSS property display. - */ - display(display: string): Builder { - this.currentElement.style.display = display; - - return this; - } - - /** - * Shows the current element of the builder. - */ - show(): Builder { - if (this.hasClass('monaco-builder-hidden')) { - this.removeClass('monaco-builder-hidden'); - } - - this.attr('aria-hidden', 'false'); - - // Cancel any pending showDelayed() invocation - this.cancelVisibilityTimeout(); - - return this; - } - - /** - * Shows the current builder element after the provided delay. If the builder - * was set to hidden using the hide() method before this method executed, the - * function will return without showing the current element. This is useful to - * only show the element when a specific delay is reached (e.g. for a long running - * operation. - */ - showDelayed(delay: number): Builder { - - // Cancel any pending showDelayed() invocation - this.cancelVisibilityTimeout(); - - // Install new delay for showing - const handle = setTimeout(() => { - this.removeProperty(VISIBILITY_BINDING_ID); - this.show(); - }, delay); - - this.setProperty(VISIBILITY_BINDING_ID, toDisposable(() => clearTimeout(handle))); - - return this; - } - - /** - * Hides the current element of the builder. - */ - hide(): Builder { - if (!this.hasClass('monaco-builder-hidden')) { - this.addClass('monaco-builder-hidden'); - } - this.attr('aria-hidden', 'true'); - - // Cancel any pending showDelayed() invocation - this.cancelVisibilityTimeout(); - - return this; - } - - /** - * Returns true if the current element of the builder is hidden. - */ - isHidden(): boolean { - return this.hasClass('monaco-builder-hidden') || this.currentElement.style.display === 'none'; - } - - private cancelVisibilityTimeout(): void { - const visibilityDisposable = this.getProperty(VISIBILITY_BINDING_ID) as IDisposable; - if (visibilityDisposable) { - visibilityDisposable.dispose(); - this.removeProperty(VISIBILITY_BINDING_ID); - } - } - - private toPixel(obj: any): string { - if (obj.toString().indexOf('px') === -1) { - return obj.toString() + 'px'; - } - - return obj; - } - - /** - * Sets the innerHTML attribute. - */ - innerHtml(html: string, append?: boolean): Builder { - if (append) { - this.currentElement.innerHTML += html; - } else { - this.currentElement.innerHTML = html; - } - - return this; - } - - /** - * Sets the textContent property of the element. - * All HTML special characters will be escaped. - */ - text(text: string, append?: boolean): Builder { - if (append) { - // children is child Elements versus childNodes includes textNodes - if (this.currentElement.children.length === 0) { - this.currentElement.textContent += text; - } - else { - // if there are elements inside this node, append the string as a new text node - // to avoid wiping out the innerHTML and replacing it with only text content - this.currentElement.appendChild(document.createTextNode(text)); - } - } else { - this.currentElement.textContent = text; - } - - return this; - } - - /** - * Sets the innerHTML attribute in escaped form. - */ - safeInnerHtml(html: string, append?: boolean): Builder { - return this.innerHtml(strings.escape(html), append); - } - - /** - * Allows to store arbritary data into the current element. - */ - setProperty(key: string, value: any): Builder { - _setPropertyOnElement(this.currentElement, key, value); - - return this; - } - - /** - * Allows to get arbritary data from the current element. - */ - getProperty(key: string, fallback?: any): any { - return _getPropertyFromElement(this.currentElement, key, fallback); - } - - /** - * Removes a property from the current element that is stored under the given key. - */ - removeProperty(key: string): Builder { - if (hasData(this.currentElement)) { - delete data(this.currentElement)[key]; - } - - return this; - } - - /** - * Returns a new builder with the child at the given index. - */ - child(index = 0): Builder { - let children = this.currentElement.children; - - return _withElement(children.item(index)); - } - - /** - * Recurse through all descendant nodes and remove their data binding. - */ - private unbindDescendants(current: HTMLElement): void { - if (current && current.children) { - for (let i = 0, length = current.children.length; i < length; i++) { - let element = current.children.item(i); - - // Unbind - if (hasData(element)) { - - // Listeners - let listeners: IDisposable[] = data(element)[LISTENER_BINDING_ID]; - if (types.isArray(listeners)) { - while (listeners.length) { - listeners.pop().dispose(); - } - } - - // Delete Data Slot - delete element[MS_DATA_KEY]; - } - - // Recurse - this.unbindDescendants(element); - } - } - } - - /** - * Removes all HTML elements from the current element of the builder. Will also clean up any - * event listners registered and also clear any data binding and properties stored - * to any child element. - */ - empty(): Builder { - this.unbindDescendants(this.currentElement); - - this.clearChildren(); - - if (this.offdom) { - this.createdElements = []; - } - - return this; - } - - /** - * Removes all HTML elements from the current element of the builder. - */ - clearChildren(): Builder { - - // Remove Elements - if (this.currentElement) { - DOM.clearNode(this.currentElement); - } - - return this; - } - - /** - * Removes the current HTML element and all its children from its parent and unbinds - * all listeners and properties set to the data slots. - */ - destroy(): void { - - if (this.currentElement) { - - // Remove from parent - if (this.currentElement.parentNode) { - this.currentElement.parentNode.removeChild(this.currentElement); - } - - // Empty to clear listeners and bindings from children - this.empty(); - - // Unbind - if (hasData(this.currentElement)) { - - // Listeners - let listeners: IDisposable[] = data(this.currentElement)[LISTENER_BINDING_ID]; - if (types.isArray(listeners)) { - while (listeners.length) { - listeners.pop().dispose(); - } - } - - // Delete Data Slot - delete this.currentElement[MS_DATA_KEY]; - } - } - - let type: string; - - for (type in this.toDispose) { - if (this.toDispose.hasOwnProperty(type) && types.isArray(this.toDispose[type])) { - this.toDispose[type] = dispose(this.toDispose[type]); - } - } - - for (type in this.captureToDispose) { - if (this.captureToDispose.hasOwnProperty(type) && types.isArray(this.captureToDispose[type])) { - this.captureToDispose[type] = dispose(this.captureToDispose[type]); - } - } - - // Nullify fields - this.currentElement = null; - this.container = null; - this.offdom = null; - this.createdElements = null; - this.captureToDispose = null; - this.toDispose = null; - } - - /** - * Removes the current HTML element and all its children from its parent and unbinds - * all listeners and properties set to the data slots. - */ - dispose(): void { - this.destroy(); - } - - /** - * Gets the size (in pixels) of an element, including the margin. - */ - getTotalSize(): DOM.Dimension { - let totalWidth = DOM.getTotalWidth(this.currentElement); - let totalHeight = DOM.getTotalHeight(this.currentElement); - - return new DOM.Dimension(totalWidth, totalHeight); - } - - /** - * Another variant of getting the inner dimensions of an element. - */ - getClientArea(): DOM.Dimension { - return DOM.getClientArea(this.currentElement); - } -} - -/** - * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - * - * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - */ -export class MultiBuilder extends Builder { - - length: number; - - private builders: Builder[]; - - constructor(multiBuilder: MultiBuilder); - constructor(builder: Builder); - constructor(builders: Builder[]); - constructor(elements: HTMLElement[]); - constructor(builders: any) { - assert.ok(types.isArray(builders) || builders instanceof MultiBuilder, 'Expected Array or MultiBuilder as parameter'); - - super(); - this.length = 0; - this.builders = []; - - // Add Builders to Array - if (types.isArray(builders)) { - for (let i = 0; i < builders.length; i++) { - if (builders[i] instanceof HTMLElement) { - this.push(_withElement(builders[i])); - } else { - this.push(builders[i]); - } - } - } else { - for (let i = 0; i < (builders).length; i++) { - this.push((builders).item(i)); - } - } - - // Mixin Builder functions to operate on all builders - let $outer = this; - let propertyFn = (prop: string) => { - ($outer)[prop] = function (): any { - let args = Array.prototype.slice.call(arguments); - - let returnValues: any[]; - let mergeBuilders = false; - - for (let i = 0; i < $outer.length; i++) { - let res = ($outer.item(i))[prop].apply($outer.item(i), args); - - // Merge MultiBuilders into one - if (res instanceof MultiBuilder) { - if (!returnValues) { - returnValues = []; - } - mergeBuilders = true; - - for (let j = 0; j < (res).length; j++) { - returnValues.push((res).item(j)); - } - } - - // Any other Return Type (e.g. boolean, integer) - else if (!types.isUndefined(res) && !(res instanceof Builder)) { - if (!returnValues) { - returnValues = []; - } - - returnValues.push(res); - } - } - - if (returnValues && mergeBuilders) { - return new MultiBuilder(returnValues); - } - - return returnValues || $outer; - }; - }; - - for (let prop in Builder.prototype) { - if (prop !== 'clone' && prop !== 'and') { // Skip methods that are explicitly defined in MultiBuilder - if (Builder.prototype.hasOwnProperty(prop) && types.isFunction((Builder).prototype[prop])) { - propertyFn(prop); - } - } - } - } - - item(i: number): Builder { - return this.builders[i]; - } - - push(...items: Builder[]): void { - for (let i = 0; i < items.length; i++) { - this.builders.push(items[i]); - } - - this.length = this.builders.length; - } - - clone(): MultiBuilder { - return new MultiBuilder(this); - } -} - -function withBuilder(builder: Builder, offdom?: boolean): Builder { - if (builder instanceof MultiBuilder) { - return new MultiBuilder((builder)); - } - - return new Builder(builder.getHTMLElement(), offdom); -} - -export function _withElement(element: HTMLElement, offdom?: boolean): Builder { - return new Builder(element, offdom); -} - -function offDOM(): Builder { - return new Builder(null, true); -} - -// Binding functions - -/** - * Allows to store arbritary data into element. - */ -export function _setPropertyOnElement(element: HTMLElement, key: string, value: any): void { - data(element)[key] = value; -} - -/** - * Allows to get arbritary data from element. - */ -export function _getPropertyFromElement(element: HTMLElement, key: string, fallback?: any): any { - if (hasData(element)) { - let value = data(element)[key]; - if (!types.isUndefined(value)) { - return value; - } - } - - return fallback; -} - -/** - * Adds the provided object as property to the given element. Call getBinding() - * to retrieve it again. - */ -export function _bindElement(element: HTMLElement, object: any): void { - _setPropertyOnElement(element, DATA_BINDING_ID, object); -} - -let SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/; - -/** - * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - * - * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! - */ -export const $: QuickBuilder = function (arg?: any): Builder { - - // Off-DOM use - if (types.isUndefined(arg)) { - return offDOM(); - } - - // Falsified values cause error otherwise - if (!arg) { - throw new Error('Bad use of $'); - } - - // Wrap the given element - if (DOM.isHTMLElement(arg) || arg === window) { - return _withElement(arg); - } - - // Wrap the given builders - if (types.isArray(arg)) { - return new MultiBuilder(arg); - } - - // Wrap the given builder - if (arg instanceof Builder) { - return withBuilder((arg)); - } - - if (types.isString(arg)) { - - // Use the argument as HTML code - if (arg[0] === '<') { - let element: Node; - let container = document.createElement('div'); - container.innerHTML = strings.format.apply(strings, arguments); - - if (container.children.length === 0) { - throw new Error('Bad use of $'); - } - - if (container.children.length === 1) { - element = container.firstChild; - container.removeChild(element); - - return _withElement(element); - } - - let builders: Builder[] = []; - while (container.firstChild) { - element = container.firstChild; - container.removeChild(element); - builders.push(_withElement(element)); - } - - return new MultiBuilder(builders); - } - - // Use the argument as a selector constructor - else if (arguments.length === 1) { - let match = SELECTOR_REGEX.exec(arg); - if (!match) { - throw new Error('Bad use of $'); - } - - let tag = match[1] || 'div'; - let id = match[3] || undefined; - let classes = (match[4] || '').replace(/\./g, ' '); - - let props: any = {}; - if (id) { - props['id'] = id; - } - - if (classes) { - props['class'] = classes; - } - - return offDOM().element(tag, props); - } - - // Use the arguments as the arguments to Builder#element(...) - else { - let result = offDOM(); - result.element.apply(result, arguments); - return result; - } - } else { - throw new Error('Bad use of $'); - } -}; diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index d4b1fe9704c..08be2a19ccb 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -970,7 +970,6 @@ export function prepend(parent: HTMLElement, child: T): T { const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/; -// Similar to builder, but much more lightweight export function $(description: string, attrs?: { [key: string]: any; }, ...children: (Node | string)[]): T { let match = SELECTOR_REGEX.exec(description); diff --git a/src/vs/base/test/browser/builder.test.ts b/src/vs/base/test/browser/builder.test.ts deleted file mode 100644 index f592174bd50..00000000000 --- a/src/vs/base/test/browser/builder.test.ts +++ /dev/null @@ -1,1323 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 * as assert from 'assert'; -import { Builder, MultiBuilder, $, _bindElement, _withElement, _setPropertyOnElement, _getPropertyFromElement } from 'vs/base/browser/builder'; -import * as Types from 'vs/base/common/types'; -import * as DomUtils from 'vs/base/browser/dom'; -import { IDisposable } from 'vs/base/common/lifecycle'; -import { timeout } from 'vs/base/common/async'; - -function withElementById(id: string, offdom?: boolean): Builder { - let element = document.getElementById(id); - if (element) { - return new Builder(element, offdom); - } - - return null; -} - -const Build = { - withElementById: withElementById -}; - -let withElementsBySelector = function (selector: string, offdom: boolean = false) { - let elements = window.document.querySelectorAll(selector); - - let builders = []; - for (let i = 0; i < elements.length; i++) { - builders.push(new Builder(elements.item(i), offdom)); - } - - return new MultiBuilder(builders); -}; - -let withBuilder = function (builder: Builder, offdom: boolean) { - if (builder instanceof MultiBuilder) { - return new MultiBuilder(builder); - } - - return new Builder(builder.getHTMLElement(), offdom); -}; - -function select(builder: Builder, selector: string, offdom?: boolean): MultiBuilder { - let elements = builder.getHTMLElement().querySelectorAll(selector); - - let builders: Builder[] = []; - for (let i = 0; i < elements.length; i++) { - builders.push(_withElement(elements.item(i), offdom)); - } - - return new MultiBuilder(builders); -} - -suite('Builder', () => { - let fixture: HTMLElement; - let fixtureId = 'builder-fixture'; - - setup(() => { - fixture = document.createElement('div'); - fixture.id = fixtureId; - document.body.appendChild(fixture); - }); - - teardown(() => { - document.body.removeChild(fixture); - }); - - test('Binding', function () { - let b = Build.withElementById(fixtureId, false); - let element = b.getHTMLElement(); - - assert(element); - - // Properties - _setPropertyOnElement(element, 'foo', 'bar'); - assert.strictEqual(_getPropertyFromElement(element, 'foo'), 'bar'); - - _setPropertyOnElement(element, 'foo', { foo: 'bar' }); - assert.deepEqual(_getPropertyFromElement(element, 'foo'), { foo: 'bar' }); - - _setPropertyOnElement(element, 'bar', 'bar'); - assert.strictEqual(_getPropertyFromElement(element, 'bar'), 'bar'); - - _setPropertyOnElement(element, 'bar', { foo: 'bar' }); - assert.deepEqual(_getPropertyFromElement(element, 'bar'), { foo: 'bar' }); - }); - - test('Select', function () { - let b = Build.withElementById(fixtureId, false); - assert(b); - - let allDivs = withElementsBySelector('div'); - - assert(allDivs); - assert(allDivs.length >= 1); - assert(Types.isFunction(allDivs.push)); - assert(allDivs instanceof MultiBuilder); - - for (let key in b) { - if (b.hasOwnProperty(key) && Types.isFunction((b as any)[key])) { - assert(allDivs.hasOwnProperty(key)); - } - } - - let noElement = withElementsBySelector('#thiselementdoesnotexist'); - - assert(noElement); - assert(noElement.length === 0); - assert(Types.isFunction(noElement.push)); - assert(noElement instanceof MultiBuilder); - - for (let key in b) { - if (b.hasOwnProperty(key) && Types.isFunction((b as any)[key])) { - assert(noElement.hasOwnProperty(key)); - } - } - }); - - test('Build.withElement()', function () { - let f = Build.withElementById(fixtureId, false); - let b = $(f.getHTMLElement()); - - b.addClass('foo'); - assert(b.hasClass('foo')); - - b.removeClass('foo'); - assert(!b.hasClass('foo')); - - assert.strictEqual(f.getHTMLElement(), document.getElementById(fixtureId)); - assert.strictEqual(b.getHTMLElement(), document.getElementById(fixtureId)); - }); - - test('Build.withBuilder()', function () { - let f = Build.withElementById(fixtureId, false); - let b = withBuilder(f, false); - - b.addClass('foo'); - assert(b.hasClass('foo')); - - b.removeClass('foo'); - assert(!b.hasClass('foo')); - - assert.strictEqual(f.getHTMLElement(), document.getElementById(fixtureId)); - assert.strictEqual(b.getHTMLElement(), document.getElementById(fixtureId)); - }); - - test('Build.withBuilder() - Multibuilder', function () { - let f = withElementsBySelector('#' + fixtureId); - let b = withBuilder(f, false); - - b.addClass('foo'); - assert(b.hasClass('foo')[0]); - - b.removeClass('foo'); - assert(!b.hasClass('foo')[0]); - }); - - test('Build.offDOM()', function () { - let b = $(); - assert(b); - - b.div({ - id: 'foobar' - }, function (div) { - div.span({ - id: 'foobarspan', - innerHtml: 'foo bar' - }); - }); - - assert(Build.withElementById('foobar') === null); - - b.build(Build.withElementById(fixtureId, false)); - - assert(Build.withElementById('foobar')); - assert(Build.withElementById('foobarspan')); - assert.strictEqual(Build.withElementById('foobarspan').getHTMLElement().innerHTML, 'foo bar'); - }); - - test('Build.withElementById()', function () { - let b = Build.withElementById(fixtureId, false); - - b.addClass('foo'); - assert(b.hasClass('foo')); - - b.removeClass('foo'); - assert(!b.hasClass('foo')); - - assert.strictEqual(b.getHTMLElement(), document.getElementById(fixtureId)); - }); - - test('withElementsBySelector()', function () { - let b = withElementsBySelector('#' + fixtureId, false); - - b.addClass('foo'); - assert(b.hasClass('foo')[0]); - - b.removeClass('foo'); - assert(!b.hasClass('foo')[0]); - }); - - test('Off DOM withElementById and container passed in', function () { - let b = Build.withElementById(fixtureId, true); - assert(b); - assert.strictEqual(b.getHTMLElement(), document.getElementById(fixtureId)); - - b.div({ - id: 'foobar' - }, function (div) { - div.span({ - id: 'foobarspan', - innerHtml: 'foo bar' - }); - }); - - assert(Build.withElementById('foobar') === null); - - b.build(); - - assert(Build.withElementById('foobar')); - assert(Build.withElementById('foobarspan')); - assert.strictEqual(Build.withElementById('foobarspan').getHTMLElement().innerHTML, 'foo bar'); - }); - - test('Off DOM withSelector and container passed in', function () { - let b = withElementsBySelector('#' + fixtureId, true); - assert(b); - - b.div({ - id: 'foobar' - }, function (div) { - div.span({ - id: 'foobarspan', - innerHtml: 'foo bar' - }); - }); - - assert(Build.withElementById('foobar') === null); - - b.build(); - - assert(Build.withElementById('foobar')); - assert(Build.withElementById('foobarspan')); - assert.strictEqual(Build.withElementById('foobarspan').getHTMLElement().innerHTML, 'foo bar'); - }); - - test('Builder.build() with index specified', function () { - let b = Build.withElementById(fixtureId); - b.empty(); - b.div({ id: '1' }); - b.div({ id: '2' }); - b.div({ id: '3' }); - - b = $(); - b.div({ id: '4' }); - b.build(Build.withElementById(fixtureId), 0); - - b = Build.withElementById(fixtureId); - let divs = select(b, 'div'); - assert.strictEqual(divs.length, 4); - - let ids = divs.attr('id'); - assert.strictEqual(ids.length, 4); - assert.strictEqual(ids[0], '4'); - assert.strictEqual(ids[1], '1'); - assert.strictEqual(ids[2], '2'); - assert.strictEqual(ids[3], '3'); - - b = $(); - b.div({ id: '5' }); - b.build(Build.withElementById(fixtureId), 2); - - b = Build.withElementById(fixtureId); - divs = select(b, 'div'); - assert.strictEqual(divs.length, 5); - - ids = divs.attr('id'); - assert.strictEqual(ids.length, 5); - assert.strictEqual(ids[0], '4'); - assert.strictEqual(ids[1], '1'); - assert.strictEqual(ids[2], '5'); - assert.strictEqual(ids[3], '2'); - assert.strictEqual(ids[4], '3'); - }); - - test('Builder.asContainer()', function () { - let f = Build.withElementById(fixtureId, false); - f.div({ - id: 'foobar' - }); - - let divBuilder = f.asContainer(); - divBuilder.span({ - innerHtml: 'see man' - }); - }); - - test('Builder.clone()', function () { - let b = Build.withElementById(fixtureId); - - let clone = b.clone(); - assert(clone); - assert(clone instanceof Builder); - assert.strictEqual(b.getHTMLElement(), clone.getHTMLElement()); - assert.deepEqual(b, clone); - - let multiB = withElementsBySelector('div'); - - let multiClone = multiB.clone(); - assert(multiClone); - }); - - test('Builder Multibuilder fn call that returns Multibuilder', function () { - let b = Build.withElementById(fixtureId); - b.div(function (div: Builder) { - div.span(); - }); - - b.div(function (div: Builder) { - div.span(); - }); - - b.div(function (div: Builder) { - div.span(); - }); - - let multiBuilder = select(Build.withElementById(fixtureId), 'div'); - assert(multiBuilder.length === 3); - }); - - test('Builder.p() and other elements', function () { - let b = Build.withElementById(fixtureId); - b.empty(); - b.div(function (div: Builder) { - assert(div !== b); - assert.strictEqual('div', div.getHTMLElement().nodeName.toLowerCase()); - - div.p(function (p: Builder) { - p.ul(function (ul: Builder) { - ul.li(function (li: Builder) { - li.span({ - id: 'builderspan', - innerHtml: 'Foo Bar' - }); - - assert.strictEqual('span', li.getHTMLElement().nodeName.toLowerCase()); - - li.img({ - id: 'builderimg', - src: '#' - }); - - assert.strictEqual('img', li.getHTMLElement().nodeName.toLowerCase()); - - li.a({ - id: 'builderlink', - href: '#', - innerHtml: 'Link' - }); - - assert.strictEqual('a', li.getHTMLElement().nodeName.toLowerCase()); - }); - }); - }); - - assert.strictEqual('p', div.getHTMLElement().nodeName.toLowerCase()); - }); - - assert.strictEqual(select(Build.withElementById(fixtureId), 'div').length, 1); - assert.strictEqual(select(Build.withElementById(fixtureId), '*').length, 7); - - assert.strictEqual(Build.withElementById('builderspan').getHTMLElement().innerHTML, 'Foo Bar'); - assert.strictEqual(Build.withElementById('builderimg').attr('src'), '#'); - assert.strictEqual(Build.withElementById('builderlink').attr('href'), '#'); - - // Assert HTML through DOM - let root = document.getElementById(fixtureId); - assert.strictEqual(root.childNodes.length, 1); - - let div = root.childNodes[0]; - assert.strictEqual('div', div.nodeName.toLowerCase()); - assert.strictEqual(b.getHTMLElement(), div); - assert.strictEqual(div.childNodes.length, 1); - - let p = div.childNodes[0]; - assert.strictEqual('p', p.nodeName.toLowerCase()); - assert.strictEqual(p.childNodes.length, 1); - - let ul = p.childNodes[0]; - assert.strictEqual('ul', ul.nodeName.toLowerCase()); - assert.strictEqual(ul.childNodes.length, 1); - - let li = ul.childNodes[0]; - assert.strictEqual('li', li.nodeName.toLowerCase()); - assert.strictEqual(li.childNodes.length, 3); - - let span = li.childNodes[0]; - assert.strictEqual('span', span.nodeName.toLowerCase()); - assert.strictEqual(span.childNodes.length, 1); - assert.strictEqual(span.innerHTML, 'Foo Bar'); - - let img = li.childNodes[1]; - assert.strictEqual('img', img.nodeName.toLowerCase()); - assert.strictEqual(img.childNodes.length, 0); - assert.strictEqual(img.getAttribute('src'), '#'); - - let a = li.childNodes[2]; - assert.strictEqual('a', a.nodeName.toLowerCase()); - assert.strictEqual(a.childNodes.length, 1); - assert.strictEqual(a.getAttribute('href'), '#'); - assert.strictEqual(a.innerHTML, 'Link'); - }); - - test('Builder.p() and other elements', function () { - let b = Build.withElementById(fixtureId); - b.element('div', function (div: Builder) { - div.element('p', function (p: Builder) { - p.element('ul', function (ul: Builder) { - ul.element('li', function (li: Builder) { - li.element('span', { - id: 'builderspan', - innerHtml: 'Foo Bar' - }); - - li.element('img', { - id: 'builderimg', - src: '#' - }); - - li.element('a', { - id: 'builderlink', - href: '#', - innerHtml: 'Link' - }); - }); - }); - }); - }); - - assert.strictEqual(select(Build.withElementById(fixtureId), 'div').length, 1); - assert.strictEqual(select(Build.withElementById(fixtureId), '*').length, 7); - - assert.strictEqual(Build.withElementById('builderspan').getHTMLElement().innerHTML, 'Foo Bar'); - assert.strictEqual(Build.withElementById('builderimg').attr('src'), '#'); - assert.strictEqual(Build.withElementById('builderlink').attr('href'), '#'); - }); - - test('Builder.attr()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - assert(!b.attr('id')); - b.attr('id', 'foobar'); - assert.strictEqual(b.attr('id'), 'foobar'); - - b.attr({ - id: 'barfoo', - padding: [4, 3, 2, 1], - margin: '4px 3px 2px 1px' - }); - - assert.strictEqual(b.attr('id'), 'barfoo'); - assert.strictEqual(b.getHTMLElement().getAttribute('id'), 'barfoo'); - assert.strictEqual(b.style('margin-top'), '4px'); - assert.strictEqual(b.getHTMLElement().style.marginTop, '4px'); - assert.strictEqual(b.style('margin-right'), '3px'); - assert.strictEqual(b.style('margin-bottom'), '2px'); - assert.strictEqual(b.style('margin-left'), '1px'); - - assert.strictEqual(b.style('padding-top'), '4px'); - assert.strictEqual(b.style('padding-right'), '3px'); - assert.strictEqual(b.style('padding-bottom'), '2px'); - assert.strictEqual(b.style('padding-left'), '1px'); - - b.attr({ - padding: '1 2 3 4', - position: '100 200 300 400', - size: '200 300' - }); - - assert.strictEqual(b.style('padding-top'), '1px'); - assert.strictEqual(b.style('padding-right'), '2px'); - assert.strictEqual(b.style('padding-bottom'), '3px'); - assert.strictEqual(b.style('padding-left'), '4px'); - - assert.strictEqual(b.style('top'), '100px'); - assert.strictEqual(b.style('right'), '200px'); - assert.strictEqual(b.style('bottom'), '300px'); - assert.strictEqual(b.style('left'), '400px'); - - assert.strictEqual(b.style('width'), '200px'); - assert.strictEqual(b.style('height'), '300px'); - }); - - test('Builder.style()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.style('padding-bottom', '5px'); - b.style('paddingTop', '4px'); - - assert.strictEqual(b.style('paddingBottom'), '5px'); - assert.strictEqual(b.style('padding-bottom'), '5px'); - - assert.strictEqual(b.style('paddingTop'), '4px'); - assert.strictEqual(b.style('padding-top'), '4px'); - }); - - test('Builder.style() as object literal', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.style({ - 'padding-bottom': '5px', - paddingTop: '4px', - border: '1px solid red' - }); - - assert.strictEqual(b.getHTMLElement().style.paddingBottom, '5px'); - - assert.strictEqual(b.style('paddingBottom'), '5px'); - assert.strictEqual(b.style('padding-bottom'), '5px'); - - assert.strictEqual(b.style('paddingTop'), '4px'); - assert.strictEqual(b.style('padding-top'), '4px'); - - assert.strictEqual(b.style('border-width'), '1px'); - assert.strictEqual(b.style('border-style'), 'solid'); - assert.strictEqual(b.style('border-color'), 'red'); - }); - - test('Builder.attributes', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.id('foobar'); - b.title('foobar'); - b.type('foobar'); - b.value('foobar'); - b.tabindex(0); - - assert.strictEqual(b.attr('id'), 'foobar'); - assert.strictEqual(b.attr('title'), 'foobar'); - assert.strictEqual(b.attr('type'), 'foobar'); - assert.strictEqual(b.attr('value'), 'foobar'); - assert.strictEqual(b.attr('tabindex'), '0'); - - assert.strictEqual(b.getHTMLElement().getAttribute('id'), 'foobar'); - assert.strictEqual(b.getHTMLElement().getAttribute('title'), 'foobar'); - assert.strictEqual(b.getHTMLElement().getAttribute('type'), 'foobar'); - assert.strictEqual(b.getHTMLElement().getAttribute('value'), 'foobar'); - assert.strictEqual(b.getHTMLElement().getAttribute('tabindex'), '0'); - }); - - test('Builder.addClass() and Co', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - assert(!b.hasClass('foobar')); - assert(!b.getHTMLElement().className); - b.addClass('foobar'); - assert(b.getComputedStyle()); - assert(b.hasClass('foobar')); - assert.strictEqual(b.getHTMLElement().className, 'foobar'); - b.removeClass('foobar'); - assert(!b.hasClass('foobar')); - assert(!b.getHTMLElement().className); - - assert(!b.hasClass('foobar')); - b.attr({ 'class': 'foobar' }); - assert(b.hasClass('foobar')); - assert.strictEqual(b.getHTMLElement().className, 'foobar'); - b.removeClass('foobar'); - assert(!b.hasClass('foobar')); - assert(!b.getHTMLElement().className); - - b.addClass('foobar').addClass('barfoo').addClass('foobar'); - assert(b.hasClass('barfoo')); - assert(b.hasClass('foobar')); - b.removeClass('foobar').removeClass('barfoo'); - assert(!b.hasClass('barfoo')); - assert(!b.hasClass('foobar')); - assert(!b.getHTMLElement().className); - }); - - test('Builder.padding() and .margin()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.padding(4, 3, 2, 1).margin(1, 2, 3, 4); - - assert.strictEqual(b.style('padding-top'), '4px'); - assert.strictEqual(b.style('padding-right'), '3px'); - assert.strictEqual(b.style('padding-bottom'), '2px'); - assert.strictEqual(b.style('padding-left'), '1px'); - - assert.strictEqual(b.style('margin-top'), '1px'); - assert.strictEqual(b.style('margin-right'), '2px'); - assert.strictEqual(b.style('margin-bottom'), '3px'); - assert.strictEqual(b.style('margin-left'), '4px'); - assert(b.getComputedStyle()); - }); - - test('Builder.position()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.position(100, 200, 300, 400, 'relative'); - - assert.strictEqual(b.style('top'), '100px'); - assert.strictEqual(b.style('right'), '200px'); - assert.strictEqual(b.style('bottom'), '300px'); - assert.strictEqual(b.style('left'), '400px'); - assert.strictEqual(b.style('position'), 'relative'); - }); - - test('Builder.size(), .minSize() and .maxSize()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.size(100, 200); - - assert.strictEqual(b.style('width'), '100px'); - assert.strictEqual(b.style('height'), '200px'); - }); - - test('Builder.show() and .hide()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.show(); - assert(!b.hasClass('monaco-builder-hidden')); - assert(!b.isHidden()); - b.hide(); - assert(b.isHidden()); - b.show(); - b.hide(); - assert(b.hasClass('monaco-builder-hidden')); - assert(b.isHidden()); - }); - - test('Builder.showDelayed()', function () { - let b = Build.withElementById(fixtureId); - b.div().hide(); - - b.showDelayed(20); - assert(b.hasClass('monaco-builder-hidden')); - - return timeout(30).then(() => { - assert(!b.hasClass('monaco-builder-hidden')); - }); - }); - - test('Builder.showDelayed() but interrupted', function () { - let b = Build.withElementById(fixtureId); - b.div().hide(); - - b.showDelayed(20); - assert(b.hasClass('monaco-builder-hidden')); - - b.hide(); // Should cancel the visibility promise - - return timeout(30).then(() => { - assert(b.hasClass('monaco-builder-hidden')); - }); - }); - - test('Builder.innerHtml()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.innerHtml('Foo Bar'); - - assert.strictEqual(b.getHTMLElement().innerHTML, 'Foo Bar'); - }); - - test('Builder.safeInnerHtml()', function () { - let b = Build.withElementById(fixtureId); - b.div(); - - b.safeInnerHtml('Foo Bar'); - - assert.strictEqual(b.getHTMLElement().innerHTML, '<b>Foo Bar</b>'); - - b.safeInnerHtml('Foo Bar'); - - assert.strictEqual(b.getHTMLElement().innerHTML, 'Foo Bar'); - }); - - test('Build Client Area', function () { - - // Global - let dimensions = $(document.body).getClientArea(); - assert(dimensions.width > 0); - assert(dimensions.height > 0); - - // Local - let b = Build.withElementById(fixtureId); - dimensions = b.getClientArea(); - // assert(dimensions.width >= 0); - // assert(dimensions.height >= 0); - }); - - test('Builder.once()', function () { - let b = Build.withElementById(fixtureId); - b.element('input', { - type: 'button' - }); - - let counter = 0; - b.once(DomUtils.EventType.CLICK, function (e) { - counter++; - assert(counter <= 1); - }); - - b.getHTMLElement().click(); - b.getHTMLElement().click(); - }); - - test('Builder.once() with capture', function () { - let b = Build.withElementById(fixtureId); - b.element('input', { - type: 'button' - }); - - let counter = 0; - b.once(DomUtils.EventType.CLICK, function (e) { - counter++; - assert(counter <= 1); - }, null, true); - - b.getHTMLElement().click(); - b.getHTMLElement().click(); - }); - - test('Builder.on() and .off()', function () { - let b = Build.withElementById(fixtureId); - b.element('input', { - type: 'button' - }); - - let listeners: Builder[] = []; - let counter = 0; - b.on(DomUtils.EventType.CLICK, function (e) { - counter++; - }, listeners); - - assert(listeners.length === 1); - - b.getHTMLElement().click(); - b.off(DomUtils.EventType.BLUR); - b.getHTMLElement().click(); - b.off(DomUtils.EventType.CLICK); - b.getHTMLElement().click(); - b.getHTMLElement().click(); - - assert.equal(counter, 2); - }); - - test('Builder.on() and .off() with capture', function () { - let b = Build.withElementById(fixtureId); - b.element('input', { - type: 'button' - }); - - let listeners: Builder[] = []; - let counter = 0; - b.on(DomUtils.EventType.CLICK, function (e) { - counter++; - }, listeners, true); - - assert(listeners.length === 1); - - b.getHTMLElement().click(); - b.off(DomUtils.EventType.BLUR); - b.getHTMLElement().click(); - b.off(DomUtils.EventType.BLUR, true); - b.getHTMLElement().click(); - b.off(DomUtils.EventType.CLICK); - b.getHTMLElement().click(); - b.off(DomUtils.EventType.CLICK, true); - b.getHTMLElement().click(); - b.getHTMLElement().click(); - assert(counter === 4); - }); - - test('Builder.empty()', function () { - let inputs: Builder[] = []; - let bindings: Builder[] = []; - - let b = Build.withElementById(fixtureId); - let counter1 = 0; - let counter2 = 0; - let counter3 = 0; - let counter4 = 0; - let counter5 = 0; - let counter6 = 0; - let counter7 = 0; - - b.div(function (div: Builder) { - _bindElement(div.getHTMLElement(), 'Foo Bar'); - div.setProperty('Foo', 'Bar'); - bindings.push(div.clone()); - - div.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function () { - counter1++; - assert(counter1 <= 1); - }); - inputs.push(div.clone()); - - div.p(function (p: Builder) { - _bindElement(p.getHTMLElement(), 'Foo Bar'); - p.setProperty('Foo', 'Bar'); - bindings.push(p.clone()); - - p.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function () { - counter2++; - assert(counter2 <= 1); - }); - inputs.push(p.clone()); - - p.ul(function (ul: Builder) { - _bindElement(ul.getHTMLElement(), 'Foo Bar'); - ul.setProperty('Foo', 'Bar'); - bindings.push(ul.clone()); - - ul.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter3++; - assert(counter3 <= 1); - }); - inputs.push(ul.clone()); - - ul.li(function (li: Builder) { - _bindElement(li.getHTMLElement(), 'Foo Bar'); - li.setProperty('Foo', 'Bar'); - bindings.push(li.clone()); - - li.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter4++; - assert(counter4 <= 1); - }); - inputs.push(li.clone()); - - li.span({ - id: 'builderspan', - innerHtml: 'Foo Bar' - }, function (span) { - _bindElement(span.getHTMLElement(), 'Foo Bar'); - span.setProperty('Foo', 'Bar'); - bindings.push(span.clone()); - - span.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter5++; - assert(counter5 <= 1); - }); - inputs.push(span.clone()); - }); - - li.img({ - id: 'builderimg', - src: '#' - }, function (img) { - _bindElement(img.getHTMLElement(), 'Foo Bar'); - img.setProperty('Foo', 'Bar'); - bindings.push(img.clone()); - - img.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter6++; - assert(counter6 <= 1); - }); - inputs.push(img.clone()); - }); - - li.a({ - id: 'builderlink', - href: '#', - innerHtml: 'Link' - }, function (a) { - _bindElement(a.getHTMLElement(), 'Foo Bar'); - a.setProperty('Foo', 'Bar'); - bindings.push(a.clone()); - - a.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter7++; - assert(counter7 <= 1); - }); - inputs.push(a.clone()); - }); - }); - }); - }); - }); - - inputs.forEach(function (input) { - input.getHTMLElement().click(); - }); - - for (let i = 0; i < bindings.length; i++) { - assert(bindings[i].getProperty('Foo')); - } - - Build.withElementById(fixtureId).empty(); - assert(select(Build.withElementById(fixtureId), '*').length === 0); - - inputs.forEach(function (input) { - input.getHTMLElement().click(); - }); - - for (let i = 0; i < bindings.length; i++) { - assert(!bindings[i].getProperty('Foo')); - } - - assert.equal(counter1, 1); - assert.equal(counter2, 1); - assert.equal(counter3, 1); - assert.equal(counter4, 1); - assert.equal(counter5, 1); - assert.equal(counter6, 1); - assert.equal(counter7, 1); - }); - - test('Builder.empty() cleans all listeners', function () { - let b = Build.withElementById(fixtureId); - let unbindCounter = 0; - - let old = DomUtils.addDisposableListener; - try { - (DomUtils as any).addDisposableListener = function (node: any, type: any, handler: any) { - let unbind: IDisposable = old.call(null, node, type, handler); - - return { - dispose: function () { - unbindCounter++; - unbind.dispose(); - } - }; - }; - - b.div(function (div: Builder) { - div.p(function (p: Builder) { - p.span().on([DomUtils.EventType.CLICK, DomUtils.EventType.KEY_DOWN], function (e) { }); - - p.img().on([DomUtils.EventType.KEY_PRESS, DomUtils.EventType.MOUSE_OUT], function (e) { }, null, true); // useCapture - - p.a(function (a: Builder) { - a.span().on([DomUtils.EventType.CLICK, DomUtils.EventType.KEY_DOWN], function (e) { }); - }).on([DomUtils.EventType.SELECT, DomUtils.EventType.BLUR], function (e) { }); - }); - }); - - b.empty(); - assert.strictEqual(unbindCounter, 8); - } finally { - (DomUtils as any).addDisposableListener = old; - } - }); - - test('Builder.destroy()', function () { - let inputs: Builder[] = []; - let bindings: Builder[] = []; - - let b = Build.withElementById(fixtureId); - let counter1 = 0; - let counter2 = 0; - let counter3 = 0; - let counter4 = 0; - let counter5 = 0; - let counter6 = 0; - let counter7 = 0; - - b.div(function (div: Builder) { - _bindElement(div.getHTMLElement(), 'Foo Bar'); - div.setProperty('Foo', 'Bar'); - bindings.push(div.clone()); - - div.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter1++; - assert(counter1 <= 1); - }, null, true); // useCapture - inputs.push(div.clone()); - - div.p(function (p: Builder) { - _bindElement(p.getHTMLElement(), 'Foo Bar'); - p.setProperty('Foo', 'Bar'); - bindings.push(p.clone()); - - p.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter2++; - assert(counter2 <= 1); - }); - inputs.push(p.clone()); - - p.ul(function (ul: Builder) { - _bindElement(ul.getHTMLElement(), 'Foo Bar'); - ul.setProperty('Foo', 'Bar'); - bindings.push(ul.clone()); - - ul.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter3++; - assert(counter3 <= 1); - }); - inputs.push(ul.clone()); - - ul.li(function (li: Builder) { - _bindElement(li.getHTMLElement(), 'Foo Bar'); - li.setProperty('Foo', 'Bar'); - bindings.push(li.clone()); - - li.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function () { - counter4++; - assert(counter4 <= 1); - }); - inputs.push(li.clone()); - - li.span({ - id: 'builderspan', - innerHtml: 'Foo Bar' - }, function (span) { - _bindElement(span.getHTMLElement(), 'Foo Bar'); - span.setProperty('Foo', 'Bar'); - bindings.push(span.clone()); - - span.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter5++; - assert(counter5 <= 1); - }); - inputs.push(span.clone()); - }); - - li.img({ - id: 'builderimg', - src: '#' - }, function (img) { - _bindElement(img.getHTMLElement(), 'Foo Bar'); - img.setProperty('Foo', 'Bar'); - bindings.push(img.clone()); - - img.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter6++; - assert(counter6 <= 1); - }); - inputs.push(img.clone()); - }); - - li.a({ - id: 'builderlink', - href: '#', - innerHtml: 'Link' - }, function (a) { - _bindElement(a.getHTMLElement(), 'Foo Bar'); - a.setProperty('Foo', 'Bar'); - bindings.push(a.clone()); - - a.element('input', { - type: 'button' - }).on(DomUtils.EventType.CLICK, function (e) { - counter7++; - assert(counter7 <= 1); - }); - inputs.push(a.clone()); - }); - }); - }); - }); - }); - - inputs.forEach(function (input) { - input.getHTMLElement().click(); - }); - - for (let i = 0; i < bindings.length; i++) { - assert(bindings[i].getProperty('Foo')); - } - - select(Build.withElementById(fixtureId), 'div').destroy(); - assert(select(Build.withElementById(fixtureId), '*').length === 0); - - inputs.forEach(function (input) { - input.getHTMLElement().click(); - }); - - for (let i = 0; i < bindings.length; i++) { - assert(!bindings[i].getProperty('Foo')); - } - - assert.equal(counter1, 1); - assert.equal(counter2, 1); - assert.equal(counter3, 1); - assert.equal(counter4, 1); - assert.equal(counter5, 1); - assert.equal(counter6, 1); - assert.equal(counter7, 1); - }); - - test('Builder.destroy() cleans all listeners', function () { - let b = Build.withElementById(fixtureId); - let unbindCounter = 0; - - let old = DomUtils.addDisposableListener; - try { - (DomUtils as any).addDisposableListener = function (node: any, type: any, handler: any) { - let unbind: IDisposable = old.call(null, node, type, handler); - - return { - dispose: function () { - unbindCounter++; - unbind.dispose(); - } - }; - }; - - b.div(function (div: Builder) { - div.p(function (p: Builder) { - p.span().on([DomUtils.EventType.CLICK, DomUtils.EventType.KEY_DOWN], function (e) { }); - - p.img().on([DomUtils.EventType.KEY_PRESS, DomUtils.EventType.MOUSE_OUT], function (e) { }); - - p.a(function (a: Builder) { - a.span().on([DomUtils.EventType.CLICK, DomUtils.EventType.KEY_DOWN], function (e) { }); - }).on([DomUtils.EventType.SELECT, DomUtils.EventType.BLUR], function (e) { }); - }); - }) - .on([DomUtils.EventType.CLICK, DomUtils.EventType.KEY_DOWN], function (e) { }) - .on([DomUtils.EventType.BLUR, DomUtils.EventType.FOCUS], function (e) { }, null, true); //useCapture - - b.destroy(); - assert.strictEqual(unbindCounter, 16); - } finally { - (DomUtils as any).addDisposableListener = old; - } - }); - - test('Builder.offDOM()', function () { - let b = Build.withElementById(fixtureId); - b.div({ id: '1' }); - - assert(Build.withElementById('1')); - - b.offDOM(); - - assert(!Build.withElementById('1')); - }); - - test('$ - selector construction', function () { - let obj = $('div'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'div'); - assert.equal(obj.getHTMLElement().id, ''); - assert.equal(obj.getHTMLElement().className, ''); - - obj = $('#myid'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'div'); - assert.equal(obj.getHTMLElement().id, 'myid'); - assert.equal(obj.getHTMLElement().className, ''); - - obj = $('.myclass'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'div'); - assert.equal(obj.getHTMLElement().id, ''); - assert.equal(obj.getHTMLElement().className, 'myclass'); - - obj = $('.myclass.element'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'div'); - assert.equal(obj.getHTMLElement().id, ''); - assert.equal(obj.getHTMLElement().className, 'myclass element'); - - obj = $('#myid.element'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'div'); - assert.equal(obj.getHTMLElement().id, 'myid'); - assert.equal(obj.getHTMLElement().className, 'element'); - - obj = $('ul#myid'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'ul'); - assert.equal(obj.getHTMLElement().id, 'myid'); - assert.equal(obj.getHTMLElement().className, ''); - - obj = $('header#monaco.container'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'header'); - assert.equal(obj.getHTMLElement().id, 'monaco'); - assert.equal(obj.getHTMLElement().className, 'container'); - - obj = $('header#monaco.container.box'); - assert(obj instanceof Builder); - assert(DomUtils.isHTMLElement(obj.getHTMLElement())); - assert.equal(obj.getHTMLElement().tagName.toLowerCase(), 'header'); - assert.equal(obj.getHTMLElement().id, 'monaco'); - assert.equal(obj.getHTMLElement().className, 'container box'); - }); - - test('$ - wrap elements and builders', function () { - let obj = $('#' + fixtureId); - assert(obj instanceof Builder); - obj = $(obj.getHTMLElement()); - assert(obj instanceof Builder); - obj = $(obj); - assert(obj instanceof Builder); - }); - - test('$ - delegate to #element', function () { - let obj = $('a', { 'class': 'a1', innerHtml: 'Hello' }); - assert(obj instanceof Builder); - let el = obj.getHTMLElement(); - assert.equal(el.tagName.toLowerCase(), 'a'); - assert.equal(el.className, 'a1'); - assert.equal(el.innerHTML, 'Hello'); - }); - - test('$ - html', function () { - let obj = $('Hello'); - assert(obj instanceof Builder); - let el = obj.getHTMLElement(); - assert.equal(el.tagName.toLowerCase(), 'a'); - assert.equal(el.className, 'a1'); - assert.equal(el.innerHTML, 'Hello'); - }); - - test('$ - multiple html tags', function () { - let objs = $('HelloThere'); - assert(objs instanceof MultiBuilder); - assert.equal(objs.length, 2); - - let obj = objs.item(0).getHTMLElement(); - assert.equal(obj.tagName.toLowerCase(), 'a'); - assert.equal(obj.className, 'a1'); - assert.equal(obj.innerHTML, 'Hello'); - - obj = objs.item(1).getHTMLElement(); - assert.equal(obj.tagName.toLowerCase(), 'a'); - assert.equal(obj.className, 'a2'); - assert.equal(obj.innerHTML, 'There'); - }); - - test('$ - html format', function () { - let objs = ($)('{1}{3}', 'a1', 'Hello', 'a2', 'There'); - assert(objs instanceof MultiBuilder); - assert.equal(objs.length, 2); - - let obj = objs.item(0).getHTMLElement(); - assert.equal(obj.tagName.toLowerCase(), 'a'); - assert.equal(obj.className, 'a1'); - assert.equal(obj.innerHTML, 'Hello'); - - obj = objs.item(1).getHTMLElement(); - assert.equal(obj.tagName.toLowerCase(), 'a'); - assert.equal(obj.className, 'a2'); - assert.equal(obj.innerHTML, 'There'); - }); - - test('$ - exceptions', function () { - assert.throws(function () { $(''); }); - assert.throws(function () { $(123); }); - }); - - test('$ - appendTo, append', function () { - let peel = $('
'); - let core = $('').appendTo(peel); - let obj = peel.getHTMLElement(); - assert(obj); - assert.equal(obj.tagName.toLowerCase(), 'div'); - assert.equal(obj.className, 'peel'); - assert.equal(obj.children.length, 1); - assert(obj.firstChild); - assert.equal((obj.firstChild).children.length, 0); - assert.equal((obj.firstChild).tagName.toLowerCase(), 'span'); - assert.equal((obj.firstChild).className, 'core'); - obj = core.getHTMLElement(); - assert.equal(obj.children.length, 0); - assert.equal(obj.tagName.toLowerCase(), 'span'); - assert.equal(obj.className, 'core'); - - peel = $('
').append($('')); - obj = peel.getHTMLElement(); - assert(obj); - assert.equal(obj.tagName.toLowerCase(), 'div'); - assert.equal(obj.className, 'peel'); - assert.equal(obj.children.length, 1); - assert(obj.firstChild); - assert.equal((obj.firstChild).children.length, 0); - assert.equal((obj.firstChild).tagName.toLowerCase(), 'span'); - assert.equal((obj.firstChild).className, 'core'); - }); -}); diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index 390f7f51b9d..1287623d743 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -71,7 +71,7 @@ export abstract class Composite extends Component implements IComposite { * Note: Clients should not call this method, the workbench calls this * method. Calling it otherwise may result in unexpected behavior. * - * Called to create this composite on the provided builder. This method is only + * Called to create this composite on the provided parent. This method is only * called once during the lifetime of the workbench. * Note that DOM-dependent calculations should be performed from the setVisible() * call. Only then the composite will be part of the DOM. diff --git a/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts b/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts index 91ec94b6b3e..3e4a4034a75 100644 --- a/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts +++ b/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts @@ -244,12 +244,14 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi this.isVisible = true; dom.show(this.$el); + dom.removeClass(this.$el, 'debug-toolbar-hidden'); this.setCoordinates(); } private hide(): void { this.isVisible = false; dom.hide(this.$el); + dom.addClass(this.$el, 'debug-toolbar-hidden'); } public static getActions(allActions: AbstractDebugAction[], toDispose: IDisposable[], debugService: IDebugService, keybindingService: IKeybindingService, instantiationService: IInstantiationService): AbstractDebugAction[] { diff --git a/test/smoke/src/areas/debug/debug.ts b/test/smoke/src/areas/debug/debug.ts index 529951db531..798a0b12593 100644 --- a/test/smoke/src/areas/debug/debug.ts +++ b/test/smoke/src/areas/debug/debug.ts @@ -23,7 +23,7 @@ const BREAKPOINT_GLYPH = '.debug-breakpoint'; const PAUSE = `.debug-actions-widget .debug-action.pause`; const DEBUG_STATUS_BAR = `.statusbar.debugging`; const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`; -const TOOLBAR_HIDDEN = `.debug-actions-widget.monaco-builder-hidden`; +const TOOLBAR_HIDDEN = `.debug-actions-widget.debug-toolbar-hidden`; const STACK_FRAME = `${VIEWLET} .monaco-tree-row .stack-frame`; const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title*="${filename}"]`; const VARIABLE = `${VIEWLET} .debug-variables .monaco-tree-row .expression`; -- GitLab