diff --git a/packages/duoyun-ui/src/elements/banner.ts b/packages/duoyun-ui/src/elements/banner.ts index a7bdb879..caceceda 100644 --- a/packages/duoyun-ui/src/elements/banner.ts +++ b/packages/duoyun-ui/src/elements/banner.ts @@ -84,7 +84,7 @@ type Status = 'positive' | 'notice' | 'negative' | 'default'; */ @customElement('dy-banner') @adoptedStyle(style) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'banner' }) export class DuoyunBannerElement extends GemElement { @slot static unnamed: string; diff --git a/packages/duoyun-ui/src/elements/button.ts b/packages/duoyun-ui/src/elements/button.ts index c4e70b5a..1c7dc939 100644 --- a/packages/duoyun-ui/src/elements/button.ts +++ b/packages/duoyun-ui/src/elements/button.ts @@ -140,7 +140,7 @@ const style = createCSSSheet(css` @adoptedStyle(style) @adoptedStyle(focusStyle) @connectStore(icons) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunButtonElement extends GemElement { @slot static unnamed: string; diff --git a/packages/duoyun-ui/src/elements/calendar.ts b/packages/duoyun-ui/src/elements/calendar.ts index ee782659..9189b09b 100644 --- a/packages/duoyun-ui/src/elements/calendar.ts +++ b/packages/duoyun-ui/src/elements/calendar.ts @@ -113,7 +113,7 @@ interface Day { @customElement('dy-calendar') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunCalendarElement extends GemElement { @part static headerRow: string; @part static headerLeftCell: string; diff --git a/packages/duoyun-ui/src/elements/card.ts b/packages/duoyun-ui/src/elements/card.ts index 743e0c69..6c067fcd 100644 --- a/packages/duoyun-ui/src/elements/card.ts +++ b/packages/duoyun-ui/src/elements/card.ts @@ -99,7 +99,7 @@ export type ActionItem = Omit & { handle: (rest: HTML @customElement('dy-card') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'group' }) export class DuoyunCardElement extends DuoyunLoadableBaseElement { @part static preview: string; diff --git a/packages/duoyun-ui/src/elements/carousel.ts b/packages/duoyun-ui/src/elements/carousel.ts index 1b752151..a6ec12fd 100644 --- a/packages/duoyun-ui/src/elements/carousel.ts +++ b/packages/duoyun-ui/src/elements/carousel.ts @@ -151,7 +151,7 @@ type State = { @customElement('dy-carousel') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunCarouselElement extends GemElement { @part static img: string; @part static title: string; diff --git a/packages/duoyun-ui/src/elements/cascader-picker.ts b/packages/duoyun-ui/src/elements/cascader-picker.ts index 87c8ab4a..0febcfbd 100644 --- a/packages/duoyun-ui/src/elements/cascader-picker.ts +++ b/packages/duoyun-ui/src/elements/cascader-picker.ts @@ -8,7 +8,6 @@ import { boolattribute, state, emitter, - shadow, focusable, aria, } from '@mantou/gem/lib/decorators'; @@ -64,7 +63,6 @@ const style = createCSSSheet(css` @adoptedStyle(style) @adoptedStyle(pickerStyle) @adoptedStyle(focusStyle) -@shadow() @focusable() @aria({ role: 'combobox' }) export class DuoyunCascaderPickerElement extends GemElement implements BasePickerElement { diff --git a/packages/duoyun-ui/src/elements/checkbox.ts b/packages/duoyun-ui/src/elements/checkbox.ts index 07a9a6ac..e4e42d17 100644 --- a/packages/duoyun-ui/src/elements/checkbox.ts +++ b/packages/duoyun-ui/src/elements/checkbox.ts @@ -74,7 +74,7 @@ const style = createCSSSheet(css` @customElement('dy-checkbox') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunCheckboxElement extends GemElement { @slot static unnamed: string; @@ -117,7 +117,7 @@ export class DuoyunCheckboxElement extends GemElement { */ @customElement('dy-checkbox-group') @adoptedStyle(groupStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'group' }) export class DuoyunCheckboxGroupElement extends GemElement { @attribute orientation: 'horizontal' | 'vertical'; diff --git a/packages/duoyun-ui/src/elements/collapse.ts b/packages/duoyun-ui/src/elements/collapse.ts index 40a77075..19734ad0 100644 --- a/packages/duoyun-ui/src/elements/collapse.ts +++ b/packages/duoyun-ui/src/elements/collapse.ts @@ -171,7 +171,7 @@ type CollapseItem = { */ @customElement('dy-collapse') @adoptedStyle(style) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'list' }) export class DuoyunCollapseElement extends GemElement { @part static panel: string; diff --git a/packages/duoyun-ui/src/elements/color-picker.ts b/packages/duoyun-ui/src/elements/color-picker.ts index 09e1f6f6..f45d659d 100644 --- a/packages/duoyun-ui/src/elements/color-picker.ts +++ b/packages/duoyun-ui/src/elements/color-picker.ts @@ -64,7 +64,7 @@ const style = createCSSSheet(css` @customElement('dy-color-picker') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunColorPickerElement extends GemElement implements BasePickerElement { @attribute value: HexColor; @boolattribute alpha: boolean; diff --git a/packages/duoyun-ui/src/elements/contextmenu.ts b/packages/duoyun-ui/src/elements/contextmenu.ts index b955f88d..67e60bcd 100644 --- a/packages/duoyun-ui/src/elements/contextmenu.ts +++ b/packages/duoyun-ui/src/elements/contextmenu.ts @@ -119,7 +119,7 @@ const style = createCSSSheet(css` @customElement('dy-contextmenu') @connectStore(contextmenuStore) @adoptedStyle(style) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunContextmenuElement extends GemElement { @refobject optionsRef: RefObject; diff --git a/packages/duoyun-ui/src/elements/copy.ts b/packages/duoyun-ui/src/elements/copy.ts index a0cf75a9..0a22f982 100644 --- a/packages/duoyun-ui/src/elements/copy.ts +++ b/packages/duoyun-ui/src/elements/copy.ts @@ -89,7 +89,7 @@ type State = { @customElement('dy-copy') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunCopyElement extends GemElement { @slot static unnamed: string; @slot static after: string; diff --git a/packages/duoyun-ui/src/elements/date-panel.ts b/packages/duoyun-ui/src/elements/date-panel.ts index c3702411..9873ff13 100644 --- a/packages/duoyun-ui/src/elements/date-panel.ts +++ b/packages/duoyun-ui/src/elements/date-panel.ts @@ -147,7 +147,7 @@ type State = { @customElement('dy-date-panel') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'widget' }) export class DuoyunDatePanelElement extends GemElement { @part static dayCell: string; diff --git a/packages/duoyun-ui/src/elements/file-picker.ts b/packages/duoyun-ui/src/elements/file-picker.ts index 9061831c..aad2fce7 100644 --- a/packages/duoyun-ui/src/elements/file-picker.ts +++ b/packages/duoyun-ui/src/elements/file-picker.ts @@ -122,7 +122,7 @@ export interface FileItem extends File { @customElement('dy-file-picker') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunFilePickerElement extends GemElement implements BasePickerElement { @part static button: string; @part static item: string; diff --git a/packages/duoyun-ui/src/elements/image-preview.ts b/packages/duoyun-ui/src/elements/image-preview.ts index 55ec37c5..a92bceaf 100644 --- a/packages/duoyun-ui/src/elements/image-preview.ts +++ b/packages/duoyun-ui/src/elements/image-preview.ts @@ -80,7 +80,7 @@ export type ImageStatus = 'negative' | 'positive' | 'default'; @customElement('dy-image-preview') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunImagePreviewElement extends GemElement { @attribute status: ImageStatus; /**0-100 */ diff --git a/packages/duoyun-ui/src/elements/input.ts b/packages/duoyun-ui/src/elements/input.ts index 3a666230..313e324e 100644 --- a/packages/duoyun-ui/src/elements/input.ts +++ b/packages/duoyun-ui/src/elements/input.ts @@ -166,7 +166,7 @@ const style = createCSSSheet(css` @customElement('dy-input') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunInputElement extends GemElement { @part static input: string; @part static clear: string; diff --git a/packages/duoyun-ui/src/elements/list.ts b/packages/duoyun-ui/src/elements/list.ts index 51d18309..98f7ef46 100644 --- a/packages/duoyun-ui/src/elements/list.ts +++ b/packages/duoyun-ui/src/elements/list.ts @@ -74,7 +74,7 @@ const styles = createCSSSheet(css` @customElement('dy-list') @adoptedStyle(styles) @adoptedStyle(blockContainer) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'list' }) export class DuoyunListElement extends GemElement { @part static list: string; @@ -594,7 +594,7 @@ const itemStyle = createCSSSheet({ @customElement('dy-list-item') @adoptedStyle(blockContainer) @adoptedStyle(itemStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'listitem' }) export class DuoyunListItemElement extends DuoyunResizeBaseElement implements DuoyunVisibleBaseElement { @emitter show: Emitter; diff --git a/packages/duoyun-ui/src/elements/modal.ts b/packages/duoyun-ui/src/elements/modal.ts index 0310138c..af2fd535 100644 --- a/packages/duoyun-ui/src/elements/modal.ts +++ b/packages/duoyun-ui/src/elements/modal.ts @@ -150,7 +150,7 @@ export interface ModalOpenOptions { @adoptedStyle(style) @adoptedStyle(style2) @connectStore(locale) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunModalElement extends GemElement { @boolattribute open: boolean; @boolattribute customize: boolean; diff --git a/packages/duoyun-ui/src/elements/pagination.ts b/packages/duoyun-ui/src/elements/pagination.ts index f65a97d2..55780724 100644 --- a/packages/duoyun-ui/src/elements/pagination.ts +++ b/packages/duoyun-ui/src/elements/pagination.ts @@ -82,7 +82,7 @@ const style = createCSSSheet(css` @adoptedStyle(style) @adoptedStyle(focusStyle) @connectStore(locale) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'listbox', ariaLabel: 'Pagination' }) export class DuoyunPaginationElement extends GemElement { @attribute align: 'left' | 'start' | 'right' | 'end' | 'center'; diff --git a/packages/duoyun-ui/src/elements/popover.ts b/packages/duoyun-ui/src/elements/popover.ts index cb9bfac3..75f0a7fd 100644 --- a/packages/duoyun-ui/src/elements/popover.ts +++ b/packages/duoyun-ui/src/elements/popover.ts @@ -66,7 +66,7 @@ type CloseCallback = { */ @customElement('dy-popover') @adoptedStyle(contentsContainer) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunPopoverElement extends GemElement { // 用于非继承样式通过 `inherit` 继承 @part static slot: string; diff --git a/packages/duoyun-ui/src/elements/radio.ts b/packages/duoyun-ui/src/elements/radio.ts index d4504755..b7b44d22 100644 --- a/packages/duoyun-ui/src/elements/radio.ts +++ b/packages/duoyun-ui/src/elements/radio.ts @@ -61,7 +61,7 @@ const style = createCSSSheet(css` @customElement('dy-radio') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunRadioElement extends GemElement { @slot static unnamed: string; @@ -125,7 +125,7 @@ export interface Option { */ @customElement('dy-radio-group') @adoptedStyle(groupStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'radiogroup' }) export class DuoyunRadioGroupElement extends GemElement { @attribute orientation: 'horizontal' | 'vertical'; diff --git a/packages/duoyun-ui/src/elements/rate.ts b/packages/duoyun-ui/src/elements/rate.ts index 2b9ace53..01c3da2a 100644 --- a/packages/duoyun-ui/src/elements/rate.ts +++ b/packages/duoyun-ui/src/elements/rate.ts @@ -67,7 +67,7 @@ const style = createCSSSheet(css` @customElement('dy-rate') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'range' }) export class DuoyunRateElement extends GemElement { @part static star: string; diff --git a/packages/duoyun-ui/src/elements/segmented.ts b/packages/duoyun-ui/src/elements/segmented.ts index 7094c063..4a8cd362 100644 --- a/packages/duoyun-ui/src/elements/segmented.ts +++ b/packages/duoyun-ui/src/elements/segmented.ts @@ -111,7 +111,7 @@ export interface SegmentedOption extends Option { */ @customElement('dy-segmented') @adoptedStyle(style) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'group' }) export class DuoyunSegmentedElement extends GemElement { @part static segment: string; diff --git a/packages/duoyun-ui/src/elements/side-navigation.ts b/packages/duoyun-ui/src/elements/side-navigation.ts index 6da3c64f..83e195b2 100644 --- a/packages/duoyun-ui/src/elements/side-navigation.ts +++ b/packages/duoyun-ui/src/elements/side-navigation.ts @@ -139,7 +139,7 @@ type State = Record; @adoptedStyle(style) @adoptedStyle(focusStyle) @connectStore(history.store) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'navigation', ariaLabel: 'Side Navigation' }) export class DuoyunSideNavigationElement extends DuoyunScrollBaseElement { @part static item: string; diff --git a/packages/duoyun-ui/src/elements/switch.ts b/packages/duoyun-ui/src/elements/switch.ts index 381abd73..989eb2a1 100644 --- a/packages/duoyun-ui/src/elements/switch.ts +++ b/packages/duoyun-ui/src/elements/switch.ts @@ -74,7 +74,7 @@ const style = createCSSSheet(css` @customElement('dy-switch') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunSwitchElement extends GemElement { @slot static unnamed: string; diff --git a/packages/duoyun-ui/src/elements/table.ts b/packages/duoyun-ui/src/elements/table.ts index 050475b7..b26564ee 100644 --- a/packages/duoyun-ui/src/elements/table.ts +++ b/packages/duoyun-ui/src/elements/table.ts @@ -156,7 +156,7 @@ export type ItemContextMenuEventDetail = { @adoptedStyle(styles) @adoptedStyle(focusStyle) @connectStore(icons) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunTableElement extends DuoyunScrollBoxElement { @part static table: string; @part static th: string; diff --git a/packages/duoyun-ui/src/elements/tabs.ts b/packages/duoyun-ui/src/elements/tabs.ts index 005d5bc3..cab8469b 100644 --- a/packages/duoyun-ui/src/elements/tabs.ts +++ b/packages/duoyun-ui/src/elements/tabs.ts @@ -118,7 +118,7 @@ export interface TabItem { @customElement('dy-tabs') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'tablist' }) export class DuoyunTabsElement extends GemElement { @part static tabs: string; diff --git a/packages/duoyun-ui/src/elements/tag.ts b/packages/duoyun-ui/src/elements/tag.ts index af16984d..e127d4d3 100644 --- a/packages/duoyun-ui/src/elements/tag.ts +++ b/packages/duoyun-ui/src/elements/tag.ts @@ -60,7 +60,7 @@ export type PresetColor = 'positive' | 'informative' | 'negative' | 'notice' | ' @adoptedStyle(style) @adoptedStyle(focusStyle) @connectStore(icons) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'mark' }) export class DuoyunTagElement extends GemElement { @slot static unnamed: string; diff --git a/packages/duoyun-ui/src/elements/time-panel.ts b/packages/duoyun-ui/src/elements/time-panel.ts index c2080b7f..8b5a6fce 100644 --- a/packages/duoyun-ui/src/elements/time-panel.ts +++ b/packages/duoyun-ui/src/elements/time-panel.ts @@ -58,7 +58,7 @@ const style = createCSSSheet(css` @customElement('dy-time-panel') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) export class DuoyunTimePanelElement extends GemElement { @boolattribute headless: boolean; @globalemitter change: Emitter; diff --git a/packages/duoyun-ui/src/elements/tree.ts b/packages/duoyun-ui/src/elements/tree.ts index bcbcc73f..efdc292f 100644 --- a/packages/duoyun-ui/src/elements/tree.ts +++ b/packages/duoyun-ui/src/elements/tree.ts @@ -156,7 +156,7 @@ export type MouseEventDetail = { value: any; item: TreeItem; originEvent: MouseE @customElement('dy-tree') @adoptedStyle(style) @adoptedStyle(focusStyle) -@shadow() +@shadow({ delegatesFocus: true }) @aria({ role: 'tree' }) export class DuoyunTreeElement extends GemElement { @part static item: string; diff --git a/packages/gem-book/src/bin/builder.ts b/packages/gem-book/src/bin/builder.ts index dd701acf..4d7817d5 100644 --- a/packages/gem-book/src/bin/builder.ts +++ b/packages/gem-book/src/bin/builder.ts @@ -89,7 +89,7 @@ function getPluginRecord(pluginList: string[]) { const [base, ...rest] = plugin.split(/(\?)/); const search = rest.join(''); const pluginPath = resolveLocalPlugin(base); - if (!pluginPath) return [plugin, { name: plugin, url: 'file:' + plugin }]; + if (!pluginPath) return [plugin, { name: plugin, url: 'gbp:' + plugin }]; if (pluginPath.custom) { const filename = path.basename(pluginPath.custom); const uniqueFilename = filename + Date.now(); @@ -97,9 +97,9 @@ function getPluginRecord(pluginList: string[]) { symlinkSync(pluginPath.custom, path.resolve(pluginDir, uniqueFilename)); // 替换内置文件 renameSync(path.resolve(pluginDir, uniqueFilename), symLinkPath); - return [pluginPath.custom, { name: filename, url: 'file:' + filename + search }]; + return [pluginPath.custom, { name: filename, url: 'gbp:' + filename + search }]; } - return [pluginPath.builtIn!, { name: base, url: 'file:' + base + search }]; + return [pluginPath.builtIn!, { name: base, url: 'gbp:' + base + search }]; }), ); } diff --git a/packages/gem-book/src/bin/index.ts b/packages/gem-book/src/bin/index.ts index 9bd9ca7d..f72f0747 100644 --- a/packages/gem-book/src/bin/index.ts +++ b/packages/gem-book/src/bin/index.ts @@ -158,7 +158,7 @@ function readFiles(filenames: string[], docsRootDir: string, dir: string, link: features, }; if (redirect) { - (bookConfig.redirects ||= {})[item.link] = new URL(redirect, `file:${item.link}`).pathname; + (bookConfig.redirects ||= {})[item.link] = new URL(redirect, `gbp:${item.link}`).pathname; } else { result.push(item); } @@ -170,7 +170,7 @@ function readFiles(filenames: string[], docsRootDir: string, dir: string, link: const newLink = path.join(link, filename) + '/'; if (redirect) { const pattern = `${newLink}*`; - const redirectPath = new URL(redirect, `file:${pattern}`).pathname; + const redirectPath = new URL(redirect, `gbp:${pattern}`).pathname; (bookConfig.redirects ||= {})[pattern] = `${redirectPath}${redirectPath.endsWith('/') ? ':0' : ''}`; } else { const subFilenameSet = new Set([...readdirSync(fullPath)]); diff --git a/packages/gem-book/src/element/elements/edit-link.ts b/packages/gem-book/src/element/elements/edit-link.ts index aba8cff6..0766d85f 100644 --- a/packages/gem-book/src/element/elements/edit-link.ts +++ b/packages/gem-book/src/element/elements/edit-link.ts @@ -85,7 +85,7 @@ export class EditLink extends GemElement { height: 18px; margin-right: 10px; } - .last-updated span { + .last-updated gem-link { opacity: 0.5; } @media ${mediaQuery.PHONE} { @@ -95,15 +95,15 @@ export class EditLink extends GemElement { } } - + ${selfI18n.get('editOnGithub')} ${lastUpdated && html`
- ${selfI18n.get('lastUpdated')}: - ${lastUpdated} + ${selfI18n.get('lastUpdated')}: + ${lastUpdated}
`} `; diff --git a/packages/gem/src/lib/decorators.ts b/packages/gem/src/lib/decorators.ts index 4ddca511..cce36299 100644 --- a/packages/gem/src/lib/decorators.ts +++ b/packages/gem/src/lib/decorators.ts @@ -451,7 +451,7 @@ export function rootElement(rootType: string) { export function shadow({ mode = 'open', serializable = true, - delegatesFocus = true, + delegatesFocus, slotAssignment, }: Partial & { mode?: null | ShadowRootMode }> = {}) { return function (_: any, context: ClassDecoratorContext) { @@ -491,8 +491,10 @@ export function aria(info: Partial) { * ``` */ export function customElement(name: string) { - return function (cls: new (...args: any) => any, _: ClassDecoratorContext) { - customElements.define(name, cls); + return function (cls: new (...args: any) => any, { addInitializer }: ClassDecoratorContext) { + addInitializer(function () { + customElements.define(name, cls); + }); }; } diff --git a/packages/gem/src/lib/element.ts b/packages/gem/src/lib/element.ts index df14f473..b87b6c0d 100644 --- a/packages/gem/src/lib/element.ts +++ b/packages/gem/src/lib/element.ts @@ -168,8 +168,7 @@ export abstract class GemElement> extends HTMLElemen } get #metadata(): Metadata { - // BUG? 为啥会是空 - return (this.constructor as any)[Symbol.metadata] || {}; + return (this.constructor as any)[Symbol.metadata]; } get internals() { diff --git a/packages/gem/src/test/gem-element/basic.test.ts b/packages/gem/src/test/gem-element/basic.test.ts index 2515f18c..ef4dfcc5 100644 --- a/packages/gem/src/test/gem-element/basic.test.ts +++ b/packages/gem/src/test/gem-element/basic.test.ts @@ -44,18 +44,17 @@ class GemDemo extends GemElement { } } -class DeferGemElement extends GemElement { - @attribute attr: string; - @property prop: { value: string }; -} - describe('基本 gem element 测试', () => { it('后定义元素', async () => { const el: DeferGemElement = await fixture(html` `); expect(el.prop.value).to.equal('prop'); - customElements.define('defer-gem-demo', DeferGemElement); + @customElement('defer-gem-demo') + class DeferGemElement extends GemElement { + @attribute attr: string; + @property prop: { value: string }; + } await nextFrame(); expect(el.prop.value).to.equal('prop'); expect(el.attr).to.equal('attr');