Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
19dea473
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
19dea473
编写于
9月 04, 2018
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
🎉
debt - remove builder
🎉
上级
55d89a74
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
4 addition
and
2762 deletion
+4
-2762
src/vs/base/browser/builder.css
src/vs/base/browser/builder.css
+0
-8
src/vs/base/browser/builder.ts
src/vs/base/browser/builder.ts
+0
-1428
src/vs/base/browser/dom.ts
src/vs/base/browser/dom.ts
+0
-1
src/vs/base/test/browser/builder.test.ts
src/vs/base/test/browser/builder.test.ts
+0
-1323
src/vs/workbench/browser/composite.ts
src/vs/workbench/browser/composite.ts
+1
-1
src/vs/workbench/parts/debug/browser/debugActionsWidget.ts
src/vs/workbench/parts/debug/browser/debugActionsWidget.ts
+2
-0
test/smoke/src/areas/debug/debug.ts
test/smoke/src/areas/debug/debug.ts
+1
-1
未找到文件。
src/vs/base/browser/builder.css
已删除
100644 → 0
浏览文件 @
55d89a74
/*---------------------------------------------------------------------------------------------
* 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
src/vs/base/browser/builder.ts
已删除
100644 → 0
浏览文件 @
55d89a74
/*---------------------------------------------------------------------------------------------
* 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
=
(
<
Builder
>
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
=
<
HTMLElement
>
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
=
(
<
Builder
>
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
=
<
HTMLElement
>
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
'
);
(
<
Builder
>
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
<
E
extends
Event
=
Event
>
(
type
:
string
,
fn
:
(
e
:
E
,
builder
:
Builder
,
unbind
:
IDisposable
)
=>
void
,
listenerToDisposeContainer
?:
IDisposable
[],
useCapture
?:
boolean
):
Builder
;
on
<
E
extends
Event
=
Event
>
(
typeArray
:
string
[],
fn
:
(
e
:
E
,
builder
:
Builder
,
unbind
:
IDisposable
)
=>
void
,
listenerToDisposeContainer
?:
IDisposable
[],
useCapture
?:
boolean
):
Builder
;
on
<
E
extends
Event
=
Event
>
(
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
<
E
extends
Event
=
Event
>
(
type
:
string
,
fn
:
(
e
:
E
,
builder
:
Builder
,
unbind
:
IDisposable
)
=>
void
,
listenerToDisposeContainer
?:
IDisposable
[],
useCapture
?:
boolean
):
Builder
;
once
<
E
extends
Event
=
Event
>
(
typesArray
:
string
[],
fn
:
(
e
:
E
,
builder
:
Builder
,
unbind
:
IDisposable
)
=>
void
,
listenerToDisposeContainer
?:
IDisposable
[],
useCapture
?:
boolean
):
Builder
;
once
<
E
extends
Event
=
Event
>
(
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
((
<
any
>
this
)[
prop
])
{
if
(
types
.
isArray
(
value
))
{
(
<
any
>
this
)[
prop
].
apply
(
this
,
value
);
}
else
{
(
<
any
>
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
(
<
HTMLElement
>
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
(
<
HTMLElement
>
element
))
{
// Listeners
let
listeners
:
IDisposable
[]
=
data
(
<
HTMLElement
>
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
(
<
HTMLElement
>
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
<
(
<
MultiBuilder
>
builders
).
length
;
i
++
)
{
this
.
push
((
<
MultiBuilder
>
builders
).
item
(
i
));
}
}
// Mixin Builder functions to operate on all builders
let
$outer
=
this
;
let
propertyFn
=
(
prop
:
string
)
=>
{
(
<
any
>
$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
=
(
<
any
>
$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
<
(
<
MultiBuilder
>
res
).
length
;
j
++
)
{
returnValues
.
push
((
<
MultiBuilder
>
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
((
<
any
>
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
((
<
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
((
<
Builder
>
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
(
<
HTMLElement
>
element
);
}
let
builders
:
Builder
[]
=
[];
while
(
container
.
firstChild
)
{
element
=
container
.
firstChild
;
container
.
removeChild
(
element
);
builders
.
push
(
_withElement
(
<
HTMLElement
>
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 $
'
);
}
};
src/vs/base/browser/dom.ts
浏览文件 @
19dea473
...
...
@@ -970,7 +970,6 @@ export function prepend<T extends Node>(parent: HTMLElement, child: T): T {
const
SELECTOR_REGEX
=
/
([\w\-]
+
)?(
#
([\w\-]
+
))?((
.
([\w\-]
+
))
*
)
/
;
// Similar to builder, but much more lightweight
export
function
$
<
T
extends
HTMLElement
>
(
description
:
string
,
attrs
?:
{
[
key
:
string
]:
any
;
},
...
children
:
(
Node
|
string
)[]):
T
{
let
match
=
SELECTOR_REGEX
.
exec
(
description
);
...
...
src/vs/base/test/browser/builder.test.ts
已删除
100644 → 0
浏览文件 @
55d89a74
/*---------------------------------------------------------------------------------------------
* 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
(
<
HTMLElement
>
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
(
<
HTMLElement
>
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
=
<
HTMLElement
>
li
.
childNodes
[
0
];
assert
.
strictEqual
(
'
span
'
,
span
.
nodeName
.
toLowerCase
());
assert
.
strictEqual
(
span
.
childNodes
.
length
,
1
);
assert
.
strictEqual
(
span
.
innerHTML
,
'
Foo Bar
'
);
let
img
=
<
HTMLElement
>
li
.
childNodes
[
1
];
assert
.
strictEqual
(
'
img
'
,
img
.
nodeName
.
toLowerCase
());
assert
.
strictEqual
(
img
.
childNodes
.
length
,
0
);
assert
.
strictEqual
(
img
.
getAttribute
(
'
src
'
),
'
#
'
);
let
a
=
<
HTMLElement
>
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
(
'
<b>Foo Bar</b>
'
);
assert
.
strictEqual
(
b
.
getHTMLElement
().
innerHTML
,
'
<b>Foo Bar</b>
'
);
});
test
(
'
Builder.safeInnerHtml()
'
,
function
()
{
let
b
=
Build
.
withElementById
(
fixtureId
);
b
.
div
();
b
.
safeInnerHtml
(
'
<b>Foo Bar</b>
'
);
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
=
$
(
'
<a class="a1">Hello</a>
'
);
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
=
<
MultiBuilder
>
$
(
'
<a class="a1">Hello</a><a class="a2">There</a>
'
);
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
=
<
MultiBuilder
>
(
<
any
>
$
)(
'
<a class="{0}">{1}</a><a class="{2}">{3}</a>
'
,
'
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
()
{
$
(
<
any
>
123
);
});
});
test
(
'
$ - appendTo, append
'
,
function
()
{
let
peel
=
$
(
'
<div class="peel"></div>
'
);
let
core
=
$
(
'
<span class="core"></span>
'
).
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
((
<
HTMLElement
>
obj
.
firstChild
).
children
.
length
,
0
);
assert
.
equal
((
<
HTMLElement
>
obj
.
firstChild
).
tagName
.
toLowerCase
(),
'
span
'
);
assert
.
equal
((
<
HTMLElement
>
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
=
$
(
'
<div class="peel"></div>
'
).
append
(
$
(
'
<span class="core"></span>
'
));
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
((
<
HTMLElement
>
obj
.
firstChild
).
children
.
length
,
0
);
assert
.
equal
((
<
HTMLElement
>
obj
.
firstChild
).
tagName
.
toLowerCase
(),
'
span
'
);
assert
.
equal
((
<
HTMLElement
>
obj
.
firstChild
).
className
,
'
core
'
);
});
});
src/vs/workbench/browser/composite.ts
浏览文件 @
19dea473
...
...
@@ -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.
...
...
src/vs/workbench/parts/debug/browser/debugActionsWidget.ts
浏览文件 @
19dea473
...
...
@@ -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
[]
{
...
...
test/smoke/src/areas/debug/debug.ts
浏览文件 @
19dea473
...
...
@@ -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-builde
r-hidden`
;
const
TOOLBAR_HIDDEN
=
`.debug-actions-widget.
debug-toolba
r-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`
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录