KISSY.add("overlay/control", ["component/container", "component/extension/shim", "component/extension/align", "./extension/loading", "./extension/mask", "./extension/overlay-effect", "component/extension/content-box", "./overlay-xtpl"], function(S, require) { var Container = require("component/container"); var Shim = require("component/extension/shim"); var AlignExtension = require("component/extension/align"); var Loading = require("./extension/loading"); var Mask = require("./extension/mask"); var OverlayEffect = require("./extension/overlay-effect"); var ContentBox = require("component/extension/content-box"); var OverlayTpl = require("./overlay-xtpl"); var HIDE = "hide", actions = {hide:HIDE, destroy:"destroy"}; return Container.extend([ContentBox, Shim, Loading, AlignExtension, Mask, OverlayEffect], {bindUI:function() { var self = this, closeBtn = self.get("closeBtn"); if(closeBtn) { closeBtn.on("click", function(ev) { self.close(); ev.preventDefault() }) } }, close:function() { var self = this; self[actions[self.get("closeAction")] || HIDE](); return self }}, {ATTRS:{contentEl:{}, closable:{value:false, sync:0, render:1, parse:function() { return!!this.get("closeBtn") }}, closeBtn:{selector:function() { return"." + this.getBaseCssClass("close") }}, closeAction:{value:HIDE}, focusable:{value:false}, allowTextSelection:{value:true}, handleGestureEvents:{value:false}, visible:{value:false}, contentTpl:{value:OverlayTpl}}, xclass:"overlay"}) });
KISSY.add(function(S, require) { _$jscoverage['/split-button.js'].functionData[0]++; _$jscoverage['/split-button.js'].lineData[7]++; var Container = require('component/container'); _$jscoverage['/split-button.js'].lineData[8]++; require('button'); _$jscoverage['/split-button.js'].lineData[9]++; require('menubutton'); _$jscoverage['/split-button.js'].lineData[15]++; return Container.extend({ renderUI: function() { _$jscoverage['/split-button.js'].functionData[1]++; _$jscoverage['/split-button.js'].lineData[17]++; var self = this, alignWithEl = self.get("alignWithEl"), menuButton = self.get("children")[1], menu = menuButton.get("menu"); _$jscoverage['/split-button.js'].lineData[21]++; if (visit1_21_1(alignWithEl)) { _$jscoverage['/split-button.js'].lineData[22]++; menu.get("align").node = self.$el; } }}, { ATTRS: { handleMouseEvents: { value: false}, focusable: { value: false}, alignWithEl: { value: true}, children: { value: [{ xclass: 'button'}, { xclass: 'menu-button'}]}, menuButton: { getter: function() { _$jscoverage['/split-button.js'].functionData[2]++; _$jscoverage['/split-button.js'].lineData[69]++; return this.get('children')[1]; }, setter: function(v) { _$jscoverage['/split-button.js'].functionData[3]++; _$jscoverage['/split-button.js'].lineData[72]++; this.get('children')[1] = v; }}, button: { getter: function() { _$jscoverage['/split-button.js'].functionData[4]++; _$jscoverage['/split-button.js'].lineData[91]++; return this.get('children')[0]; }, setter: function(v) { _$jscoverage['/split-button.js'].functionData[5]++; _$jscoverage['/split-button.js'].lineData[94]++; this.get('children')[0] = v; }}}, xclass: 'split-button'}); });
KISSY.add('tabs/panel', ['component/container'], function (S, require, exports, module) { /** * @ignore * single tab panel. * @author yiminghe@gmail.com */ var Container = require('component/container'); /** * KISSY.Tabs.Panel.xclass: 'tabs-panel'. * @class KISSY.Tabs.Panel * @extends KISSY.Component.Container */ /** * KISSY.Tabs.Panel.xclass: 'tabs-panel'. * @class KISSY.Tabs.Panel * @extends KISSY.Component.Container */ module.exports = Container.extend({ isTabsPanel: 1, beforeCreateDom: function (renderData) { var self = this; renderData.elAttrs.role = 'tabpanel'; if (renderData.selected) { renderData.elCls.push(self.getBaseCssClasses('selected')); } else { renderData.elAttrs['aria-hidden'] = false; } }, _onSetSelected: function (v) { var el = this.$el; var selectedCls = this.getBaseCssClasses('selected'); el[v ? 'addClass' : 'removeClass'](selectedCls).attr('aria-hidden', !v); } }, { ATTRS: { allowTextSelection: { value: true }, focusable: { value: false }, handleGestureEvents: { value: false }, /** * whether selected * @cfg {Boolean} selected */ /** * @ignore */ selected: { render: 1, sync: 0, parse: function (el) { return el.hasClass(this.getBaseCssClass('selected')); } } }, xclass: 'tabs-panel' }); });
it('allows the Container constructor to be configurable within subclasses', function() { var Container = require('Component/Container'), TestContainer = Container.extend(), Foo = InfiniteContainer.extend({ Container: TestContainer }), foo = new Foo(), $bar = affix('div'); foo.of(Controller).at($bar).bind(model); expect(foo._container instanceof TestContainer).toBeTruthy(); });
KISSY.add(function(S, require) { _$jscoverage['/tabs/panel.js'].functionData[0]++; _$jscoverage['/tabs/panel.js'].lineData[7]++; var Container = require('component/container'); _$jscoverage['/tabs/panel.js'].lineData[13]++; return Container.extend({ isTabsPanel: 1, beforeCreateDom: function(renderData) { _$jscoverage['/tabs/panel.js'].functionData[1]++; _$jscoverage['/tabs/panel.js'].lineData[17]++; var self = this; _$jscoverage['/tabs/panel.js'].lineData[18]++; renderData.elAttrs.role = 'tabpanel'; _$jscoverage['/tabs/panel.js'].lineData[19]++; if (visit12_19_1(renderData.selected)) { _$jscoverage['/tabs/panel.js'].lineData[20]++; renderData.elCls.push(self.getBaseCssClasses('selected')); } else { _$jscoverage['/tabs/panel.js'].lineData[22]++; renderData.elAttrs['aria-hidden'] = false; } }, _onSetSelected: function(v) { _$jscoverage['/tabs/panel.js'].functionData[2]++; _$jscoverage['/tabs/panel.js'].lineData[27]++; var el = this.$el; _$jscoverage['/tabs/panel.js'].lineData[28]++; var selectedCls = this.getBaseCssClasses('selected'); _$jscoverage['/tabs/panel.js'].lineData[30]++; el[v ? 'addClass' : 'removeClass'](selectedCls).attr('aria-hidden', !v); }}, { ATTRS: { selected: { render: 1, sync: 0, parse: function(el) { _$jscoverage['/tabs/panel.js'].functionData[3]++; _$jscoverage['/tabs/panel.js'].lineData[45]++; return el.hasClass(this.getBaseCssClass('selected')); }}, focusable: { value: false}, allowTextSelection: { value: true}}, xclass: 'tabs-panel'}); });
KISSY.add("tabs/body", ["component/container"], function(S, require) { var Container = require("component/container"); var TabBody = Container.extend({bindUI:function() { var self = this; self.on("afterSelectedPanelIndexChange", function(e) { var children = self.get("children"), newIndex = e.newVal, hidePanel; if(children[newIndex]) { if(hidePanel = children[e.prevVal]) { hidePanel.set("selected", false) } self.selectPanelByIndex(newIndex) } }) }, syncUI:function() { var self = this, children = self.get("children"); S.each(children, function(c, i) { if(c.get("selected")) { self.set("selectedPanelIndex", i); return false } return undefined }) }, createChild:function(index) { return checkLazy(this, "createChild", index) }, renderChild:function(index) { return checkLazy(this, "renderChild", index) }, selectPanelByIndex:function(newIndex) { this.get("children")[newIndex].set("selected", true); if(this.get("lazyRender")) { this.renderChild(newIndex) } }}, {ATTRS:{selectedPanelIndex:{}, allowTextSelection:{value:true}, focusable:{value:false}, lazyRender:{}, handleMouseEvents:{value:false}, defaultChildCfg:{value:{xclass:"tabs-panel"}}}, xclass:"tabs-body"}); function checkLazy(self, method, index) { if(self.get("lazyRender")) { var c = self.get("children")[index]; if(!c.get("selected")) { return c } } return TabBody.superclass[method].call(self, index) } return TabBody });
KISSY.add("split-button", ["component/container", "button", "menubutton"], function(S, require) { var Container = require("component/container"); require("button"); require("menubutton"); return Container.extend({renderUI:function() { var self = this, alignWithEl = self.get("alignWithEl"), menuButton = self.get("children")[1], menu = menuButton.get("menu"); if(alignWithEl) { menu.get("align").node = self.$el } }}, {ATTRS:{handleMouseEvents:{value:false}, focusable:{value:false}, alignWithEl:{value:true}, children:{value:[{xclass:"button"}, {xclass:"menu-button"}]}, menuButton:{getter:function() { return this.get("children")[1] }, setter:function(v) { this.get("children")[1] = v }}, button:{getter:function() { return this.get("children")[0] }, setter:function(v) { this.get("children")[0] = v }}}, xclass:"split-button"}) });
KISSY.add("overlay/control", ["component/container", "component/extension/shim", "component/extension/align", "./extension/loading", "./extension/mask", "./overlay-render", "./extension/overlay-effect"], function(S, require) { var Container = require("component/container"); var Shim = require("component/extension/shim"); var AlignExtension = require("component/extension/align"); var Loading = require("./extension/loading"); var Mask = require("./extension/mask"); var OverlayRender = require("./overlay-render"); var OverlayEffect = require("./extension/overlay-effect"); var HIDE = "hide", actions = {hide:HIDE, destroy:"destroy"}; return Container.extend([Shim, Loading, AlignExtension, Mask, OverlayEffect], {bindUI:function() { var self = this, closeBtn = self.get("closeBtn"); if(closeBtn) { closeBtn.on("click", function(ev) { self.close(); ev.preventDefault() }) } }, close:function() { var self = this; self[actions[self.get("closeAction")] || HIDE](); return self }}, {ATTRS:{contentEl:{}, closable:{value:false, view:1}, closeBtn:{view:1}, closeAction:{value:HIDE}, focusable:{value:false}, allowTextSelection:{value:true}, handleMouseEvents:{value:false}, visible:{value:false}, xrender:{value:OverlayRender}}, xclass:"overlay"}) });
KISSY.add("tabs", ["component/container", "tabs/bar", "tabs/body", "tabs/tab", "tabs/panel", "tabs/render"], function(S, require) { var Container = require("component/container"); var Bar = require("tabs/bar"); var Body = require("tabs/body"); require("tabs/tab"); var Panel = require("tabs/panel"); var Render = require("tabs/render"); function setBar(children, barOrientation, bar) { children[BarIndexMap[barOrientation]] = bar } function setBody(children, barOrientation, body) { children[1 - BarIndexMap[barOrientation]] = body } var Tabs = Container.extend({initializer:function() { var self = this, items = self.get("items"); if(items) { var children = self.get("children"), barOrientation = self.get("barOrientation"), selected, prefixCls = self.get("prefixCls"), tabItem, panelItem, bar = {prefixCls:prefixCls, xclass:"tabs-bar", changeType:self.get("changeType"), children:[]}, body = {prefixCls:prefixCls, xclass:"tabs-body", lazyRender:self.get("lazyRender"), children:[]}, barChildren = bar.children, panels = body.children; S.each(items, function(item) { selected = selected || item.selected; barChildren.push(tabItem = {content:item.title, selected:item.selected}); panels.push(panelItem = {content:item.content, selected:item.selected}) }); if(!selected && barChildren.length) { barChildren[0].selected = true; panels[0].selected = true } setBar(children, barOrientation, bar); setBody(children, barOrientation, body) } }, addItem:function(item, index) { var self = this, bar = self.get("bar"), selectedTab, tabItem, panelItem, barChildren = bar.get("children"), body = self.get("body"); if(typeof index === "undefined") { index = barChildren.length } tabItem = {content:item.title}; panelItem = {content:item.content}; bar.addChild(tabItem, index); selectedTab = barChildren[index]; body.addChild(panelItem, index); if(item.selected) { bar.set("selectedTab", selectedTab); body.set("selectedPanelIndex", index) } return self }, removeItemAt:function(index, destroy) { var tabs = this, bar = tabs.get("bar"), barCs = bar.get("children"), tab = bar.getChildAt(index), body = tabs.get("body"); if(tab.get("selected")) { if(barCs.length === 1) { bar.set("selectedTab", null) }else { if(index === 0) { bar.set("selectedTab", bar.getChildAt(index + 1)) }else { bar.set("selectedTab", bar.getChildAt(index - 1)) } } } bar.removeChild(bar.getChildAt(index), destroy); body.removeChild(body.getChildAt(index), destroy); return tabs }, removeItemByTab:function(tab, destroy) { var index = S.indexOf(tab, this.get("bar").get("children")); return this.removeItemAt(index, destroy) }, removeItemByPanel:function(panel, destroy) { var index = S.indexOf(panel, this.get("body").get("children")); return this.removeItemAt(index, destroy) }, getSelectedTab:function() { var tabs = this, bar = tabs.get("bar"), child = null; S.each(bar.get("children"), function(c) { if(c.get("selected")) { child = c; return false } return undefined }); return child }, getSelectedPanel:function() { var tabs = this, body = tabs.get("body"), child = null; S.each(body.get("children"), function(c) { if(c.get("selected")) { child = c; return false } return undefined }); return child }, getTabs:function() { return this.get("bar").get("children") }, getPanels:function() { return this.get("body").get("children") }, getTabAt:function(index) { return this.get("bar").get("children")[index] }, getPanelAt:function(index) { return this.get("body").get("children")[index] }, setSelectedTab:function(tab) { var tabs = this, bar = tabs.get("bar"), body = tabs.get("body"); bar.set("selectedTab", tab); body.set("selectedPanelIndex", S.indexOf(tab, bar.get("children"))); return this }, setSelectedPanel:function(panel) { var tabs = this, bar = tabs.get("bar"), body = tabs.get("body"), selectedPanelIndex = S.indexOf(panel, body.get("children")); body.set("selectedPanelIndex", selectedPanelIndex); bar.set("selectedTab", tabs.getTabAt(selectedPanelIndex)); return this }, bindUI:function() { this.on("afterSelectedTabChange", function(e) { this.setSelectedTab(e.newVal) }) }}, {ATTRS:{items:{}, changeType:{}, lazyRender:{value:false}, handleMouseEvents:{value:false}, allowTextSelection:{value:true}, focusable:{value:false}, bar:{getter:function() { return this.get("children")[BarIndexMap[this.get("barOrientation")]] }}, body:{getter:function() { return this.get("children")[1 - BarIndexMap[this.get("barOrientation")]] }}, barOrientation:{view:1, value:"top"}, xrender:{value:Render}}, xclass:"tabs"}); Tabs.Orientation = {TOP:"top", BOTTOM:"bottom", LEFT:"left", RIGHT:"right"}; var BarIndexMap = {top:0, left:0, bottom:1, right:0}; Tabs.ChangeType = Bar.ChangeType; Tabs.Bar = Bar; Tabs.Body = Body; Tabs.Panel = Panel; return Tabs });
KISSY.add("tabs/panel", ["component/container", "./panel-render"], function(S, require) { var Container = require("component/container"); var PanelRender = require("./panel-render"); return Container.extend({isTabsPanel:1}, {ATTRS:{selected:{view:1}, focusable:{value:false}, allowTextSelection:{value:true}, xrender:{value:PanelRender}}, xclass:"tabs-panel"}) });
KISSY.add(function(S, require) { _$jscoverage['/overlay/control.js'].functionData[0]++; _$jscoverage['/overlay/control.js'].lineData[7]++; var Container = require('component/container'); _$jscoverage['/overlay/control.js'].lineData[8]++; var Shim = require('component/extension/shim'); _$jscoverage['/overlay/control.js'].lineData[9]++; var AlignExtension = require('component/extension/align'); _$jscoverage['/overlay/control.js'].lineData[10]++; var Loading = require('./extension/loading'); _$jscoverage['/overlay/control.js'].lineData[11]++; var Mask = require('./extension/mask'); _$jscoverage['/overlay/control.js'].lineData[12]++; var OverlayEffect = require('./extension/overlay-effect'); _$jscoverage['/overlay/control.js'].lineData[13]++; var ContentBox = require('component/extension/content-box'); _$jscoverage['/overlay/control.js'].lineData[14]++; var OverlayTpl = require('./overlay-xtpl'); _$jscoverage['/overlay/control.js'].lineData[15]++; var HIDE = 'hide', actions = { hide: HIDE, destroy: 'destroy'}; _$jscoverage['/overlay/control.js'].lineData[31]++; return Container.extend([ContentBox, Shim, Loading, AlignExtension, Mask, OverlayEffect], { bindUI: function() { _$jscoverage['/overlay/control.js'].functionData[1]++; _$jscoverage['/overlay/control.js'].lineData[40]++; var self = this, closeBtn = self.get('closeBtn'); _$jscoverage['/overlay/control.js'].lineData[42]++; if (visit1_42_1(closeBtn)) { _$jscoverage['/overlay/control.js'].lineData[43]++; closeBtn.on('click', function(ev) { _$jscoverage['/overlay/control.js'].functionData[2]++; _$jscoverage['/overlay/control.js'].lineData[44]++; self.close(); _$jscoverage['/overlay/control.js'].lineData[45]++; ev.preventDefault(); }); } }, close: function() { _$jscoverage['/overlay/control.js'].functionData[3]++; _$jscoverage['/overlay/control.js'].lineData[54]++; var self = this; _$jscoverage['/overlay/control.js'].lineData[55]++; self[visit2_55_1(actions[self.get('closeAction')] || HIDE)](); _$jscoverage['/overlay/control.js'].lineData[56]++; return self; }}, { ATTRS: { contentEl: {}, closable: { value: false, sync: 0, render: 1, parse: function() { _$jscoverage['/overlay/control.js'].functionData[4]++; _$jscoverage['/overlay/control.js'].lineData[83]++; return !!this.get('closeBtn'); }}, closeBtn: { selector: function() { _$jscoverage['/overlay/control.js'].functionData[5]++; _$jscoverage['/overlay/control.js'].lineData[98]++; return '.' + this.getBaseCssClass('close'); }}, closeAction: { value: HIDE}, focusable: { value: false}, allowTextSelection: { value: true}, handleGestureEvents: { value: false}, visible: { value: false}, contentTpl: { value: OverlayTpl}}, xclass: 'overlay'}); });
KISSY.add(function (S, require) { var Container = require('component/container'); var Shim = require('component/extension/shim'); var AlignExtension = require('component/extension/align'); var Loading = require('./extension/loading'); var Mask = require('./extension/mask'); var OverlayRender = require('./overlay-render'); var OverlayEffect = require('./extension/overlay-effect'); var HIDE = 'hide', actions = { hide: HIDE, destroy: 'destroy' }; /** * KISSY Overlay Component. * xclass: 'overlay'. * @class KISSY.Overlay * @extends KISSY.Component.Container * @mixins KISSY.Component.Extension.Shim * @mixins KISSY.Overlay.Extension.Effect * @mixins KISSY.Overlay.Extension.Loading * @mixins KISSY.Component.Extension.Align * @mixins KISSY.Overlay.Extension.Mask */ return Container.extend([ Shim, Loading, AlignExtension, Mask, OverlayEffect ], { bindUI: function () { var self = this, closeBtn = self.get('closeBtn'); if (closeBtn) { closeBtn.on('click', function (ev) { self.close(); ev.preventDefault(); }); } }, /** * hide or destroy according to {@link KISSY.Overlay#closeAction} * @chainable */ close: function () { var self = this; self[actions[self.get('closeAction')] || HIDE](); return self; } }, { ATTRS: { contentEl: { }, /** * Whether close button is visible. * * Defaults to: true. * * @cfg {Boolean} closable */ /** * Whether close button is visible. * @type {Boolean} * @property closable */ /** * @ignore */ closable: { value: false, view: 1 }, /** * close button element. * @type {KISSY.NodeList} * @property closeBtn * @readonly */ /** * @ignore */ closeBtn: { view: 1 }, /** * Whether to destroy or hide current element when click close button. * Can set 'destroy' to destroy it when click close button. * * Defaults to: 'hide'. * * @cfg {String} closeAction */ /** * @ignore */ closeAction: { value: HIDE }, /** * overlay can not have focus. * * Defaults to: false. * * @cfg {Boolean} focusable * @protected */ /** * @ignore */ focusable: { value: false }, /** * overlay can have text selection. * * Defaults to: true. * * @cfg {Boolean} allowTextSelection * @protected */ /** * @ignore */ allowTextSelection: { value: true }, /** * whether this component can be responsive to mouse. * * Defaults to: false * * @cfg {Boolean} handleMouseEvents * @protected */ /** * @ignore */ handleMouseEvents: { value: false }, visible: { value: false }, xrender: { value: OverlayRender } }, xclass: 'overlay' }); });
KISSY.add("scroll-view/base", ["node", "anim", "component/container", "./base/render"], function(S, require) { var Node = require("node"); var Anim = require("anim"); var Container = require("component/container"); var Render = require("./base/render"); var $ = S.all, KeyCode = Node.KeyCode; function onElScroll() { var self = this, el = self.el, scrollTop = el.scrollTop, scrollLeft = el.scrollLeft; if(scrollTop) { self.set("scrollTop", scrollTop + self.get("scrollTop")) } if(scrollLeft) { self.set("scrollLeft", scrollLeft + self.get("scrollLeft")) } el.scrollTop = el.scrollLeft = 0 } function frame(anim, fx) { anim.scrollView.set(fx.prop, fx.val) } function reflow(v) { var control = this, $contentEl = control.$contentEl; var scrollHeight = v.scrollHeight, scrollWidth = v.scrollWidth; var clientHeight = v.clientHeight, allowScroll, clientWidth = v.clientWidth; control.scrollHeight = scrollHeight; control.scrollWidth = scrollWidth; control.clientHeight = clientHeight; control.clientWidth = clientWidth; allowScroll = control.allowScroll = {}; if(scrollHeight > clientHeight) { allowScroll.top = 1 } if(scrollWidth > clientWidth) { allowScroll.left = 1 } control.minScroll = {left:0, top:0}; var maxScrollLeft, maxScrollTop; control.maxScroll = {left:maxScrollLeft = scrollWidth - clientWidth, top:maxScrollTop = scrollHeight - clientHeight}; delete control.scrollStep; var snap = control.get("snap"), scrollLeft = control.get("scrollLeft"), scrollTop = control.get("scrollTop"); if(snap) { var elOffset = $contentEl.offset(); var pages = control.pages = typeof snap === "string" ? $contentEl.all(snap) : $contentEl.children(), pageIndex = control.get("pageIndex"), pagesOffset = control.pagesOffset = []; pages.each(function(p, i) { var offset = p.offset(), left = offset.left - elOffset.left, top = offset.top - elOffset.top; if(left <= maxScrollLeft && top <= maxScrollTop) { pagesOffset[i] = {left:left, top:top, index:i} } }); if(pageIndex) { control.scrollToPage(pageIndex); return } } control.scrollToWithBounds({left:scrollLeft, top:scrollTop}); control.fire("reflow", v) } return Container.extend({initializer:function() { this.scrollAnims = [] }, bindUI:function() { var self = this, $el = self.$el; $el.on("mousewheel", self.handleMouseWheel, self).on("scroll", onElScroll, self) }, _onSetDimension:reflow, handleKeyDownInternal:function(e) { var target = e.target, $target = $(target), nodeName = $target.nodeName(); if(nodeName === "input" || nodeName === "textarea" || nodeName === "select" || $target.hasAttr("contenteditable")) { return undefined } var self = this, keyCode = e.keyCode, scrollStep = self.getScrollStep(), ok; var allowX = self.allowScroll.left; var allowY = self.allowScroll.top; if(allowY) { var scrollStepY = scrollStep.top, clientHeight = self.clientHeight, scrollTop = self.get("scrollTop"); if(keyCode === KeyCode.DOWN) { self.scrollToWithBounds({top:scrollTop + scrollStepY}); ok = true }else { if(keyCode === KeyCode.UP) { self.scrollToWithBounds({top:scrollTop - scrollStepY}); ok = true }else { if(keyCode === KeyCode.PAGE_DOWN) { self.scrollToWithBounds({top:scrollTop + clientHeight}); ok = true }else { if(keyCode === KeyCode.PAGE_UP) { self.scrollToWithBounds({top:scrollTop - clientHeight}); ok = true } } } } } if(allowX) { var scrollStepX = scrollStep.left; var scrollLeft = self.get("scrollLeft"); if(keyCode === KeyCode.RIGHT) { self.scrollToWithBounds({left:scrollLeft + scrollStepX}); ok = true }else { if(keyCode === KeyCode.LEFT) { self.scrollToWithBounds({left:scrollLeft - scrollStepX}); ok = true } } } return ok }, getScrollStep:function() { var control = this; if(control.scrollStep) { return control.scrollStep } var elDoc = $(this.get("el")[0].ownerDocument); var clientHeight = control.clientHeight; var clientWidth = control.clientWidth; control.scrollStep = {top:Math.max(clientHeight * clientHeight * 0.7 / elDoc.height(), 20), left:Math.max(clientWidth * clientWidth * 0.7 / elDoc.width(), 20)}; return control.scrollStep }, handleMouseWheel:function(e) { if(this.get("disabled")) { return } var max, min, self = this, scrollStep = self.getScrollStep(), deltaY, deltaX, maxScroll = self.maxScroll, minScroll = self.minScroll; if((deltaY = e.deltaY) && self.allowScroll.top) { var scrollTop = self.get("scrollTop"); max = maxScroll.top; min = minScroll.top; if(!(scrollTop <= min && deltaY > 0 || scrollTop >= max && deltaY < 0)) { self.scrollToWithBounds({top:scrollTop - e.deltaY * scrollStep.top}); e.preventDefault() } } if((deltaX = e.deltaX) && self.allowScroll.left) { var scrollLeft = self.get("scrollLeft"); max = maxScroll.left; min = minScroll.left; if(!(scrollLeft <= min && deltaX > 0 || scrollLeft >= max && deltaX < 0)) { self.scrollToWithBounds({left:scrollLeft - e.deltaX * scrollStep.left}); e.preventDefault() } } }, stopAnimation:function() { var self = this; if(self.scrollAnims.length) { S.each(self.scrollAnims, function(scrollAnim) { scrollAnim.stop() }); self.scrollAnims = [] } self.scrollToWithBounds({left:self.get("scrollLeft"), top:self.get("scrollTop")}) }, _uiSetPageIndex:function(v) { this.scrollToPage(v) }, getPageIndexFromXY:function(v, allowX, direction) { var pagesOffset = this.pagesOffset.concat([]); var p2 = allowX ? "left" : "top"; var i, offset; pagesOffset.sort(function(e1, e2) { return e1[p2] - e2[p2] }); if(direction > 0) { for(i = 0;i < pagesOffset.length;i++) { offset = pagesOffset[i]; if(offset[p2] >= v) { return offset.index } } }else { for(i = pagesOffset.length - 1;i >= 0;i--) { offset = pagesOffset[i]; if(offset[p2] <= v) { return offset.index } } } return undefined }, scrollToPage:function(index, animCfg) { var self = this, pageOffset; if((pageOffset = self.pagesOffset) && pageOffset[index]) { self.set("pageIndex", index); self.scrollTo(pageOffset[index], animCfg) } }, scrollToWithBounds:function(cfg, anim) { var self = this; var maxScroll = self.maxScroll; var minScroll = self.minScroll; if(cfg.left) { cfg.left = Math.min(Math.max(cfg.left, minScroll.left), maxScroll.left) } if(cfg.top) { cfg.top = Math.min(Math.max(cfg.top, minScroll.top), maxScroll.top) } self.scrollTo(cfg, anim) }, scrollTo:function(cfg, animCfg) { var self = this, left = cfg.left, top = cfg.top; if(animCfg) { var node = {}, to = {}; if(left !== undefined) { to.scrollLeft = left; node.scrollLeft = self.get("scrollLeft") } if(top !== undefined) { to.scrollTop = top; node.scrollTop = self.get("scrollTop") } animCfg.frame = frame; animCfg.node = node; animCfg.to = to; var anim; self.scrollAnims.push(anim = new Anim(animCfg)); anim.scrollView = self; anim.run() }else { if(left !== undefined) { self.set("scrollLeft", left) } if(top !== undefined) { self.set("scrollTop", top) } } }}, {ATTRS:{contentEl:{}, scrollLeft:{view:1, value:0}, scrollTop:{view:1, value:0}, dimension:{}, focusable:{value:true}, allowTextSelection:{value:true}, handleMouseEvents:{value:false}, snap:{value:false}, pageIndex:{value:0}, xrender:{value:Render}}, xclass:"scroll-view"}) });
module.exports = Container.extend([ContentBox], methods, { ATTRS: { focusable: { // need process keydown value: true }, allowTextSelection: { value: true }, handleGestureEvents: { value: false }, /** * scrollLeft of scroll view * @property scrollLeft * @type {Number} */ /** * @ignore */ scrollLeft: { render: 1, value: 0 }, /** * scrollTop of scroll view * @property scrollTop * @type {Number} */ /** * @ignore */ scrollTop: { render: 1, value: 0 }, dimension: {}, /** * whether to allow snap effect * @cfg {Boolean} snap */ /** * @ignore */ snap: { value: false }, /** * pageIndex, current pageIndex if allow snap * @property pageIndex * @type {Number} */ /** * @ignore */ pageIndex: { value: 0 } }, xclass: 'scroll-view' });
], function (S, require) { var Node = require('node'); var Container = require('component/container'); var DelegateChildrenExtension = require('component/extension/delegate-children'); var KeyCode = Node.KeyCode; /** * KISSY Menu. * xclass: 'menu'. * @class KISSY.Menu * @extends KISSY.Component.Container */ /** * KISSY Menu. * xclass: 'menu'. * @class KISSY.Menu * @extends KISSY.Component.Container */ return Container.extend([DelegateChildrenExtension], { isMenu: 1, beforeCreateDom: function (renderData) { renderData.elAttrs.role = 'menu'; }, bindUI: function () { var self = this; self.on('afterHighlightedItemChange', afterHighlightedItemChange, self); }, // 只能允许一个方向,这个属性只是为了记录和排他性选择 // 只允许调用 menuItem 的 set('highlighted') // 不允许调用 menu 的 set('highlightedItem'),内部调用时防止循环更新 _onSetHighlightedItem: function (v, ev) { var highlightedItem; // ignore v == null // do not use set('highlightedItem',null) for api // use this.get('highlightedItem').set('highlighted', false); // ignore v == null // do not use set('highlightedItem',null) for api // use this.get('highlightedItem').set('highlighted', false); if (v && ev && (highlightedItem = ev.prevVal)) { // in case set highlightedItem null again highlightedItem.set('highlighted', false, { data: { byPassSetHighlightedItem: 1 } }); } }, _onSetVisible: function (v, e) { this.callSuper(v, e); var highlightedItem; if (!v && (highlightedItem = this.get('highlightedItem'))) { highlightedItem.set('highlighted', false); } }, getRootMenu: function () { return this; }, handleMouseEnterInternal: function (e) { this.callSuper(e); var rootMenu = this.getRootMenu(); // maybe called by popupmenu, no submenu // maybe called by popupmenu, no submenu if (rootMenu && rootMenu._popupAutoHideTimer) { clearTimeout(rootMenu._popupAutoHideTimer); rootMenu._popupAutoHideTimer = null; } this.focus(); }, handleBlurInternal: function (e) { this.callSuper(e); var highlightedItem; if (highlightedItem = this.get('highlightedItem')) { highlightedItem.set('highlighted', false); } }, //dir : -1 ,+1 //skip disabled items _getNextEnabledHighlighted: function (index, dir) { var children = this.get('children'), len = children.length, o = index; do { var c = children[index]; if (!c.get('disabled') && c.get('visible') !== false) { return children[index]; } index = (index + dir + len) % len; } while (index !== o); return undefined; }, /** * Attempts to handle a keyboard event; * returns true if the event was handled, * false otherwise. * If the container is enabled, and a child is highlighted, * calls the child control's {@code handleKeydown} method to give the control * a chance to handle the event first. * Protected, should only be overridden by subclasses. * @param {KISSY.Event.DomEvent.Object} e Key event to handle. * @return {Boolean|undefined} Whether the event was handled by the container (or one of * its children). * @protected * */ handleKeyDownInternal: function (e) { var self = this; // Give the highlighted control the chance to handle the key event. // Give the highlighted control the chance to handle the key event. var highlightedItem = self.get('highlightedItem'); // 先看当前活跃 menuitem 是否要处理 // 先看当前活跃 menuitem 是否要处理 if (highlightedItem && highlightedItem.handleKeyDownInternal(e)) { return true; } var children = self.get('children'), len = children.length; if (len === 0) { return undefined; } var index, destIndex, nextHighlighted; //自己处理了,不要向上处理,嵌套菜单情况 //自己处理了,不要向上处理,嵌套菜单情况 switch (e.keyCode) { // esc case KeyCode.ESC: // 清除所有菜单 if (highlightedItem = self.get('highlightedItem')) { highlightedItem.set('highlighted', false); } break; // home // home case KeyCode.HOME: nextHighlighted = self._getNextEnabledHighlighted(0, 1); break; // end // end case KeyCode.END: nextHighlighted = self._getNextEnabledHighlighted(len - 1, -1); break; // up // up case KeyCode.UP: if (!highlightedItem) { destIndex = len - 1; } else { index = S.indexOf(highlightedItem, children); destIndex = (index - 1 + len) % len; } nextHighlighted = self._getNextEnabledHighlighted(destIndex, -1); break; //down //down case KeyCode.DOWN: if (!highlightedItem) { destIndex = 0; } else { index = S.indexOf(highlightedItem, children); destIndex = (index + 1 + len) % len; } nextHighlighted = self._getNextEnabledHighlighted(destIndex, 1); break; } if (nextHighlighted) { nextHighlighted.set('highlighted', true, { data: { fromKeyboard: 1 } }); return true; } else { return undefined; } }, /** * Whether this menu contains specified html element. * @param {KISSY.Node} element html Element to be tested. * @return {Boolean} * @protected */ containsElement: function (element) { var self = this; var $el = self.$el; // 隐藏当然不包含了 // 隐藏当然不包含了 if (!self.get('visible') || !$el) { return false; } if ($el && ($el[0] === element || $el.contains(element))) { return true; } var children = self.get('children'); for (var i = 0, count = children.length; i < count; i++) { var child = children[i]; if (child.containsElement && child.containsElement(element)) { return true; } } return false; } }, { ATTRS: { /** * Current highlighted child menu item. * @type {KISSY.Menu.Item} * @property highlightedItem * @readonly */ /** * @ignore */ highlightedItem: { value: null }, defaultChildCfg: { valueFn: function () { return { xclass: 'menuitem' }; } } }, xclass: 'menu' }); // capture bubbling // capture bubbling function afterHighlightedItemChange(e) { if (e.target.isMenu) { var el = this.el, menuItem = e.newVal; el.setAttribute('aria-activedescendant', menuItem && menuItem.el.id || ''); } } }); /**
KISSY.add("menu/control", ["node", "component/container", "component/extension/delegate-children"], function(S, require) { var Node = require("node"); var Container = require("component/container"); var DelegateChildrenExtension = require("component/extension/delegate-children"); var KeyCode = Node.KeyCode; return Container.extend([DelegateChildrenExtension], {isMenu:1, beforeCreateDom:function(renderData) { renderData.elAttrs.role = "menu" }, bindUI:function() { var self = this; self.on("afterHighlightedItemChange", afterHighlightedItemChange, self) }, _onSetHighlightedItem:function(v, ev) { var highlightedItem; if(v && ev && (highlightedItem = ev.prevVal)) { highlightedItem.set("highlighted", false, {data:{byPassSetHighlightedItem:1}}) } }, _onSetVisible:function(v, e) { this.callSuper(v, e); var highlightedItem; if(!v && (highlightedItem = this.get("highlightedItem"))) { highlightedItem.set("highlighted", false) } }, getRootMenu:function() { return this }, handleMouseEnterInternal:function(e) { this.callSuper(e); var rootMenu = this.getRootMenu(); if(rootMenu && rootMenu._popupAutoHideTimer) { clearTimeout(rootMenu._popupAutoHideTimer); rootMenu._popupAutoHideTimer = null } this.focus() }, handleBlurInternal:function(e) { this.callSuper(e); var highlightedItem; if(highlightedItem = this.get("highlightedItem")) { highlightedItem.set("highlighted", false) } }, _getNextEnabledHighlighted:function(index, dir) { var children = this.get("children"), len = children.length, o = index; do { var c = children[index]; if(!c.get("disabled") && c.get("visible") !== false) { return children[index] } index = (index + dir + len) % len }while(index !== o); return undefined }, handleKeyDownInternal:function(e) { var self = this; var highlightedItem = self.get("highlightedItem"); if(highlightedItem && highlightedItem.handleKeyDownInternal(e)) { return true } var children = self.get("children"), len = children.length; if(len === 0) { return undefined } var index, destIndex, nextHighlighted; switch(e.keyCode) { case KeyCode.ESC: if(highlightedItem = self.get("highlightedItem")) { highlightedItem.set("highlighted", false) } break; case KeyCode.HOME: nextHighlighted = self._getNextEnabledHighlighted(0, 1); break; case KeyCode.END: nextHighlighted = self._getNextEnabledHighlighted(len - 1, -1); break; case KeyCode.UP: if(!highlightedItem) { destIndex = len - 1 }else { index = S.indexOf(highlightedItem, children); destIndex = (index - 1 + len) % len } nextHighlighted = self._getNextEnabledHighlighted(destIndex, -1); break; case KeyCode.DOWN: if(!highlightedItem) { destIndex = 0 }else { index = S.indexOf(highlightedItem, children); destIndex = (index + 1 + len) % len } nextHighlighted = self._getNextEnabledHighlighted(destIndex, 1); break } if(nextHighlighted) { nextHighlighted.set("highlighted", true, {data:{fromKeyboard:1}}); return true }else { return undefined } }, containsElement:function(element) { var self = this; var $el = self.$el; if(!self.get("visible") || !$el) { return false } if($el && ($el[0] === element || $el.contains(element))) { return true } var children = self.get("children"); for(var i = 0, count = children.length;i < count;i++) { var child = children[i]; if(child.containsElement && child.containsElement(element)) { return true } } return false }}, {ATTRS:{highlightedItem:{value:null}, defaultChildCfg:{value:{xclass:"menuitem"}}}, xclass:"menu"}); function afterHighlightedItemChange(e) { if(e.target.isMenu) { var el = this.el, menuItem = e.newVal; el.setAttribute("aria-activedescendant", menuItem && menuItem.el.id || "") } } });
KISSY.add(function (S, require) { var $ = require('node').all; var Container = require('component/container'); var ContentTpl = require('component/extension/content-xtpl'); var ContentRender = require('component/extension/content-render'); var LOADING_HTML = '<div class="{prefixCls}navigation-view-loading">' + '<div class="{prefixCls}navigation-view-loading-outer">' + '<div class="{prefixCls}navigation-view-loading-inner"></div>' + '</div>' + '</div>'; var vendorPrefix = S.Feature.getVendorCssPropPrefix('animation'); var ANIMATION_END_EVENT = vendorPrefix ? (vendorPrefix.toLowerCase() + 'AnimationEnd') : // https://github.com/kissyteam/kissy/issues/538 'animationend webkitAnimationEnd'; var uuid = 0; var NavigationViewRender = Container.getDefaultRender().extend([ContentRender], { createDom: function () { var self = this, control = self.control; var $loadingEl = $(S.substitute(LOADING_HTML, { prefixCls: self.control.get('prefixCls') })); control.get('contentEl').append($loadingEl); control.$loadingEl = $loadingEl; control.loadingEl = $loadingEl[0]; $loadingEl.on(ANIMATION_END_EVENT, onAnimEnd($loadingEl[0]), control); } }); function getViewInstance(navigationView, config) { var children = navigationView.get('children'); var viewId = config.viewId; for (var i = 0; i < children.length; i++) { if (children[i].constructor.xclass === config.xclass) { if (viewId) { if (children[i].get('viewId') === viewId) { return children[i]; } } else { return children[i]; } } } return null; } function gc(navigationView) { var children = navigationView.get('children').concat(); var viewCacheSize = navigationView.get('viewCacheSize'); if (children.length <= viewCacheSize) { return; } var removedSize = Math.floor(viewCacheSize / 3); children.sort(function (a, b) { return a.uuid - b.uuid; }); for (var i = 0; i < removedSize; i++) { navigationView.removeChild(children[i]); } } /** * @private * @param self * @param css * @param [enter] * @returns {string} */ function getAnimCss(self, css, enter) { return self.view.getBaseCssClass('anim-' + css + '-' + (enter ? 'enter' : 'leave')); } function trimClassName(className) { return S.trim(className).replace(/\s+/, ' '); } /** * * @param el * @param self * @param [css] */ function showAnimateEl(el, self, css) { var className = el.className, originalClassName = className; if (className.match(self.animateClassRegExp)) { className = className.replace(self.animateClassRegExp, ''); } if (css) { className += ' ' + css; } if (className.indexOf(self.showViewClass) === -1) { className += ' ' + self.showViewClass; } if (className !== originalClassName) { el.className = trimClassName(className); } } function hideAnimateEl(el, self) { var className = el.className, originalClassName = className; className = className.replace(self.animateClassRegExp, '') .replace(self.showViewClass, ''); if (className !== originalClassName) { el.className = trimClassName(className); } } function postProcessSwitchView(self, oldView, newView, backward) { var promise = newView.promise; self.set('activeView', newView); gc(self); if (promise) { promise.then(function () { var activeView = self.get('activeView'); if (activeView && activeView.uuid === newView.uuid) { self.fire('afterInnerViewChange', { oldView: oldView, newView: newView, backward: backward }); hideAnimateEl(self.loadingEl, self); showAnimateEl(newView.el, self); } }); } else { self.fire('afterInnerViewChange', { oldView: oldView, newView: newView, backward: backward }); } } function processSwitchView(self, config, oldView, newView, enterAnimCssClass, leaveAnimCssClass, backward) { var loadingEl = self.loadingEl; if (oldView) { if (oldView.leave) { oldView.leave(); } oldView.fire('leave'); } var newViewEl = newView.el; newView.set(config); if (newView) { if (newView.enter) { newView.enter(); } newView.fire('enter'); } self.fire('beforeInnerViewChange', { oldView: oldView, newView: newView, backward: backward }); var promise = newView.promise; if (oldView) { showAnimateEl(oldView.el, self, leaveAnimCssClass); } if (promise) { if (oldView) { showAnimateEl(loadingEl, self, enterAnimCssClass); } else { // first view show loading without anim showAnimateEl(loadingEl, self); } // leave without aim, hidden hideAnimateEl(newViewEl, self); } else { // is loading and not first view if (self.$loadingEl.hasClass(self.showViewClass) && oldView) { showAnimateEl(loadingEl, self, leaveAnimCssClass); } showAnimateEl(newViewEl, self, enterAnimCssClass); } } function isEnterCss(css, self) { return css.match(self.animateEnterRegExp); } function isLeaveCss(css, self) { return css.match(self.animateLeaveRegExp); } function onAnimEnd(el) { return function () { var self = this; var className = el.className; if (isEnterCss(className, self)) { showAnimateEl(el, self); } else if (isLeaveCss(className, self)) { hideAnimateEl(el, self); } }; } return Container.extend({ createDom: function () { var self = this; self.animateClassRegExp = new RegExp(self.view.getBaseCssClass() + '-anim-[^\\s]+'); self.animateEnterRegExp = new RegExp('-enter(?:\\s|$)'); self.animateLeaveRegExp = new RegExp('-leave(?:\\s|$)'); self.showViewClass = self.view.getBaseCssClass('show-view'); self.viewStack = []; }, /** * get inner view instance for specified view class. * @param [config] * @returns {KISSY.Component.Control} */ createView: function (config) { var self = this; var nextView = getViewInstance(self, config); var nextViewEl; if (!nextView) { nextView = self.addChild(config); nextViewEl = nextView.get('el'); nextViewEl.on(ANIMATION_END_EVENT, onAnimEnd(nextViewEl[0]), self); } return nextView; }, push: function (config) { var self = this, nextView, animation, enterAnimation, leaveAnimation, enterAnimCssClass, leaveAnimCssClass, activeView, viewStack = self.viewStack, activeViewConfig = viewStack[viewStack.length - 1]; activeView = self.get('activeView'); if (activeView) { config.animation = config.animation || self.get('animation'); } else { // first view no animation config.animation = {}; } animation = config.animation; nextView = self.createView(config); nextView.uuid = uuid++; viewStack.push(config); enterAnimation = animation.enter; leaveAnimation = animation.leave; if (activeView) { leaveAnimation = activeViewConfig.animation.leave || leaveAnimation; } enterAnimCssClass = enterAnimation && getAnimCss(self, enterAnimation, true) || ''; leaveAnimCssClass = getAnimCss(self, leaveAnimation); processSwitchView(self, config, activeView, nextView, enterAnimCssClass, leaveAnimCssClass); postProcessSwitchView(self, activeView, nextView); }, replace: function (config) { var self = this, viewStack = self.viewStack; S.mix(viewStack[viewStack.length - 1], config); }, pop: function (config) { var self = this, activeView, nextView, enterAnimCssClass, leaveAnimCssClass, activeViewConfig, viewStack = self.viewStack; if (viewStack.length > 1) { activeViewConfig = viewStack[viewStack.length - 1]; viewStack.pop(); activeView = self.get('activeView'); config = viewStack[viewStack.length - 1]; nextView = self.createView(config); nextView.uuid = uuid++; enterAnimCssClass = getAnimCss(self, config.animation.leave || activeViewConfig.animation.leave, true); leaveAnimCssClass = getAnimCss(self, activeViewConfig.animation.enter); processSwitchView(self, config, activeView, nextView, enterAnimCssClass, leaveAnimCssClass, true); postProcessSwitchView(self, activeView, nextView, true); } } }, { xclass: 'navigation-view', ATTRS: { /** * default animation for view switch when pushed enter or pushed leave */ animation: { value: { 'enter': 'slide-right', 'leave': 'slide-left' } }, handleGestureEvents: { value: false }, viewCacheSize: { value: 20 }, focusable: { value: false }, allowTextSelection: { value: true }, xrender: { value: NavigationViewRender }, contentTpl: { value: ContentTpl }, defaultChildCfg: { value: { handleGestureEvents: false, allowTextSelection: true } } } }); });
KISSY.add(function(S, require) { _$jscoverage['/base.js'].functionData[0]++; _$jscoverage['/base.js'].lineData[7]++; var Node = require('node'); _$jscoverage['/base.js'].lineData[8]++; var Anim = require('anim'); _$jscoverage['/base.js'].lineData[9]++; var Container = require('component/container'); _$jscoverage['/base.js'].lineData[10]++; var Render = require('./base/render'); _$jscoverage['/base.js'].lineData[13]++; var $ = S.all, isTouchEventSupported = S.Features.isTouchEventSupported(), KeyCode = Node.KeyCode; _$jscoverage['/base.js'].lineData[17]++; function onElScroll() { _$jscoverage['/base.js'].functionData[1]++; _$jscoverage['/base.js'].lineData[18]++; var self = this, el = self.el, scrollTop = el.scrollTop, scrollLeft = el.scrollLeft; _$jscoverage['/base.js'].lineData[22]++; if (visit10_22_1(scrollTop)) { _$jscoverage['/base.js'].lineData[23]++; self.set('scrollTop', scrollTop + self.get('scrollTop')); } _$jscoverage['/base.js'].lineData[25]++; if (visit11_25_1(scrollLeft)) { _$jscoverage['/base.js'].lineData[26]++; self.set('scrollLeft', scrollLeft + self.get('scrollLeft')); } _$jscoverage['/base.js'].lineData[28]++; el.scrollTop = el.scrollLeft = 0; } _$jscoverage['/base.js'].lineData[31]++; function frame(anim, fx) { _$jscoverage['/base.js'].functionData[2]++; _$jscoverage['/base.js'].lineData[32]++; anim.scrollView.set(fx.prop, fx.val); } _$jscoverage['/base.js'].lineData[41]++; return Container.extend({ initializer: function() { _$jscoverage['/base.js'].functionData[3]++; _$jscoverage['/base.js'].lineData[43]++; this.scrollAnims = []; }, bindUI: function() { _$jscoverage['/base.js'].functionData[4]++; _$jscoverage['/base.js'].lineData[47]++; var self = this, $el = self.$el; _$jscoverage['/base.js'].lineData[52]++; $el.on('mousewheel', self.handleMouseWheel, self).on('scroll', onElScroll, self); }, handleKeyDownInternal: function(e) { _$jscoverage['/base.js'].functionData[5]++; _$jscoverage['/base.js'].lineData[57]++; var target = e.target, $target = $(target), nodeName = $target.nodeName(); _$jscoverage['/base.js'].lineData[61]++; if (visit12_61_1(visit13_61_2(nodeName === 'input') || visit14_62_1(visit15_62_2(nodeName === 'textarea') || visit16_63_1(visit17_63_2(nodeName === 'select') || $target.hasAttr('contenteditable'))))) { _$jscoverage['/base.js'].lineData[65]++; return undefined; } _$jscoverage['/base.js'].lineData[67]++; var self = this, keyCode = e.keyCode, scrollStep = self.getScrollStep(), ok; _$jscoverage['/base.js'].lineData[71]++; var allowX = self.allowScroll.left; _$jscoverage['/base.js'].lineData[72]++; var allowY = self.allowScroll.top; _$jscoverage['/base.js'].lineData[73]++; if (visit18_73_1(allowY)) { _$jscoverage['/base.js'].lineData[74]++; var scrollStepY = scrollStep.top, clientHeight = self.clientHeight, scrollTop = self.get('scrollTop'); _$jscoverage['/base.js'].lineData[77]++; if (visit19_77_1(keyCode === KeyCode.DOWN)) { _$jscoverage['/base.js'].lineData[78]++; self.scrollToWithBounds({ top: scrollTop + scrollStepY}); _$jscoverage['/base.js'].lineData[81]++; ok = true; } else { _$jscoverage['/base.js'].lineData[82]++; if (visit20_82_1(keyCode === KeyCode.UP)) { _$jscoverage['/base.js'].lineData[83]++; self.scrollToWithBounds({ top: scrollTop - scrollStepY}); _$jscoverage['/base.js'].lineData[84]++; ok = true; } else { _$jscoverage['/base.js'].lineData[85]++; if (visit21_85_1(keyCode === KeyCode.PAGE_DOWN)) { _$jscoverage['/base.js'].lineData[86]++; self.scrollToWithBounds({ top: scrollTop + clientHeight}); _$jscoverage['/base.js'].lineData[87]++; ok = true; } else { _$jscoverage['/base.js'].lineData[88]++; if (visit22_88_1(keyCode === KeyCode.PAGE_UP)) { _$jscoverage['/base.js'].lineData[89]++; self.scrollToWithBounds({ top: scrollTop - clientHeight}); _$jscoverage['/base.js'].lineData[90]++; ok = true; } } } } } _$jscoverage['/base.js'].lineData[93]++; if (visit23_93_1(allowX)) { _$jscoverage['/base.js'].lineData[94]++; var scrollStepX = scrollStep.left; _$jscoverage['/base.js'].lineData[95]++; var scrollLeft = self.get('scrollLeft'); _$jscoverage['/base.js'].lineData[96]++; if (visit24_96_1(keyCode === KeyCode.RIGHT)) { _$jscoverage['/base.js'].lineData[97]++; self.scrollToWithBounds({ left: scrollLeft + scrollStepX}); _$jscoverage['/base.js'].lineData[98]++; ok = true; } else { _$jscoverage['/base.js'].lineData[99]++; if (visit25_99_1(keyCode === KeyCode.LEFT)) { _$jscoverage['/base.js'].lineData[100]++; self.scrollToWithBounds({ left: scrollLeft - scrollStepX}); _$jscoverage['/base.js'].lineData[101]++; ok = true; } } } _$jscoverage['/base.js'].lineData[104]++; return ok; }, getScrollStep: function() { _$jscoverage['/base.js'].functionData[6]++; _$jscoverage['/base.js'].lineData[108]++; var control = this; _$jscoverage['/base.js'].lineData[109]++; if (visit26_109_1(control.scrollStep)) { _$jscoverage['/base.js'].lineData[110]++; return control.scrollStep; } _$jscoverage['/base.js'].lineData[112]++; var elDoc = $(this.get('el')[0].ownerDocument); _$jscoverage['/base.js'].lineData[113]++; var clientHeight = control.clientHeight; _$jscoverage['/base.js'].lineData[114]++; var clientWidth = control.clientWidth; _$jscoverage['/base.js'].lineData[115]++; control.scrollStep = { top: Math.max(clientHeight * clientHeight * 0.7 / elDoc.height(), 20), left: Math.max(clientWidth * clientWidth * 0.7 / elDoc.width(), 20)}; _$jscoverage['/base.js'].lineData[119]++; return control.scrollStep; }, handleMouseWheel: function(e) { _$jscoverage['/base.js'].functionData[7]++; _$jscoverage['/base.js'].lineData[123]++; if (visit27_123_1(this.get('disabled'))) { _$jscoverage['/base.js'].lineData[124]++; return; } _$jscoverage['/base.js'].lineData[126]++; var max, min, self = this, scrollStep = self.getScrollStep(), deltaY, deltaX, maxScroll = self.maxScroll, minScroll = self.minScroll; _$jscoverage['/base.js'].lineData[135]++; if (visit28_135_1((deltaY = e.deltaY) && self.allowScroll.top)) { _$jscoverage['/base.js'].lineData[136]++; var scrollTop = self.get('scrollTop'); _$jscoverage['/base.js'].lineData[137]++; max = maxScroll.top; _$jscoverage['/base.js'].lineData[138]++; min = minScroll.top; _$jscoverage['/base.js'].lineData[139]++; if (visit29_139_1(!(visit30_139_2(visit31_139_3(visit32_139_4(scrollTop <= min) && visit33_139_5(deltaY > 0)) || visit34_139_6(visit35_139_7(scrollTop >= max) && visit36_139_8(deltaY < 0)))))) { _$jscoverage['/base.js'].lineData[140]++; self.scrollToWithBounds({ top: scrollTop - e.deltaY * scrollStep.top}); _$jscoverage['/base.js'].lineData[141]++; e.preventDefault(); } } _$jscoverage['/base.js'].lineData[145]++; if (visit37_145_1((deltaX = e.deltaX) && self.allowScroll.left)) { _$jscoverage['/base.js'].lineData[146]++; var scrollLeft = self.get('scrollLeft'); _$jscoverage['/base.js'].lineData[147]++; max = maxScroll.left; _$jscoverage['/base.js'].lineData[148]++; min = minScroll.left; _$jscoverage['/base.js'].lineData[149]++; if (visit38_149_1(!(visit39_149_2(visit40_149_3(visit41_149_4(scrollLeft <= min) && visit42_149_5(deltaX > 0)) || visit43_149_6(visit44_149_7(scrollLeft >= max) && visit45_149_8(deltaX < 0)))))) { _$jscoverage['/base.js'].lineData[150]++; self.scrollToWithBounds({ left: scrollLeft - e.deltaX * scrollStep.left}); _$jscoverage['/base.js'].lineData[151]++; e.preventDefault(); } } }, 'isAxisEnabled': function(axis) { _$jscoverage['/base.js'].functionData[8]++; _$jscoverage['/base.js'].lineData[157]++; return this.allowScroll[visit46_157_1(axis === 'x') ? 'left' : 'top']; }, stopAnimation: function() { _$jscoverage['/base.js'].functionData[9]++; _$jscoverage['/base.js'].lineData[161]++; var self = this; _$jscoverage['/base.js'].lineData[162]++; if (visit47_162_1(self.scrollAnims.length)) { _$jscoverage['/base.js'].lineData[163]++; S.each(self.scrollAnims, function(scrollAnim) { _$jscoverage['/base.js'].functionData[10]++; _$jscoverage['/base.js'].lineData[164]++; scrollAnim.stop(); }); _$jscoverage['/base.js'].lineData[166]++; self.scrollAnims = []; } _$jscoverage['/base.js'].lineData[168]++; self.scrollToWithBounds({ left: self.get('scrollLeft'), top: self.get('scrollTop')}); }, '_uiSetPageIndex': function(v) { _$jscoverage['/base.js'].functionData[11]++; _$jscoverage['/base.js'].lineData[175]++; this.scrollToPage(v); }, _getPageIndexFromXY: function(v, allowX, direction) { _$jscoverage['/base.js'].functionData[12]++; _$jscoverage['/base.js'].lineData[179]++; var pagesOffset = this.pagesOffset.concat([]); _$jscoverage['/base.js'].lineData[180]++; var p2 = allowX ? 'left' : 'top'; _$jscoverage['/base.js'].lineData[181]++; var i, offset; _$jscoverage['/base.js'].lineData[182]++; pagesOffset.sort(function(e1, e2) { _$jscoverage['/base.js'].functionData[13]++; _$jscoverage['/base.js'].lineData[183]++; return e1[p2] - e2[p2]; }); _$jscoverage['/base.js'].lineData[185]++; if (visit48_185_1(direction > 0)) { _$jscoverage['/base.js'].lineData[186]++; for (i = 0; visit49_186_1(i < pagesOffset.length); i++) { _$jscoverage['/base.js'].lineData[187]++; offset = pagesOffset[i]; _$jscoverage['/base.js'].lineData[188]++; if (visit50_188_1(offset[p2] >= v)) { _$jscoverage['/base.js'].lineData[189]++; return offset.index; } } } else { _$jscoverage['/base.js'].lineData[193]++; for (i = pagesOffset.length - 1; visit51_193_1(i >= 0); i--) { _$jscoverage['/base.js'].lineData[194]++; offset = pagesOffset[i]; _$jscoverage['/base.js'].lineData[195]++; if (visit52_195_1(offset[p2] <= v)) { _$jscoverage['/base.js'].lineData[196]++; return offset.index; } } } _$jscoverage['/base.js'].lineData[200]++; return undefined; }, scrollToPage: function(index, animCfg) { _$jscoverage['/base.js'].functionData[14]++; _$jscoverage['/base.js'].lineData[204]++; var self = this, pageOffset; _$jscoverage['/base.js'].lineData[206]++; if (visit53_206_1((pageOffset = self.pagesOffset) && pageOffset[index])) { _$jscoverage['/base.js'].lineData[207]++; self.set('pageIndex', index); _$jscoverage['/base.js'].lineData[208]++; self.scrollTo(pageOffset[index], animCfg); } }, scrollToWithBounds: function(cfg, anim) { _$jscoverage['/base.js'].functionData[15]++; _$jscoverage['/base.js'].lineData[213]++; var self = this; _$jscoverage['/base.js'].lineData[214]++; var maxScroll = self.maxScroll; _$jscoverage['/base.js'].lineData[215]++; var minScroll = self.minScroll; _$jscoverage['/base.js'].lineData[216]++; if (visit54_216_1(cfg.left)) { _$jscoverage['/base.js'].lineData[217]++; cfg.left = Math.min(Math.max(cfg.left, minScroll.left), maxScroll.left); } _$jscoverage['/base.js'].lineData[219]++; if (visit55_219_1(cfg.top)) { _$jscoverage['/base.js'].lineData[220]++; cfg.top = Math.min(Math.max(cfg.top, minScroll.top), maxScroll.top); } _$jscoverage['/base.js'].lineData[222]++; self.scrollTo(cfg, anim); }, scrollTo: function(cfg, animCfg) { _$jscoverage['/base.js'].functionData[16]++; _$jscoverage['/base.js'].lineData[226]++; var self = this, left = cfg.left, top = cfg.top; _$jscoverage['/base.js'].lineData[229]++; if (visit56_229_1(animCfg)) { _$jscoverage['/base.js'].lineData[230]++; var node = {}, to = {}; _$jscoverage['/base.js'].lineData[232]++; if (visit57_232_1(left !== undefined)) { _$jscoverage['/base.js'].lineData[233]++; to.scrollLeft = left; _$jscoverage['/base.js'].lineData[234]++; node.scrollLeft = self.get('scrollLeft'); } _$jscoverage['/base.js'].lineData[236]++; if (visit58_236_1(top !== undefined)) { _$jscoverage['/base.js'].lineData[237]++; to.scrollTop = top; _$jscoverage['/base.js'].lineData[238]++; node.scrollTop = self.get('scrollTop'); } _$jscoverage['/base.js'].lineData[240]++; animCfg.frame = frame; _$jscoverage['/base.js'].lineData[241]++; animCfg.node = node; _$jscoverage['/base.js'].lineData[242]++; animCfg.to = to; _$jscoverage['/base.js'].lineData[243]++; var anim; _$jscoverage['/base.js'].lineData[244]++; self.scrollAnims.push(anim = new Anim(animCfg)); _$jscoverage['/base.js'].lineData[245]++; anim.scrollView = self; _$jscoverage['/base.js'].lineData[246]++; anim.run(); } else { _$jscoverage['/base.js'].lineData[248]++; if (visit59_248_1(left !== undefined)) { _$jscoverage['/base.js'].lineData[249]++; self.set('scrollLeft', left); } _$jscoverage['/base.js'].lineData[251]++; if (visit60_251_1(top !== undefined)) { _$jscoverage['/base.js'].lineData[252]++; self.set('scrollTop', top); } } }}, { ATTRS: { contentEl: {}, scrollLeft: { view: 1, value: 0}, scrollTop: { view: 1, value: 0}, focusable: { value: !isTouchEventSupported}, allowTextSelection: { value: true}, handleGestureEvents: { value: false}, snap: { value: false}, pageIndex: { value: 0}, xrender: { value: Render}}, xclass: 'scroll-view'}); });
], function (S, require, exports, module) { /** * @ignore * abstraction of tree node ,root and other node will extend it * @author yiminghe@gmail.com */ var Container = require('component/container'); var util = require('util'); var $ = require('node'), KeyCode = require('node').Event.KeyCode; var SELECTED_CLS = 'selected', EXPAND_EL_CLS = 'expand-icon', COMMON_EXPAND_EL_CLS = 'expand-icon-{t}', EXPAND_ICON_EL_FILE_CLS = [COMMON_EXPAND_EL_CLS].join(' '), EXPAND_ICON_EL_FOLDER_EXPAND_CLS = [COMMON_EXPAND_EL_CLS + 'minus'].join(' '), EXPAND_ICON_EL_FOLDER_COLLAPSE_CLS = [COMMON_EXPAND_EL_CLS + 'plus'].join(' '), ICON_EL_FILE_CLS = ['file-icon'].join(' '), ICON_EL_FOLDER_EXPAND_CLS = ['expanded-folder-icon'].join(' '), ICON_EL_FOLDER_COLLAPSE_CLS = ['collapsed-folder-icon'].join(' '), ROW_EL_CLS = 'row', CHILDREN_CLS = 'children', CHILDREN_CLS_L = 'lchildren'; var TreeNodeTpl = require('./node-xtpl'); var ContentBox = require('component/extension/content-box'); /** * Tree Node. xclass: 'tree-node'. * @class KISSY.Tree.Node * @extends KISSY.Component.Container */ /** * Tree Node. xclass: 'tree-node'. * @class KISSY.Tree.Node * @extends KISSY.Component.Container */ module.exports = Container.extend([ContentBox], { beforeCreateDom: function (renderData) { util.mix(renderData.elAttrs, { role: 'tree-node', 'aria-labelledby': 'ks-content' + renderData.id, 'aria-expanded': renderData.expanded ? 'true' : 'false', 'aria-selected': renderData.selected ? 'true' : 'false', 'aria-level': renderData.depth, title: renderData.tooltip }); }, bindUI: function () { this.on('afterAddChild', onAddChild); this.on('afterRemoveChild', onRemoveChild); this.on('afterAddChild afterRemoveChild', syncAriaSetSize); }, syncUI: function () { // 集中设置样式 refreshCss(this); syncAriaSetSize.call(this, { target: this }); }, handleKeyDownInternal: function (e) { var self = this, processed = true, tree = self.get('tree'), expanded = self.get('expanded'), nodeToBeSelected, isLeaf = self.get('isLeaf'), children = self.get('children'), keyCode = e.keyCode; // 顺序统统为前序遍历顺序 // 顺序统统为前序遍历顺序 switch (keyCode) { case KeyCode.ENTER: return self.handleClickInternal(e); // home // 移到树的顶层节点 // home // 移到树的顶层节点 case KeyCode.HOME: nodeToBeSelected = tree; break; // end // 移到最后一个可视节点 // end // 移到最后一个可视节点 case KeyCode.END: nodeToBeSelected = getLastVisibleDescendant(tree); break; // 上 // 当前节点的上一个兄弟节点的最后一个可显示节点 // 上 // 当前节点的上一个兄弟节点的最后一个可显示节点 case KeyCode.UP: nodeToBeSelected = getPreviousVisibleNode(self); break; // 下 // 当前节点的下一个可显示节点 // 下 // 当前节点的下一个可显示节点 case KeyCode.DOWN: nodeToBeSelected = getNextVisibleNode(self); break; // 左 // 选择父节点或 collapse 当前节点 // 左 // 选择父节点或 collapse 当前节点 case KeyCode.LEFT: if (expanded && (children.length || isLeaf === false)) { self.set('expanded', false); } else { nodeToBeSelected = self.get('parent'); } break; // 右 // expand 当前节点 // 右 // expand 当前节点 case KeyCode.RIGHT: if (children.length || isLeaf === false) { if (!expanded) { self.set('expanded', true); } else { nodeToBeSelected = children[0]; } } break; default: processed = false; break; } if (nodeToBeSelected) { nodeToBeSelected.select(); } return processed; }, next: function () { var self = this, parent = self.get('parent'), siblings, index; if (!parent) { return null; } siblings = parent.get('children'); index = util.indexOf(self, siblings); if (index === siblings.length - 1) { return null; } return siblings[index + 1]; }, prev: function () { var self = this, parent = self.get('parent'), siblings, index; if (!parent) { return null; } siblings = parent.get('children'); index = util.indexOf(self, siblings); if (index === 0) { return null; } return siblings[index - 1]; }, /** * Select current tree node. */ select: function () { this.set('selected', true); }, handleClickInternal: function (e) { // prevent firing click from parent e.stopPropagation(); var self = this, target = $(e.target), expanded = self.get('expanded'), tree = self.get('tree'); tree.focus(); self.callSuper(e); if (target.equals(self.get('expandIconEl'))) { self.set('expanded', !expanded); } else { self.select(); self.fire('click'); } return true; }, /** * override root 's renderChildren to apply depth and css recursively */ createChildren: function () { var self = this; self.renderChildren.apply(self, arguments); // only sync child sub tree at root node // only sync child sub tree at root node if (self === self.get('tree')) { updateSubTreeStatus(self, self, -1, 0); } }, refreshCss: function (isNodeSingleOrLast, isNodeLeaf) { var self = this, iconEl = self.get('iconEl'), iconElCss, expandElCss, expandIconEl = self.get('expandIconEl'), childrenEl = self.getChildrenContainerEl(); if (isNodeLeaf) { iconElCss = ICON_EL_FILE_CLS; expandElCss = EXPAND_ICON_EL_FILE_CLS; } else { var expanded = self.get('expanded'); if (expanded) { iconElCss = ICON_EL_FOLDER_EXPAND_CLS; expandElCss = EXPAND_ICON_EL_FOLDER_EXPAND_CLS; } else { iconElCss = ICON_EL_FOLDER_COLLAPSE_CLS; expandElCss = EXPAND_ICON_EL_FOLDER_COLLAPSE_CLS; } } iconEl[0].className = self.getBaseCssClasses(iconElCss); expandIconEl[0].className = self.getBaseCssClasses([ EXPAND_EL_CLS, util.substitute(expandElCss, { t: isNodeSingleOrLast ? 'l' : 't' }) ]); childrenEl[0].className = self.getBaseCssClasses(isNodeSingleOrLast ? CHILDREN_CLS_L : CHILDREN_CLS); }, _onSetDepth: function (v) { this.el.setAttribute('aria-level', v); }, getChildrenContainerEl: function () { return this.get('childrenEl'); }, _onSetExpanded: function (v) { var self = this, childrenEl = self.getChildrenContainerEl(); childrenEl[v ? 'show' : 'hide'](); self.el.setAttribute('aria-expanded', v); refreshCss(self); self.fire(v ? 'expand' : 'collapse'); }, _onSetSelected: function (v, e) { var self = this, rowEl = self.get('rowEl'); rowEl[v ? 'addClass' : 'removeClass'](self.getBaseCssClasses(SELECTED_CLS)); self.el.setAttribute('aria-selected', v); var tree = this.get('tree'); if (!(e && e.byPassSetTreeSelectedItem)) { tree.set('selectedItem', v ? this : null); } }, /** * Expand all descend nodes of current node */ expandAll: function () { var self = this; self.set('expanded', true); util.each(self.get('children'), function (c) { c.expandAll(); }); }, /** * Collapse all descend nodes of current node */ collapseAll: function () { var self = this; self.set('expanded', false); util.each(self.get('children'), function (c) { c.collapseAll(); }); } }, { ATTRS: { allowTextSelection: { value: true }, focusable: { value: false }, handleGestureEvents: { value: false }, contentTpl: { value: TreeNodeTpl }, /** * Only For Config. * Whether to force current tree node as a leaf. * * It will change as children are added. * * @type {Boolean} */ isLeaf: { render: 1, sync: 0, parse: function (el) { var self = this; if (el.hasClass(self.getBaseCssClass('leaf'))) { return true; } else if (el.hasClass(self.getBaseCssClass('folder'))) { return false; } return undefined; } }, rowEl: { selector: function () { return '.' + this.getBaseCssClass(ROW_EL_CLS); } }, childrenEl: { selector: function () { return '.' + this.getBaseCssClass(CHILDREN_CLS); } }, /** * Element for expand icon. * @type {KISSY.Node} */ expandIconEl: { selector: function () { return '.' + this.getBaseCssClass(EXPAND_EL_CLS); } }, /** * Element for icon. * @type {KISSY.Node} */ iconEl: { selector: function () { return '.' + this.getBaseCssClass('icon'); } }, /** * Whether current tree node is selected. * @type {Boolean} */ selected: { render: 1, sync: 0 }, /** * Whether current tree node is expanded. * @type {Boolean} * Defaults to: false. */ expanded: { sync: 0, value: false, render: 1, parse: function () { return this.get('childrenEl').css('display') !== 'none'; } }, /** * html title for current tree node. * @type {String} */ tooltip: { render: 1, sync: 0 }, /** * Tree instance current tree node belongs to. * @type {KISSY.Tree} */ tree: { getter: function () { var self = this, from = self; while (from && !from.isTree) { from = from.get('parent'); } return from; } }, /** * depth of node. * @type {Number} */ depth: { render: 1, sync: 0 }, defaultChildCfg: { valueFn: function () { return { xclass: 'tree-node' }; } } }, xclass: 'tree-node' }); // # ------------------- private start // # ------------------- private start function onAddChild(e) { var self = this; if (e.target === self) { updateSubTreeStatus(self, e.component, self.get('depth'), e.index); } } function onRemoveChild(e) { var self = this; if (e.target === self) { recursiveSetDepth(self.get('tree'), e.component); refreshCssForSelfAndChildren(self, e.index); } } function syncAriaSetSize(e) { var self = this; if (e.target === self) { self.el.setAttribute('aria-setsize', self.get('children').length); } } function isNodeSingleOrLast(self) { var parent = self.get('parent'), children = parent && parent.get('children'), lastChild = children && children[children.length - 1]; // 根节点 // or // 父亲的最后一个子节点 // 根节点 // or // 父亲的最后一个子节点 return !lastChild || lastChild === self; } function isNodeLeaf(self) { var isLeaf = self.get('isLeaf'); // 强制指定了 isLeaf,否则根据儿子节点集合自动判断 // 强制指定了 isLeaf,否则根据儿子节点集合自动判断 return !(isLeaf === false || isLeaf === undefined && self.get('children').length); } function getLastVisibleDescendant(self) { var children = self.get('children'); // 没有展开或者根本没有儿子节点,可视的只有自己 // 没有展开或者根本没有儿子节点,可视的只有自己 if (!self.get('expanded') || !children.length) { return self; } // 可视的最后一个子孙 // 可视的最后一个子孙 return getLastVisibleDescendant(children[children.length - 1]); } // not same with _4ePreviousSourceNode in editor ! // not same with _4ePreviousSourceNode in editor ! function getPreviousVisibleNode(self) { var prev = self.prev(); if (!prev) { prev = self.get('parent'); } else { prev = getLastVisibleDescendant(prev); } return prev; } // similar to _4eNextSourceNode in editor // similar to _4eNextSourceNode in editor function getNextVisibleNode(self) { var children = self.get('children'), n, parent; if (self.get('expanded') && children.length) { return children[0]; } // 没有展开或者根本没有儿子节点 // 深度遍历的下一个 // 没有展开或者根本没有儿子节点 // 深度遍历的下一个 n = self.next(); parent = self; while (!n && (parent = parent.get('parent'))) { n = parent.next(); } return n; } /* 每次添加/删除节点,都检查自己以及自己子孙 class 每次 expand/collapse,都检查 */ /* 每次添加/删除节点,都检查自己以及自己子孙 class 每次 expand/collapse,都检查 */ function refreshCss(self) { self.refreshCss(isNodeSingleOrLast(self), isNodeLeaf(self)); } function updateSubTreeStatus(self, c, depth, index) { var tree = self.get('tree'); if (tree) { recursiveSetDepth(tree, c, depth + 1); refreshCssForSelfAndChildren(self, index); } } function recursiveSetDepth(tree, c, setDepth) { if (setDepth !== undefined) { c.set('depth', setDepth); } util.each(c.get('children'), function (child) { if (typeof setDepth === 'number') { recursiveSetDepth(tree, child, setDepth + 1); } else { recursiveSetDepth(tree, child); } }); } function refreshCssForSelfAndChildren(self, index) { refreshCss(self); index = Math.max(0, index - 1); var children = self.get('children'), c, len = children.length; for (; index < len; index++) { c = children[index]; refreshCss(c); c.el.setAttribute('aria-posinset', index + 1); } } // # ------------------- private end /** * @ignore * 2012-09-25 * - 去除 dblclick 支持,该交互会重复触发 click 事件,可能会重复执行逻辑 */ });
KISSY.add("toolbar", ["component/container", "component/extension/delegate-children", "toolbar/render", "node"], function(S, require) { var Container = require("component/container"); var DelegateChildrenExtension = require("component/extension/delegate-children"); var ToolbarRender = require("toolbar/render"); var Node = require("node"); var KeyCode = Node.KeyCode; function getNextEnabledItem(index, direction, self) { var children = self.get("children"), count = 0, childrenLength = children.length; if(index === undefined) { if(direction === 1) { index = 0 }else { index = childrenLength - 1 } if(!children[index].get("disabled")) { return children[index] } } do { count++; index = (index + childrenLength + direction) % childrenLength }while(count < childrenLength && children[index].get("disabled")); if(count !== childrenLength) { return children[index] } return null } function afterCollapsedChange(e) { var self = this; if(e.newVal) { self.set("expandedItem", null) }else { self.set("expandedItem", e.target) } } function afterHighlightedChange(e) { var self = this, expandedItem, children, target = e.target; if(self !== target && (target.isMenuItem || target.isButton)) { if(e.newVal) { children = self.get("children"); if((expandedItem = self.get("expandedItem")) && S.inArray(target, children)) { self.set("expandedItem", target.isMenuButton ? target : null) } self.set("highlightedItem", target) }else { if(!e.byPassSetToolbarHighlightedItem) { self.set("highlightedItem", null) } } } } function getChildByHighlightedItem(toolbar) { var children = toolbar.get("children"), i, child; for(i = 0;i < children.length;i++) { child = children[i]; if(child.get("highlighted") || child.isMenuButton && !child.get("collapsed")) { return child } } return null } return Container.extend([DelegateChildrenExtension], {_onSetHighlightedItem:function(item, e) { var id, itemEl, self = this, prevVal = e && e.prevVal, children = self.get("children"), el = self.el; if(prevVal && S.inArray(prevVal, children)) { prevVal.set("highlighted", false, {data:{byPassSetToolbarHighlightedItem:1}}) } if(item) { if(el.ownerDocument.activeElement !== el) { self.focus() } itemEl = item.el; id = itemEl.id; if(!id) { itemEl.id = id = S.guid("ks-toolbar-item") } el.setAttribute("aria-activedescendant", id) }else { el.setAttribute("aria-activedescendant", "") } }, _onSetExpandedItem:function(v, e) { if(e && e.prevVal) { e.prevVal.set("collapsed", true) } if(v) { v.set("collapsed", false) } }, bindUI:function() { var self = this; self.on("afterCollapsedChange", afterCollapsedChange, self); self.on("afterHighlightedChange", afterHighlightedChange, self) }, handleBlurInternal:function(e) { var self = this, highlightedItem; self.callSuper(e); self.set("expandedItem", null); if(highlightedItem = self.get("highlightedItem")) { highlightedItem.set("highlighted", false) } }, getNextItemByKeyDown:function(e, current) { var self = this, children = self.get("children"), childIndex = current && S.indexOf(current, children); if(current) { if(current.handleKeyDownInternal(e)) { return true } } if(e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) { return false } switch(e.keyCode) { case KeyCode.ESC: self.view.getKeyEventTarget().fire("blur"); return true; case KeyCode.HOME: current = getNextEnabledItem(undefined, 1, self); break; case KeyCode.END: current = getNextEnabledItem(undefined, -1, self); break; case KeyCode.UP: current = getNextEnabledItem(childIndex, -1, self); break; case KeyCode.LEFT: current = getNextEnabledItem(childIndex, -1, self); break; case KeyCode.DOWN: current = getNextEnabledItem(childIndex, 1, self); break; case KeyCode.RIGHT: current = getNextEnabledItem(childIndex, 1, self); break; default: return false } return current }, handleKeyDownInternal:function(e) { var self = this, currentChild = getChildByHighlightedItem(self), nextHighlightedItem = self.getNextItemByKeyDown(e, currentChild); if(typeof nextHighlightedItem === "boolean") { return nextHighlightedItem } if(nextHighlightedItem) { nextHighlightedItem.set("highlighted", true) } return true }}, {xclass:"toolbar", ATTRS:{highlightedItem:{}, expandedItem:{}, defaultChildCfg:{value:{xclass:"button", handleMouseEvents:false, focusable:false}}, xrender:{value:ToolbarRender}}}) });
KISSY.add(function (S, require) { var Container = require('component/container'); /** * tab body container for tab panels.xclass: 'tabs-body'. * @class KISSY.Tabs.Body * @extends KISSY.Component.Container */ var TabBody = Container.extend({ bindUI: function () { var self = this; self.on("afterSelectedPanelIndexChange", function (e) { var children = self.get('children'), newIndex = e.newVal, hidePanel; if (children[newIndex]) { if (hidePanel = children[e.prevVal]) { hidePanel.set("selected", false); } self.selectPanelByIndex(newIndex); } }); }, syncUI: function () { var self = this, children = self.get("children"); S.each(children, function (c, i) { if (c.get("selected")) { self.set("selectedPanelIndex", i); return false; } return undefined; }); }, createChild: function (index) { return checkLazy(this, 'createChild', index); }, renderChild: function (index) { return checkLazy(this, 'renderChild', index); }, selectPanelByIndex: function (newIndex) { this.get('children')[newIndex].set("selected", true); if (this.get('lazyRender')) { // lazy render this.renderChild(newIndex); } } }, { ATTRS: { selectedPanelIndex: { }, allowTextSelection: { value: true }, focusable: { value: false }, lazyRender: { }, handleMouseEvents: { value: false }, defaultChildCfg: { value: { xclass: 'tabs-panel' } } }, xclass: 'tabs-body' }); function checkLazy(self, method, index) { if (self.get('lazyRender')) { var c = self.get('children')[index]; if (!c.get('selected')) { return c; } } return TabBody.superclass[method].call(self, index); } return TabBody; });
], function (S, require, exports, module) { /** * navigation view to accommodate multiple views * @author yiminghe@gmail.com */ var util = require('util'); var vendorInfo = require('feature').getCssVendorInfo('animation'); var vendorPrefix = vendorInfo && vendorInfo.propertyNamePrefix; var ANIMATION_END_EVENT = vendorPrefix ? vendorPrefix.toLowerCase() + 'AnimationEnd' : // https://github.com/kissyteam/kissy/issues/538 'animationend webkitAnimationEnd'; var Container = require('component/container'); var Control = require('component/control'); var ContentBox = require('component/extension/content-box'); function getAnimCss(prefixCls, animation, enter) { return prefixCls + 'navigation-view-' + ('anim-' + animation + '-' + (enter ? 'enter' : 'leave')) + ' ' + prefixCls + 'navigation-view-anim-ing'; } function getAnimValueFromView(view, enter, backward) { var animation = view.get('animation'); if (typeof animation === 'string') { return animation; } var animationValue; if (backward) { animationValue = enter ? animation[1] : animation[0]; } else { animationValue = enter ? animation[0] : animation[1]; } return animationValue; } function transition(view, enter, backward) { clearAnimCss(view); var animationValue = getAnimValueFromView(view, enter, backward); if (animationValue === 'none') { if (enter) { view.show(); } else { view.hide(); } return; } view.show(); view.$el.addClass(view._viewAnimCss = getAnimCss(view.get('prefixCls'), animationValue, enter)); } function loadingTransition(loadingView, view, enter, backward) { clearAnimCss(loadingView); var animationValue = getAnimValueFromView(view, enter, backward); if (animationValue === 'none') { if (enter) { loadingView.show(); } else { loadingView.hide(); } return; } loadingView.show(); loadingView.$el.addClass(loadingView._viewAnimCss = getAnimCss(view.get('prefixCls'), animationValue, enter)); } function clearAnimCss(self) { if (self._viewAnimCss) { self.$el.removeClass(self._viewAnimCss); self._viewAnimCss = null; } } var LoadingView = Control.extend({ bindUI: function () { var self = this; self.$el.on(ANIMATION_END_EVENT, function () { clearAnimCss(self); if (!self.active) { self.hide(); } }); }, transition: function (enter, backward) { var self = this; self.active = enter; loadingTransition(self, self.navigationView.get('activeView'), enter, backward); } }, { xclass: 'navigation-view-loading', ATTRS: { handleGestureEvents: { value: false }, visible: { value: false } } }); function getViewInstance(navigationView, config) { var children = navigationView.get('children'); var viewId = config.viewId; for (var i = 0; i < children.length; i++) { if (children[i].constructor.xclass === config.xclass) { if (viewId) { if (children[i].get('viewId') === viewId) { return children[i]; } } else { return children[i]; } } } return null; } function switchTo(navigationView, viewConfig, backward) { var loadingView = navigationView.loadingView; var view = viewConfig.view; var fromCache = viewConfig.fromCache; var oldView = navigationView.get('activeView'); navigationView.fire('beforeInnerViewChange', { oldView: oldView, newView: view, backward: backward }); if (oldView && oldView.leave) { oldView.leave(); } navigationView.set('activeView', view); if (view.enter) { view.enter({ fromCache: fromCache }); } var promise = view.promise; if (promise) { if (oldView) { transition(oldView, false, backward); loadingView.transition(true, backward); } else { loadingView.show(); } promise.then(function () { if (navigationView.get('activeView') === view) { loadingView.hide(); view.show(); navigationView.fire('afterInnerViewChange', { newView: view, oldView: oldView, backward: backward }); } }); } else { // is loading and not first view if (loadingView.get('visible')) { loadingView.transition(false, backward); transition(view, true, backward); } else if (oldView) { transition(oldView, false, backward); transition(view, true, backward); } else { view.show(); } navigationView.fire('afterInnerViewChange', { newView: view, oldView: oldView, backward: backward }); } gc(navigationView); } function gc(navigationView) { var children = navigationView.get('children').concat(); var viewCacheSize = navigationView.get('viewCacheSize'); if (children.length <= viewCacheSize) { return; } var removedSize = Math.floor(viewCacheSize / 3); children.sort(function (a, b) { return a.timeStamp - b.timeStamp; }); for (var i = 0; i < removedSize; i++) { navigationView.removeChild(children[i]); } } function onViewAnimEnd() { var self = this; clearAnimCss(self); if (self.get('navigationView').get('activeView') === self) { self.show(); } else { self.hide(); } } function createView(self, config) { var view = getViewInstance(self, config); var fromCache = !!view; if (view) { view.set(config); } else { view = self.addChild(config); view.$el.on(ANIMATION_END_EVENT, onViewAnimEnd, view); } view.timeStamp = util.now(); return { view: view, fromCache: fromCache }; } module.exports = Container.extend([ContentBox], { initializer: function () { this.viewStack = []; }, createDom: function () { var self = this; var loadingHtml = self.get('loadingHtml'); if (loadingHtml !== false) { self.loadingView = new LoadingView({ content: loadingHtml, render: self.contentEl }).render(); self.loadingView.navigationView = self; } }, _onSetLoadingHtml: function (v) { if (this.loadingView) { this.loadingView.set('content', v); } }, push: function (config) { var self = this, viewStack = self.viewStack; config.animation = config.animation || self.get('animation'); config.navigationView = self; viewStack.push(config); switchTo(self, createView(self, config)); }, replace: function (config) { var self = this, viewStack = self.viewStack; if (viewStack.length) { util.mix(viewStack[viewStack.length - 1], config); self.get('activeView').set(config); } }, pop: function (config) { var self = this, viewStack = self.viewStack; if (viewStack.length > 1) { viewStack.pop(); config = viewStack[viewStack.length - 1]; switchTo(self, createView(self, config), true); } } }, { xclass: 'navigation-view', ATTRS: { /** * default animation for view switch when pushed enter or pushed leave */ animation: { // push enter: slide-right-enter // push leave: slide-left-leave // pop enter: slide-left-enter // pop leave: slide-right-leave valueFn: function () { return [ 'slide-right', 'slide-left' ]; } }, loadingHtml: { sync: 0 }, handleGestureEvents: { value: false }, viewCacheSize: { value: 10 }, focusable: { value: false }, allowTextSelection: { value: true }, defaultChildCfg: { valueFn: function () { return { handleGestureEvents: false, visible: false, allowTextSelection: true }; } } } }); });
], function (S, require) { var Node = require('node'); var TimerAnim = require('anim/timer'); var Container = require('component/container'); var ContentBox = require('component/extension/content-box'); var $ = S.all, KeyCode = Node.KeyCode; // http://www.html5rocks.com/en/tutorials/speed/html5/ // http://www.html5rocks.com/en/tutorials/speed/html5/ var Feature = S.Feature, // MARKER_CLS = 'ks-scroll-view-marker', transformVendorInfo = Feature.getCssVendorInfo('transform'), floor = Math.floor, transformProperty; var isTransform3dSupported = S.Feature.isTransform3dSupported(); // http://www.html5rocks.com/en/tutorials/speed/html5/ // http://www.html5rocks.com/en/tutorials/speed/html5/ var supportCss3 = !!transformVendorInfo; var methods = { initializer: function () { this.scrollAnims = []; }, bindUI: function () { var self = this, $el = self.$el; $el.on('mousewheel', self.handleMouseWheel, self) // textarea enter cause el to scroll // bug: left top scroll does not fire scroll event, because scrollTop is 0! .on('scroll', onElScroll, self); }, syncUI: function () { this.sync(); }, sync: function () { var self = this, el = self.el, contentEl = self.contentEl; // consider pull to refresh // refresh label will be prepended to el // contentEl must be absolute // or else // relative is weird, should math.max(contentEl.scrollHeight,el.scrollHeight) // will affect pull to refresh // consider pull to refresh // refresh label will be prepended to el // contentEl must be absolute // or else // relative is weird, should math.max(contentEl.scrollHeight,el.scrollHeight) // will affect pull to refresh var scrollHeight = Math.max(contentEl.offsetHeight, contentEl.scrollHeight), scrollWidth = Math.max(contentEl.offsetWidth, contentEl.scrollWidth); var clientHeight = el.clientHeight, clientWidth = el.clientWidth; self.set('dimension', { scrollHeight: scrollHeight, scrollWidth: scrollWidth, clientWidth: clientWidth, clientHeight: clientHeight }); }, _onSetDimension: reflow, handleKeyDownInternal: function (e) { // no need to process disabled (already processed by Component) var target = e.target, $target = $(target), nodeName = $target.nodeName(); // editable element // editable element if (nodeName === 'input' || nodeName === 'textarea' || nodeName === 'select' || $target.hasAttr('contenteditable')) { return undefined; } var self = this, keyCode = e.keyCode, scrollStep = self.getScrollStep(), ok; var allowX = self.allowScroll.left; var allowY = self.allowScroll.top; if (allowY) { var scrollStepY = scrollStep.top, clientHeight = self.clientHeight, scrollTop = self.get('scrollTop'); if (keyCode === KeyCode.DOWN) { self.scrollToWithBounds({ top: scrollTop + scrollStepY }); ok = true; } else if (keyCode === KeyCode.UP) { self.scrollToWithBounds({ top: scrollTop - scrollStepY }); ok = true; } else if (keyCode === KeyCode.PAGE_DOWN) { self.scrollToWithBounds({ top: scrollTop + clientHeight }); ok = true; } else if (keyCode === KeyCode.PAGE_UP) { self.scrollToWithBounds({ top: scrollTop - clientHeight }); ok = true; } } if (allowX) { var scrollStepX = scrollStep.left; var scrollLeft = self.get('scrollLeft'); if (keyCode === KeyCode.RIGHT) { self.scrollToWithBounds({ left: scrollLeft + scrollStepX }); ok = true; } else if (keyCode === KeyCode.LEFT) { self.scrollToWithBounds({ left: scrollLeft - scrollStepX }); ok = true; } } return ok; }, getScrollStep: function () { var self = this; if (self.scrollStep) { return self.scrollStep; } var elDoc = $(this.get('el')[0].ownerDocument); var clientHeight = self.clientHeight; var clientWidth = self.clientWidth; self.scrollStep = { top: Math.max(clientHeight * clientHeight * 0.7 / elDoc.height(), 20), left: Math.max(clientWidth * clientWidth * 0.7 / elDoc.width(), 20) }; return self.scrollStep; }, handleMouseWheel: function (e) { if (this.get('disabled')) { return; } var max, min, self = this, scrollStep = self.getScrollStep(), deltaY, deltaX, maxScroll = self.maxScroll, minScroll = self.minScroll; if ((deltaY = e.deltaY) && self.allowScroll.top) { var scrollTop = self.get('scrollTop'); max = maxScroll.top; min = minScroll.top; if (!(scrollTop <= min && deltaY > 0 || scrollTop >= max && deltaY < 0)) { self.scrollToWithBounds({ top: scrollTop - e.deltaY * scrollStep.top }); e.preventDefault(); } } if ((deltaX = e.deltaX) && self.allowScroll.left) { var scrollLeft = self.get('scrollLeft'); max = maxScroll.left; min = minScroll.left; if (!(scrollLeft <= min && deltaX > 0 || scrollLeft >= max && deltaX < 0)) { self.scrollToWithBounds({ left: scrollLeft - e.deltaX * scrollStep.left }); e.preventDefault(); } } }, stopAnimation: function () { var self = this; if (self.scrollAnims.length) { S.each(self.scrollAnims, function (scrollAnim) { scrollAnim.stop(); }); self.scrollAnims = []; } self.scrollToWithBounds({ left: self.get('scrollLeft'), top: self.get('scrollTop') }); }, _uiSetPageIndex: function (v) { this.scrollToPage(v); }, getPageIndexFromXY: function (v, allowX, direction) { var pagesOffset = this.pagesOffset.concat([]); var p2 = allowX ? 'left' : 'top'; var i, offset; pagesOffset.sort(function (e1, e2) { return e1[p2] - e2[p2]; }); if (direction > 0) { for (i = 0; i < pagesOffset.length; i++) { offset = pagesOffset[i]; if (offset[p2] >= v) { return offset.index; } } } else { for (i = pagesOffset.length - 1; i >= 0; i--) { offset = pagesOffset[i]; if (offset[p2] <= v) { return offset.index; } } } return undefined; }, scrollToPage: function (index, animCfg) { var self = this, pageOffset; if ((pageOffset = self.pagesOffset) && pageOffset[index]) { self.set('pageIndex', index); self.scrollTo(pageOffset[index], animCfg); } }, scrollToWithBounds: function (cfg, anim) { var self = this; var maxScroll = self.maxScroll; var minScroll = self.minScroll; if (cfg.left) { cfg.left = Math.min(Math.max(cfg.left, minScroll.left), maxScroll.left); } if (cfg.top) { cfg.top = Math.min(Math.max(cfg.top, minScroll.top), maxScroll.top); } self.scrollTo(cfg, anim); }, scrollTo: function (cfg, animCfg) { var self = this, left = cfg.left, top = cfg.top; if (animCfg) { var node = {}, to = {}; if (left !== undefined) { to.scrollLeft = left; node.scrollLeft = self.get('scrollLeft'); } if (top !== undefined) { to.scrollTop = top; node.scrollTop = self.get('scrollTop'); } animCfg.frame = frame; animCfg.node = node; animCfg.to = to; var anim; self.scrollAnims.push(anim = new TimerAnim(animCfg)); anim.scrollView = self; anim.run(); } else { if (left !== undefined) { self.set('scrollLeft', left); } if (top !== undefined) { self.set('scrollTop', top); } } }, _onSetScrollLeft: function (v) { this.contentEl.style.left = -v + 'px'; }, _onSetScrollTop: function (v) { this.contentEl.style.top = -v + 'px'; } }; if (supportCss3) { transformProperty = transformVendorInfo.propertyName; methods._onSetScrollLeft = function (v) { this.contentEl.style[transformProperty] = 'translateX(' + floor(0 - v) + 'px)' + ' translateY(' + floor(0 - this.get('scrollTop')) + 'px)' + (isTransform3dSupported ? ' translateZ(0)' : ''); }; methods._onSetScrollTop = function (v) { this.contentEl.style[transformProperty] = 'translateX(' + floor(0 - this.get('scrollLeft')) + 'px)' + ' translateY(' + floor(0 - v) + 'px)' + (isTransform3dSupported ? ' translateZ(0)' : ''); }; } function onElScroll() { var self = this, el = self.el, scrollTop = el.scrollTop, scrollLeft = el.scrollLeft; if (scrollTop) { self.set('scrollTop', scrollTop + self.get('scrollTop')); } if (scrollLeft) { self.set('scrollLeft', scrollLeft + self.get('scrollLeft')); } el.scrollTop = el.scrollLeft = 0; } function frame(anim, fx) { anim.scrollView.set(fx.prop, fx.val); } function reflow(v, e) { var self = this, $contentEl = self.$contentEl; // consider pull to refresh // refresh label will be prepended to el // contentEl must be absolute // or else // relative is weird, should math.max(contentEl.scrollHeight,el.scrollHeight) // will affect pull to refresh // consider pull to refresh // refresh label will be prepended to el // contentEl must be absolute // or else // relative is weird, should math.max(contentEl.scrollHeight,el.scrollHeight) // will affect pull to refresh var scrollHeight = v.scrollHeight, scrollWidth = v.scrollWidth; var clientHeight = v.clientHeight, allowScroll, clientWidth = v.clientWidth; var prevVal = e && e.prevVal || {}; if (prevVal.scrollHeight === scrollHeight && prevVal.scrollWidth === scrollWidth && clientHeight === prevVal.clientHeight && clientWidth === prevVal.clientWidth) { return; } self.scrollHeight = scrollHeight; self.scrollWidth = scrollWidth; self.clientHeight = clientHeight; self.clientWidth = clientWidth; allowScroll = self.allowScroll = {}; if (scrollHeight > clientHeight) { allowScroll.top = 1; } if (scrollWidth > clientWidth) { allowScroll.left = 1; } self.minScroll = { left: 0, top: 0 }; var maxScrollLeft, maxScrollTop; self.maxScroll = { left: maxScrollLeft = scrollWidth - clientWidth, top: maxScrollTop = scrollHeight - clientHeight }; delete self.scrollStep; var snap = self.get('snap'), scrollLeft = self.get('scrollLeft'), scrollTop = self.get('scrollTop'); if (snap) { var elOffset = $contentEl.offset(); var pages = self.pages = typeof snap === 'string' ? $contentEl.all(snap) : $contentEl.children(), pageIndex = self.get('pageIndex'), pagesOffset = self.pagesOffset = []; pages.each(function (p, i) { var offset = p.offset(), left = offset.left - elOffset.left, top = offset.top - elOffset.top; if (left <= maxScrollLeft && top <= maxScrollTop) { pagesOffset[i] = { left: left, top: top, index: i }; } }); if (pageIndex) { self.scrollToPage(pageIndex); return; } } // in case content is reduces // in case content is reduces self.scrollToWithBounds({ left: scrollLeft, top: scrollTop }); self.fire('reflow', v); } /** * Make container scrollable. * module scroll-view will be this class on non-touch device * @class KISSY.ScrollView.Base * @extend KISSY.Component.Container */ /** * Make container scrollable. * module scroll-view will be this class on non-touch device * @class KISSY.ScrollView.Base * @extend KISSY.Component.Container */ return Container.extend([ContentBox], methods, { ATTRS: { /** * content element of scroll view component * @property contentEl * @type {KISSY.Node} */ /** * @ignore */ contentEl: {}, /** * scrollLeft of scroll view * @property scrollLeft * @type {Number} */ /** * @ignore */ scrollLeft: { render: 1, value: 0 }, /** * scrollTop of scroll view * @property scrollTop * @type {Number} */ /** * @ignore */ scrollTop: { render: 1, value: 0 }, dimension: {}, focusable: { // need process keydown value: true }, allowTextSelection: { value: true }, handleGestureEvents: { value: false }, /** * whether to allow snap effect * @cfg {Boolean} snap */ /** * @ignore */ snap: { value: false }, /** * pageIndex, current pageIndex if allow snap * @property pageIndex * @type {Number} */ /** * @ignore */ pageIndex: { value: 0 } }, xclass: 'scroll-view' }); });
KISSY.add(function(S, require) { _$jscoverage['/navigation-view.js'].functionData[0]++; _$jscoverage['/navigation-view.js'].lineData[6]++; var $ = require('node').all; _$jscoverage['/navigation-view.js'].lineData[7]++; var Container = require('component/container'); _$jscoverage['/navigation-view.js'].lineData[8]++; var ContentTpl = require('component/extension/content-xtpl'); _$jscoverage['/navigation-view.js'].lineData[9]++; var ContentRender = require('component/extension/content-render'); _$jscoverage['/navigation-view.js'].lineData[10]++; var LOADING_HTML = '<div class="{prefixCls}navigation-view-loading">' + '<div class="{prefixCls}navigation-view-loading-outer">' + '<div class="{prefixCls}navigation-view-loading-inner"></div>' + '</div>' + '</div>'; _$jscoverage['/navigation-view.js'].lineData[16]++; var uuid = 0; _$jscoverage['/navigation-view.js'].lineData[18]++; var NavigationViewRender = Container.getDefaultRender().extend([ContentRender], { renderUI: function() { _$jscoverage['/navigation-view.js'].functionData[1]++; _$jscoverage['/navigation-view.js'].lineData[20]++; var loadingEl = $(S.substitute(LOADING_HTML, { prefixCls: this.control.get('prefixCls')})); _$jscoverage['/navigation-view.js'].lineData[23]++; this.control.get('contentEl').append(loadingEl); _$jscoverage['/navigation-view.js'].lineData[24]++; this.control.loadingEl = loadingEl; }}); _$jscoverage['/navigation-view.js'].lineData[28]++; function getViewInstance(navigationView, config) { _$jscoverage['/navigation-view.js'].functionData[2]++; _$jscoverage['/navigation-view.js'].lineData[29]++; var children = navigationView.get('children'); _$jscoverage['/navigation-view.js'].lineData[30]++; var viewId = config.viewId; _$jscoverage['/navigation-view.js'].lineData[31]++; for (var i = 0; visit1_31_1(i < children.length); i++) { _$jscoverage['/navigation-view.js'].lineData[32]++; if (visit2_32_1(children[i].constructor.xclass === config.xclass)) { _$jscoverage['/navigation-view.js'].lineData[33]++; if (visit3_33_1(viewId)) { _$jscoverage['/navigation-view.js'].lineData[34]++; if (visit4_34_1(children[i].get('viewId') === viewId)) { _$jscoverage['/navigation-view.js'].lineData[35]++; return children[i]; } } else { _$jscoverage['/navigation-view.js'].lineData[38]++; return children[i]; } } } _$jscoverage['/navigation-view.js'].lineData[42]++; return null; } _$jscoverage['/navigation-view.js'].lineData[45]++; function gc(navigationView) { _$jscoverage['/navigation-view.js'].functionData[3]++; _$jscoverage['/navigation-view.js'].lineData[46]++; var children = navigationView.get('children').concat(); _$jscoverage['/navigation-view.js'].lineData[47]++; var viewCacheSize = navigationView.get('viewCacheSize'); _$jscoverage['/navigation-view.js'].lineData[48]++; if (visit5_48_1(children.length <= viewCacheSize)) { _$jscoverage['/navigation-view.js'].lineData[49]++; return; } _$jscoverage['/navigation-view.js'].lineData[51]++; var removedSize = Math.floor(viewCacheSize / 3); _$jscoverage['/navigation-view.js'].lineData[52]++; children.sort(function(a, b) { _$jscoverage['/navigation-view.js'].functionData[4]++; _$jscoverage['/navigation-view.js'].lineData[53]++; return a.uuid - b.uuid; }); _$jscoverage['/navigation-view.js'].lineData[55]++; for (var i = 0; visit6_55_1(i < removedSize); i++) { _$jscoverage['/navigation-view.js'].lineData[56]++; navigationView.removeChild(children[i]); } } _$jscoverage['/navigation-view.js'].lineData[67]++; function getAnimCss(self, css, enter) { _$jscoverage['/navigation-view.js'].functionData[5]++; _$jscoverage['/navigation-view.js'].lineData[68]++; return self.view.getBaseCssClass('anim-' + css + '-' + (enter ? 'enter' : 'leave')); } _$jscoverage['/navigation-view.js'].lineData[71]++; function trimClassName(className) { _$jscoverage['/navigation-view.js'].functionData[6]++; _$jscoverage['/navigation-view.js'].lineData[72]++; return S.trim(className).replace(/\s+/, ' '); } _$jscoverage['/navigation-view.js'].lineData[75]++; function animateEl(el, self, css) { _$jscoverage['/navigation-view.js'].functionData[7]++; _$jscoverage['/navigation-view.js'].lineData[76]++; var className = el[0].className, originalClassName = className; _$jscoverage['/navigation-view.js'].lineData[78]++; if (visit7_78_1(className.match(self.animateClassRegExp))) { _$jscoverage['/navigation-view.js'].lineData[79]++; className = className.replace(self.animateClassRegExp, css); } else { _$jscoverage['/navigation-view.js'].lineData[81]++; className += ' ' + css; } _$jscoverage['/navigation-view.js'].lineData[83]++; if (visit8_83_1(css)) { _$jscoverage['/navigation-view.js'].lineData[84]++; if (visit9_84_1(className.indexOf(self.animatorClass) === -1)) { _$jscoverage['/navigation-view.js'].lineData[85]++; className += ' ' + self.animatorClass; } } _$jscoverage['/navigation-view.js'].lineData[88]++; if (visit10_88_1(className !== originalClassName)) { _$jscoverage['/navigation-view.js'].lineData[89]++; el[0].className = trimClassName(className); } } _$jscoverage['/navigation-view.js'].lineData[93]++; function stopAnimateEl(el, self) { _$jscoverage['/navigation-view.js'].functionData[8]++; _$jscoverage['/navigation-view.js'].lineData[94]++; var className = el[0].className, originalClassName = className; _$jscoverage['/navigation-view.js'].lineData[97]++; className = className.replace(self.animateClassRegExp, '').replace(self.animatorClassRegExp, ''); _$jscoverage['/navigation-view.js'].lineData[99]++; if (visit11_99_1(className !== originalClassName)) { _$jscoverage['/navigation-view.js'].lineData[100]++; el[0].className = trimClassName(className); } } _$jscoverage['/navigation-view.js'].lineData[104]++; function postProcessSwitchView(self, oldView, newView, backward) { _$jscoverage['/navigation-view.js'].functionData[9]++; _$jscoverage['/navigation-view.js'].lineData[105]++; var promise = newView.promise; _$jscoverage['/navigation-view.js'].lineData[107]++; self.set('activeView', newView); _$jscoverage['/navigation-view.js'].lineData[109]++; gc(self); _$jscoverage['/navigation-view.js'].lineData[111]++; if (visit12_111_1(promise)) { _$jscoverage['/navigation-view.js'].lineData[112]++; promise.then(function() { _$jscoverage['/navigation-view.js'].functionData[10]++; _$jscoverage['/navigation-view.js'].lineData[113]++; var activeView = self.get('activeView'); _$jscoverage['/navigation-view.js'].lineData[114]++; if (visit13_114_1(activeView && visit14_114_2(activeView.uuid === newView.uuid))) { _$jscoverage['/navigation-view.js'].lineData[115]++; self.fire('afterInnerViewChange', { oldView: oldView, newView: newView, backward: backward}); _$jscoverage['/navigation-view.js'].lineData[120]++; stopAnimateEl(self.loadingEl, self); _$jscoverage['/navigation-view.js'].lineData[121]++; animateEl(newView.get('el'), self, self.animateNoneEnterClass); } }); } else { _$jscoverage['/navigation-view.js'].lineData[125]++; self.fire('afterInnerViewChange', { oldView: oldView, newView: newView, backward: backward}); } } _$jscoverage['/navigation-view.js'].lineData[133]++; function processSwitchView(self, config, oldView, newView, enterAnimCssClass, leaveAnimCssClass, backward) { _$jscoverage['/navigation-view.js'].functionData[11]++; _$jscoverage['/navigation-view.js'].lineData[134]++; var loadingEl = self.loadingEl; _$jscoverage['/navigation-view.js'].lineData[135]++; if (visit15_135_1(oldView && oldView.leave)) { _$jscoverage['/navigation-view.js'].lineData[136]++; oldView.leave(); } _$jscoverage['/navigation-view.js'].lineData[138]++; var newViewEl = newView.get('el'); _$jscoverage['/navigation-view.js'].lineData[139]++; newView.set(config); _$jscoverage['/navigation-view.js'].lineData[140]++; if (visit16_140_1(newView.enter)) { _$jscoverage['/navigation-view.js'].lineData[141]++; newView.enter(); } _$jscoverage['/navigation-view.js'].lineData[144]++; self.fire('beforeInnerViewChange', { oldView: oldView, newView: newView, backward: backward}); _$jscoverage['/navigation-view.js'].lineData[150]++; var promise = newView.promise; _$jscoverage['/navigation-view.js'].lineData[152]++; if (visit17_152_1(oldView)) { _$jscoverage['/navigation-view.js'].lineData[153]++; animateEl(oldView.get('el'), self, leaveAnimCssClass); } _$jscoverage['/navigation-view.js'].lineData[156]++; if (visit18_156_1(promise)) { _$jscoverage['/navigation-view.js'].lineData[157]++; if (visit19_157_1(oldView)) { _$jscoverage['/navigation-view.js'].lineData[158]++; animateEl(loadingEl, self, enterAnimCssClass); } else { _$jscoverage['/navigation-view.js'].lineData[160]++; animateEl(loadingEl, self, self.animateNoneEnterClass); } _$jscoverage['/navigation-view.js'].lineData[163]++; stopAnimateEl(newViewEl, self); } else { _$jscoverage['/navigation-view.js'].lineData[165]++; if (visit20_165_1(self.isLoading() || !oldView)) { _$jscoverage['/navigation-view.js'].lineData[166]++; stopAnimateEl(loadingEl, self); _$jscoverage['/navigation-view.js'].lineData[167]++; animateEl(newViewEl, self, self.animateNoneEnterClass); } else { _$jscoverage['/navigation-view.js'].lineData[169]++; animateEl(newViewEl, self, enterAnimCssClass); } } } _$jscoverage['/navigation-view.js'].lineData[174]++; return Container.extend({ isLoading: function() { _$jscoverage['/navigation-view.js'].functionData[12]++; _$jscoverage['/navigation-view.js'].lineData[176]++; return this.loadingEl.hasClass(this.animatorClass); }, renderUI: function() { _$jscoverage['/navigation-view.js'].functionData[13]++; _$jscoverage['/navigation-view.js'].lineData[180]++; var self = this; _$jscoverage['/navigation-view.js'].lineData[181]++; self.animateClassRegExp = new RegExp(self.view.getBaseCssClass() + '-anim-[^\\s]+'); _$jscoverage['/navigation-view.js'].lineData[182]++; self.animatorClass = self.view.getBaseCssClass('animator'); _$jscoverage['/navigation-view.js'].lineData[183]++; self.animateNoneEnterClass = getAnimCss(self, 'none', true); _$jscoverage['/navigation-view.js'].lineData[184]++; self.animatorClassRegExp = new RegExp(self.animatorClass); _$jscoverage['/navigation-view.js'].lineData[185]++; self.viewStack = []; _$jscoverage['/navigation-view.js'].lineData[186]++; var barEl = self.get('barEl'); _$jscoverage['/navigation-view.js'].lineData[187]++; var bar = self.get('bar'); _$jscoverage['/navigation-view.js'].lineData[188]++; var el = self.get('el'); _$jscoverage['/navigation-view.js'].lineData[189]++; if (visit21_189_1(barEl)) { _$jscoverage['/navigation-view.js'].lineData[190]++; el.prepend(barEl); } else { _$jscoverage['/navigation-view.js'].lineData[191]++; if (visit22_191_1(bar)) { _$jscoverage['/navigation-view.js'].lineData[192]++; bar.set('elBefore', el[0].firstChild); _$jscoverage['/navigation-view.js'].lineData[193]++; bar.set('navigationView', self); _$jscoverage['/navigation-view.js'].lineData[194]++; bar.render(); } } }, createView: function(config) { _$jscoverage['/navigation-view.js'].functionData[14]++; _$jscoverage['/navigation-view.js'].lineData[204]++; var self = this; _$jscoverage['/navigation-view.js'].lineData[205]++; var nextView = getViewInstance(self, config); _$jscoverage['/navigation-view.js'].lineData[206]++; if (visit23_206_1(!nextView)) { _$jscoverage['/navigation-view.js'].lineData[207]++; nextView = self.addChild(config); } _$jscoverage['/navigation-view.js'].lineData[209]++; return nextView; }, push: function(config) { _$jscoverage['/navigation-view.js'].functionData[15]++; _$jscoverage['/navigation-view.js'].lineData[213]++; var self = this, nextView, animation, enterAnimation, leaveAnimation, enterAnimCssClass, leaveAnimCssClass, activeView, viewStack = self.viewStack; _$jscoverage['/navigation-view.js'].lineData[223]++; activeView = self.get('activeView'); _$jscoverage['/navigation-view.js'].lineData[224]++; config.animation = visit24_224_1(config.animation || self.get('animation')); _$jscoverage['/navigation-view.js'].lineData[225]++; if (visit25_225_1(!activeView)) { _$jscoverage['/navigation-view.js'].lineData[227]++; config.animation = {}; } _$jscoverage['/navigation-view.js'].lineData[229]++; nextView = self.createView(config); _$jscoverage['/navigation-view.js'].lineData[230]++; nextView.uuid = uuid++; _$jscoverage['/navigation-view.js'].lineData[231]++; viewStack.push(config); _$jscoverage['/navigation-view.js'].lineData[232]++; animation = nextView.get('animation'); _$jscoverage['/navigation-view.js'].lineData[233]++; enterAnimation = animation.enter; _$jscoverage['/navigation-view.js'].lineData[234]++; leaveAnimation = animation.leave; _$jscoverage['/navigation-view.js'].lineData[235]++; if (visit26_235_1(activeView)) { _$jscoverage['/navigation-view.js'].lineData[236]++; leaveAnimation = visit27_236_1(activeView.get('animation').leave || leaveAnimation); } _$jscoverage['/navigation-view.js'].lineData[239]++; enterAnimCssClass = getAnimCss(self, enterAnimation, true); _$jscoverage['/navigation-view.js'].lineData[240]++; leaveAnimCssClass = getAnimCss(self, leaveAnimation); _$jscoverage['/navigation-view.js'].lineData[242]++; processSwitchView(self, config, activeView, nextView, enterAnimCssClass, leaveAnimCssClass); _$jscoverage['/navigation-view.js'].lineData[244]++; postProcessSwitchView(self, activeView, nextView); }, replace: function(config) { _$jscoverage['/navigation-view.js'].functionData[16]++; _$jscoverage['/navigation-view.js'].lineData[248]++; var self = this, viewStack = self.viewStack; _$jscoverage['/navigation-view.js'].lineData[250]++; S.mix(viewStack[viewStack.length - 1], config); }, pop: function() { _$jscoverage['/navigation-view.js'].functionData[17]++; _$jscoverage['/navigation-view.js'].lineData[254]++; var self = this, activeView, config, nextView, enterAnimCssClass, leaveAnimCssClass, viewStack = self.viewStack; _$jscoverage['/navigation-view.js'].lineData[262]++; if (visit28_262_1(viewStack.length > 1)) { _$jscoverage['/navigation-view.js'].lineData[263]++; viewStack.pop(); _$jscoverage['/navigation-view.js'].lineData[264]++; activeView = self.get('activeView'); _$jscoverage['/navigation-view.js'].lineData[265]++; config = viewStack[viewStack.length - 1]; _$jscoverage['/navigation-view.js'].lineData[266]++; nextView = self.createView(config); _$jscoverage['/navigation-view.js'].lineData[267]++; nextView.uuid = uuid++; _$jscoverage['/navigation-view.js'].lineData[268]++; enterAnimCssClass = getAnimCss(self, visit29_268_1(nextView.get('animation').leave || activeView.get('animation').leave), true); _$jscoverage['/navigation-view.js'].lineData[269]++; leaveAnimCssClass = getAnimCss(self, activeView.get('animation').enter); _$jscoverage['/navigation-view.js'].lineData[271]++; processSwitchView(self, config, activeView, nextView, enterAnimCssClass, leaveAnimCssClass, true); _$jscoverage['/navigation-view.js'].lineData[273]++; postProcessSwitchView(self, activeView, nextView, true); } }}, { xclass: 'navigation-view', ATTRS: { bar: {}, barEl: {}, animation: { value: { 'enter': 'slide-right', 'leave': 'slide-left'}}, handleMouseEvents: { value: false}, viewCacheSize: { value: 20}, focusable: { value: false}, allowTextSelection: { value: true}, xrender: { value: NavigationViewRender}, contentTpl: { value: ContentTpl}, defaultChildCfg: { value: { handleMouseEvents: false, allowTextSelection: true}}}}); });
], function (S, require, exports, module) { /** * @ignore * SplitButton for KISSY. Combination of button and menubutton. * @author yiminghe@gmail.com */ var Container = require('component/container'); require('button'); require('menubutton'); /** * split button container for menubutton and button * @class KISSY.SplitButton * @extend KISSY.Component.Container */ /** * split button container for menubutton and button * @class KISSY.SplitButton * @extend KISSY.Component.Container */ module.exports = Container.extend({ renderUI: function () { var self = this, alignWithEl = self.get('alignWithEl'), menuButton = self.get('children')[1], menu = menuButton.get('menu'); if (alignWithEl) { menu.get('align').node = self.$el; } } }, { ATTRS: { handleGestureEvents: { value: false }, focusable: { value: false }, allowTextSelection: { value: true }, /** * whether align menubutton with button. * Defaults to: true * @cfg {Boolean} alignWithEl */ /** * @ignore */ alignWithEl: { value: true }, children: { value: [ { xclass: 'button' }, { xclass: 'menu-button' } ] }, /** * menubutton component * @cfg {KISSY.MenuButton} menuButton */ /** * menubutton component * @property {KISSY.MenuButton} menuButton */ /** * @ignore */ menuButton: { getter: function () { return this.get('children')[1]; }, setter: function (v) { this.get('children')[1] = v; } }, /** * button component * @cfg {KISSY.Button} button */ /** * button component * @property {KISSY.Button} button */ /** * @ignore */ button: { getter: function () { return this.get('children')[0]; }, setter: function (v) { this.get('children')[0] = v; } } }, xclass: 'split-button' }); });
module.exports = Container.extend([ ContentBox, Shim, Loading, AlignExtension, Mask, OverlayEffect ], { bindUI: function () { var self = this, closeBtn = self.get('closeBtn'); if (closeBtn) { closeBtn.on('click', function (ev) { self.close(); ev.preventDefault(); }); } }, /** * hide or destroy according to {@link KISSY.Overlay#closeAction} * @chainable */ close: function () { var self = this; self[actions[self.get('closeAction')] || HIDE](); return self; } }, { ATTRS: { handleGestureEvents: { value: false }, focusable: { value: false }, allowTextSelection: { value: true }, contentTpl: { value: OverlayTpl }, /** * Whether close button is visible. * * Defaults to: true. * * @cfg {Boolean} closable */ /** * Whether close button is visible. * @type {Boolean} * @property closable */ /** * @ignore */ closable: { value: false, sync: 0, render: 1, parse: function () { return !!this.get('closeBtn'); } }, /** * close button element. * @type {KISSY.Node} * @property closeBtn * @readonly */ /** * @ignore */ closeBtn: { selector: function () { return '.' + this.getBaseCssClass('close'); } }, /** * Whether to destroy or hide current element when click close button. * Can set 'destroy' to destroy it when click close button. * * Defaults to: 'hide'. * * @cfg {String} closeAction */ /** * @ignore */ closeAction: { value: HIDE }, closeText: { value: 'close', render: 1 }, visible: { value: false } }, xclass: 'overlay' });
describe("delegate children works", function () { var MyContainer = Container.extend([DelegateChildrenExtension], {}, { xclass: 'MyContainer' }); it("should attach its methods", function () { var c = new MyContainer({ content: "xx" }); c.render(); expect(c.getOwnerControl).not.toBeUndefined(); expect(c.get('el')[0].parentNode).toBe(document.body); expect(c.get('el').html()).toBe("xx"); c.destroy(); expect(invalidNode(c.get('el')[0].parentNode)).toBe(true); }); if (Feature.isTouchEventSupported()) { } else { it("should delegate events", function () { var c = new MyContainer({ content: "xx" }); var child1 = new Control({ content: "yy", handleGestureEvents: false, focusable: false }); c.addChild(child1); var child2 = new Control({ content: "yy", handleGestureEvents: false, focusable: false }); c.addChild(child2); c.render(); // ie11 bug if (S.UA.ieMode === 11) { return; } waits(100); runs(function () { jasmine.simulate(c.get('el')[0], 'mousedown'); }); waits(100); runs(function () { expect(c.get('active')).toBe(true); }); runs(function () { jasmine.simulate(c.get('el')[0], "mouseup"); }); waits(100); runs(function () { expect(c.get('active')).toBe(false); }); runs(function () { jasmine.simulate(child1.get('el')[0], 'mousedown'); }); waits(100); runs(function () { // do not stop bubble expect(c.get('active')).toBe(true); expect(child1.get('active')).toBe(true); expect(child2.get('active')).toBeFalsy(); }); runs(function () { jasmine.simulate(child1.get('el')[0], "mouseup"); }); waits(100); runs(function () { expect(c.get('active')).toBeFalsy(); expect(child1.get('active')).toBeFalsy(); expect(child2.get('active')).toBeFalsy(); }); runs(function () { c.destroy(); expect(invalidNode(child1.get('el')[0].parentNode)).toBe(true); }); }); } });
], function (S, require, exports, module) { /** * @ignore * KISSY Tabs Component. * @author yiminghe@gmail.com */ var Container = require('component/container'); var Bar = require('tabs/bar'); var Body = require('tabs/body'); require('tabs/tab'); var Panel = require('tabs/panel'); var CLS = 'top bottom left right'; var util = require('util'); var BarIndexMap = { top: 0, left: 0, bottom: 1, right: 0 }; function setBar(children, barOrientation, bar) { children[BarIndexMap[barOrientation]] = bar; } function setBody(children, barOrientation, body) { children[1 - BarIndexMap[barOrientation]] = body; } function afterTabClose(e) { this.removeItemByTab(e.target); } function afterSelectedTabChange(e) { this.setSelectedTab(e.newVal); } function fromTabItemConfigToTabConfig(item) { var ret = {}; ret.content = item.title; ret.selected = item.selected; ret.closable = item.closable; return ret; } /** * Tabs for KISSY * @class KISSY.Tabs * @extends KISSY.Component.Container */ /** * Tabs for KISSY * @class KISSY.Tabs * @extends KISSY.Component.Container */ var Tabs = Container.extend({ initializer: function () { var self = this, items = self.get('items'); // items sugar // items sugar if (items) { var children = self.get('children'), barOrientation = self.get('barOrientation'), selected, prefixCls = self.get('prefixCls'), tabItem, panelItem, bar = { prefixCls: prefixCls, xclass: 'tabs-bar', changeType: self.get('changeType'), children: [] }, body = { prefixCls: prefixCls, xclass: 'tabs-body', lazyRender: self.get('lazyRender'), children: [] }, barChildren = bar.children, panels = body.children; util.each(items, function (item) { selected = selected || item.selected; barChildren.push(tabItem = fromTabItemConfigToTabConfig(item)); panels.push(panelItem = { content: item.content, selected: item.selected }); }); if (!selected && barChildren.length) { barChildren[0].selected = true; panels[0].selected = true; } setBar(children, barOrientation, bar); setBody(children, barOrientation, body); } }, beforeCreateDom: function (renderData) { renderData.elCls.push(this.getBaseCssClass(this.get('barOrientation'))); }, decorateDom: function () { this.get('bar').set('changeType', this.get('changeType')); }, bindUI: function () { this.on('afterSelectedTabChange', afterSelectedTabChange); this.on('afterTabClose', afterTabClose); /** * fired when selected tab is changed * @event afterSelectedTabChange * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.newVal selected tab */ /** * fired before selected tab is changed * @event beforeSelectedTabChange * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.newVal tab to be selected */ /** * fired when tab is closed * @event afterTabClose * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.target closed tab */ /** * fired before tab is closed * @event beforeTabClose * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.target tab to be closed */ }, /** * fired when selected tab is changed * @event afterSelectedTabChange * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.newVal selected tab */ /** * fired before selected tab is changed * @event beforeSelectedTabChange * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.newVal tab to be selected */ /** * fired when tab is closed * @event afterTabClose * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.target closed tab */ /** * fired before tab is closed * @event beforeTabClose * @member KISSY.Tabs * @param {KISSY.Event.CustomEvent.Object} e * @param {KISSY.Tabs.Tab} e.target tab to be closed */ /** * add one item to tabs * @param {Object} item item description * @param {String} item.content tab panel html * @param {String} item.title tab bar html * @param {String} item.closable whether this tab is closable * @param {Number} index insert index * @chainable */ addItem: function (item, index) { var self = this, bar = self.get('bar'), selectedTab, tabItem, panelItem, barChildren = bar.get('children'), body = self.get('body'); if (typeof index === 'undefined') { index = barChildren.length; } tabItem = fromTabItemConfigToTabConfig(item); panelItem = { content: item.content }; bar.addChild(tabItem, index); selectedTab = barChildren[index]; body.addChild(panelItem, index); if (item.selected) { bar.set('selectedTab', selectedTab); body.set('selectedPanelIndex', index); } return self; }, /** * remove specified tab from current tabs * @param {Number} index * @param {Boolean} destroy whether destroy specified tab and panel * @chainable */ removeItemAt: function (index, destroy) { var self = this, bar = /** @ignore @type KISSY.Component.Control */ self.get('bar'), barCs = bar.get('children'), tab = bar.getChildAt(index), body = /** @ignore @type KISSY.Component.Control */ self.get('body'); if (tab.get('selected')) { if (barCs.length === 1) { bar.set('selectedTab', null); } else if (index === 0) { bar.set('selectedTab', bar.getChildAt(index + 1)); } else { bar.set('selectedTab', bar.getChildAt(index - 1)); } } bar.removeChild(bar.getChildAt(index), destroy); body.removeChild(body.getChildAt(index), destroy); return self; }, /** * remove item by specified tab * @param {KISSY.Tabs.Tab} tab * @param {Boolean} destroy whether destroy specified tab and panel * @chainable */ removeItemByTab: function (tab, destroy) { var index = util.indexOf(tab, this.get('bar').get('children')); return this.removeItemAt(index, destroy); }, /** * remove item by specified panel * @param {KISSY.Tabs.Panel} panel * @param {Boolean} destroy whether destroy specified tab and panel * @chainable */ removeItemByPanel: function (panel, destroy) { var index = util.indexOf(panel, this.get('body').get('children')); return this.removeItemAt(index, destroy); }, /** * get selected tab instance * @return {KISSY.Tabs.Tab} */ getSelectedTab: function () { var self = this, bar = self.get('bar'), child = null; util.each(bar.get('children'), function (c) { if (c.get('selected')) { child = c; return false; } return undefined; }); return child; }, /** * get selected tab instance * @return {KISSY.Tabs.Tab} */ getSelectedPanel: function () { var self = this, body = self.get('body'), child = null; util.each(body.get('children'), function (c) { if (c.get('selected')) { child = c; return false; } return undefined; }); return child; }, /** * get all tabs * @return {KISSY.Tabs.Tab[]} */ getTabs: function () { return this.get('bar').get('children'); }, /** * get all tabs * @return {KISSY.Tabs.Panel[]} */ getPanels: function () { return this.get('body').get('children'); }, /** * @ignore */ getTabAt: function (index) { return this.get('bar').get('children')[index]; }, /** * @ignore */ getPanelAt: function (index) { return this.get('body').get('children')[index]; }, /** * set tab as selected * @param {KISSY.Tabs.Tab} tab * @chainable */ setSelectedTab: function (tab) { var self = this, bar = self.get('bar'), body = self.get('body'); bar.set('selectedTab', tab); body.set('selectedPanelIndex', util.indexOf(tab, bar.get('children'))); return this; }, /** * set panel as selected * @param {KISSY.Tabs.Panel} panel * @chainable */ setSelectedPanel: function (panel) { var self = this, bar = self.get('bar'), body = self.get('body'), selectedPanelIndex = util.indexOf(panel, body.get('children')); body.set('selectedPanelIndex', selectedPanelIndex); bar.set('selectedTab', self.getTabAt(selectedPanelIndex)); return this; }, _onSetBarOrientation: function (v) { var self = this, el = self.$el; el.removeClass(self.getBaseCssClass(CLS)).addClass(self.getBaseCssClass(v)); } }, { ATTRS: { handleGestureEvents: { value: false }, allowTextSelection: { value: true }, focusable: { value: false }, /** * tabs config, eg: {title:'', content:'', selected:false, closable:false} * @cfg {Object} item */ /** * @ignore */ items: {}, /** * tabs trigger event type, mouse or click * @cfg {String} changeType */ /** * @ignore */ changeType: {}, /** * whether allow tab to lazy render * @cfg {Boolean} lazyRender */ /** * @ignore */ lazyRender: { value: false }, bar: { getter: function () { return this.get('children')[BarIndexMap[this.get('barOrientation')]]; } }, body: { getter: function () { return this.get('children')[1 - BarIndexMap[this.get('barOrientation')]]; } }, /** * tab bar orientation. * eg: 'left' 'right' 'top' 'bottom' * @cfg {String} barOrientation */ barOrientation: { render: 1, sync: 0, value: 'top', parse: function (el) { var orientation = el[0].className.match(/(top|bottom|left|right)\b/); return orientation && orientation[1] || undefined; } } }, xclass: 'tabs' }); /** * Tab bar orientation. * @enum {String} KISSY.Tabs.Orientation */ /** * Tab bar orientation. * @enum {String} KISSY.Tabs.Orientation */ Tabs.Orientation = { /** * top */ TOP: 'top', /** * bottom */ BOTTOM: 'bottom', /** * left */ LEFT: 'left', /** * right */ RIGHT: 'right' }; Tabs.ChangeType = Bar.ChangeType; Tabs.Bar = Bar; Tabs.Body = Body; Tabs.Panel = Panel; module.exports = Tabs; });
], function (S, require, exports, module) { /** * @ignore * control for overlay * @author yiminghe@gmail.com */ var Container = require('component/container'); var Shim = require('component/extension/shim'); var AlignExtension = require('component/extension/align'); var Loading = require('./extension/loading'); var Mask = require('./extension/mask'); var OverlayEffect = require('./extension/overlay-effect'); var ContentBox = require('component/extension/content-box'); var OverlayTpl = require('./overlay-xtpl'); var HIDE = 'hide', actions = { hide: HIDE, destroy: 'destroy' }; /** * KISSY Overlay Component. * xclass: 'overlay'. * @class KISSY.Overlay * @extends KISSY.Component.Container * @mixins KISSY.Component.Extension.Shim * @mixins KISSY.Overlay.Extension.Effect * @mixins KISSY.Overlay.Extension.Loading * @mixins KISSY.Component.Extension.Align * @mixins KISSY.Overlay.Extension.Mask */ /** * KISSY Overlay Component. * xclass: 'overlay'. * @class KISSY.Overlay * @extends KISSY.Component.Container * @mixins KISSY.Component.Extension.Shim * @mixins KISSY.Overlay.Extension.Effect * @mixins KISSY.Overlay.Extension.Loading * @mixins KISSY.Component.Extension.Align * @mixins KISSY.Overlay.Extension.Mask */ module.exports = Container.extend([ ContentBox, Shim, Loading, AlignExtension, Mask, OverlayEffect ], { bindUI: function () { var self = this, closeBtn = self.get('closeBtn'); if (closeBtn) { closeBtn.on('click', function (ev) { self.close(); ev.preventDefault(); }); } }, /** * hide or destroy according to {@link KISSY.Overlay#closeAction} * @chainable */ close: function () { var self = this; self[actions[self.get('closeAction')] || HIDE](); return self; } }, { ATTRS: { handleGestureEvents: { value: false }, focusable: { value: false }, allowTextSelection: { value: true }, contentTpl: { value: OverlayTpl }, /** * Whether close button is visible. * * Defaults to: true. * * @cfg {Boolean} closable */ /** * Whether close button is visible. * @type {Boolean} * @property closable */ /** * @ignore */ closable: { value: false, sync: 0, render: 1, parse: function () { return !!this.get('closeBtn'); } }, /** * close button element. * @type {KISSY.Node} * @property closeBtn * @readonly */ /** * @ignore */ closeBtn: { selector: function () { return '.' + this.getBaseCssClass('close'); } }, /** * Whether to destroy or hide current element when click close button. * Can set 'destroy' to destroy it when click close button. * * Defaults to: 'hide'. * * @cfg {String} closeAction */ /** * @ignore */ closeAction: { value: HIDE }, closeText: { value: 'close', render: 1 }, visible: { value: false } }, xclass: 'overlay' }); });
], function (S, require, exports, module) { /** * @ignore * Body for tab panels. * @author yiminghe@gmail.com */ var Container = require('component/container'); var util = require('util'); /** * tab body container for tab panels.xclass: 'tabs-body'. * @class KISSY.Tabs.Body * @extends KISSY.Component.Container */ /** * tab body container for tab panels.xclass: 'tabs-body'. * @class KISSY.Tabs.Body * @extends KISSY.Component.Container */ var TabBody = Container.extend({ bindUI: function () { var self = this; self.on('afterSelectedPanelIndexChange', function (e) { var children = self.get('children'), newIndex = e.newVal, hidePanel; if (children[newIndex]) { if (hidePanel = children[e.prevVal]) { hidePanel.set('selected', false); } self.selectPanelByIndex(newIndex); } }); }, syncUI: function () { var self = this, children = self.get('children'); util.each(children, function (c, i) { if (c.get('selected')) { self.set('selectedPanelIndex', i); return false; } return undefined; }); }, createChild: function (index) { return checkLazy(this, 'createChild', index); }, renderChild: function (index) { return checkLazy(this, 'renderChild', index); }, selectPanelByIndex: function (newIndex) { this.get('children')[newIndex].set('selected', true); if (this.get('lazyRender')) { // lazy render this.renderChild(newIndex); } } }, { ATTRS: { allowTextSelection: { value: true }, focusable: { value: false }, handleGestureEvents: { value: false }, selectedPanelIndex: {}, lazyRender: {}, defaultChildCfg: { valueFn: function () { return { xclass: 'tabs-panel' }; } } }, xclass: 'tabs-body' }); function checkLazy(self, method, index) { if (self.get('lazyRender')) { var c = self.get('children')[index]; if (!c.get('selected')) { return c; } } return TabBody.superclass[method].call(self, index); } module.exports = TabBody; });