From c629da28c9bc3404fc3141b30d26ce9774761f99 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 09:53:10 +0800 Subject: [PATCH 01/19] add --- src/base/single/button/button.basic.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js index 5a1b20dd8..1b6214536 100644 --- a/src/base/single/button/button.basic.js +++ b/src/base/single/button/button.basic.js @@ -284,13 +284,8 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - empty: function () { + destroyed: function () { $(document).unbind("mouseup." + this.getName()); - BI.BasicButton.superclass.empty.apply(this, arguments); - }, - - destroy: function () { - BI.BasicButton.superclass.destroy.apply(this, arguments); } }); BI.BasicButton.EVENT_CHANGE = "BasicButton.EVENT_CHANGE"; \ No newline at end of file From 10281e3a2f40f1441e5dd33948cb2677a14d34f1 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 10:16:32 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E5=B8=83=E5=B1=80demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/js/config.js | 70 ++------ demo/js/layout/demo.border.js | 97 +++++++++++ demo/js/layout/demo.center.js | 35 ++++ demo/js/layout/demo.float_center.js | 27 +++ demo/js/layout/demo.flow.js | 85 +++++++++ demo/js/layout/demo.grid.js | 137 +++++++++++++++ demo/js/layout/demo.horizontal.js | 50 ++++++ demo/js/layout/demo.horizontal_adapt.js | 42 +++++ demo/js/layout/demo.horizontal_auto.js | 42 +++++ demo/js/layout/demo.horizontal_float.js | 35 ++++ demo/js/layout/demo.htape.js | 38 ++++ demo/js/layout/demo.inline.js | 47 +++++ .../layout/demo.left_right_vertical_adapt.js | 44 +++++ demo/js/layout/demo.table.js | 162 ++++++++++++++++++ demo/js/layout/demo.td.js | 59 +++++++ demo/js/layout/demo.vertical.js | 25 +++ demo/js/layout/demo.vertical_adapt.js | 42 +++++ demo/js/layout/demo.vtape.js | 38 ++++ dist/core.css | 2 +- dist/core.js | 4 +- .../wrapper/layout/adapt/float.horizontal.js | 4 +- src/css/utils/widget.css | 2 +- 22 files changed, 1028 insertions(+), 59 deletions(-) create mode 100644 demo/js/layout/demo.border.js create mode 100644 demo/js/layout/demo.center.js create mode 100644 demo/js/layout/demo.float_center.js create mode 100644 demo/js/layout/demo.flow.js create mode 100644 demo/js/layout/demo.grid.js create mode 100644 demo/js/layout/demo.horizontal.js create mode 100644 demo/js/layout/demo.horizontal_adapt.js create mode 100644 demo/js/layout/demo.horizontal_auto.js create mode 100644 demo/js/layout/demo.horizontal_float.js create mode 100644 demo/js/layout/demo.htape.js create mode 100644 demo/js/layout/demo.inline.js create mode 100644 demo/js/layout/demo.left_right_vertical_adapt.js create mode 100644 demo/js/layout/demo.table.js create mode 100644 demo/js/layout/demo.td.js create mode 100644 demo/js/layout/demo.vertical.js create mode 100644 demo/js/layout/demo.vertical_adapt.js create mode 100644 demo/js/layout/demo.vtape.js diff --git a/demo/js/config.js b/demo/js/config.js index e2a314c17..6ca641c57 100644 --- a/demo/js/config.js +++ b/demo/js/config.js @@ -17,108 +17,72 @@ Demo.CONFIG = [{ pId: 1, text: "bi.center_adapt", value: "demo.center_adapt" -}, { - pId: 1, - text: "bi.float_center_adapt", - value: "float_center_adapt" -}, { - pId: 1, - text: "bi.absolute_center_adapt", - value: "absolute_center_adapt" -}, { - pId: 1, - text: "bi.flex_center", - value: "flex_center" -}, { - pId: 1, - text: "bi.inline_center_adapt", - value: "inline_center_adapt" }, { pId: 1, text: "bi.vertical_adapt", - value: "vertical_adapt" -}, { - pId: 1, - text: "bi.inline_vertical_adapt", - value: "inline_vertical_adapt" + value: "demo.vertical_adapt" }, { pId: 1, text: "bi.horizontal_adapt", - value: "horizontal_adapt" + value: "demo.horizontal_adapt" }, { pId: 1, text: "bi.horizontal_auto", - value: "horizontal_auto" + value: "demo.horizontal_auto" }, { pId: 1, text: "bi.horizontal_float", - value: "horizontal_float" + value: "demo.horizontal_float" }, { pId: 1, text: "bi.left_right_vertical_adapt", - value: "left_right_vertical_adapt" + value: "demo.left_right_vertical_adapt" }, { pId: 1, text: "bi.center", - value: "center" + value: "demo.center_layout" }, { pId: 1, text: "bi.float_center", - value: "float_center" + value: "demo.float_center" }, { pId: 1, text: "bi.vertical", - value: "vertical" + value: "demo.vertical" }, { pId: 1, text: "bi.horizontal", - value: "horizontal" + value: "demo.horizontal" }, { pId: 1, text: "bi.border", - value: "border" -}, { - pId: 1, - text: "bi.card", - value: "card" + value: "demo.border" }, { pId: 1, text: "bi.left, bi.right", - value: "flow" -}, { - pId: 1, - text: "bi.lattice", - value: "lattice" + value: "demo.flow" }, { pId: 1, text: "bi.inline", - value: "inline" + value: "demo.inline" }, { pId: 1, text: "bi.htape", - value: "htape" + value: "demo.htape" }, { pId: 1, text: "bi.vtape", - value: "vtape" + value: "demo.vtape" }, { pId: 1, text: "bi.grid", - value: "grid" + value: "demo.grid" }, { pId: 1, text: "bi.table", - value: "table" -}, { - pId: 1, - text: "bi.division", - value: "division" -}, { - pId: 1, - text: "bi.window", - value: "window" + value: "demo.table_layout" }, { pId: 1, text: "bi.td", - value: "td" + value: "demo.td" }]; \ No newline at end of file diff --git a/demo/js/layout/demo.border.js b/demo/js/layout/demo.border.js new file mode 100644 index 000000000..0391d51fa --- /dev/null +++ b/demo/js/layout/demo.border.js @@ -0,0 +1,97 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.BorderLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-border" + }, + + _createNorth: function(){ + return BI.createWidget({ + type: "bi.label", + text: "North", + cls: "layout-bg1", + height: 30 + }) + }, + + _createWest: function(){ + return BI.createWidget({ + type: "bi.center", + cls: "layout-bg2", + items:[{ + type: "bi.label", + text: "West", + whiteSpace: "normal" + }] + }) + }, + + _createCenter: function(){ + return BI.createWidget({ + type: "bi.center", + cls: "layout-bg3", + items: [{ + type: "bi.label", + text: "Center", + whiteSpace: "normal" + }] + }) + }, + + _createEast: function(){ + return BI.createWidget({ + type: "bi.center", + cls: "layout-bg5", + items: [{ + type: "bi.label", + text: "East", + whiteSpace: "normal" + }] + }) + }, + + _createSouth: function(){ + return BI.createWidget({ + type: "bi.label", + text: "South", + cls: "layout-bg6", + height: 50 + }) + }, + + render: function () { + return { + type: "bi.border", + cls: "", + items: { + north: { + el: this._createNorth(), + height: 30, + top: 20, + left: 20, + right: 20 + }, + south: { + el: this._createSouth(), + height: 50, + bottom: 20, + left: 20, + right: 20 + }, + west: { + el: this._createWest(), + width: 200, + left: 20 + }, + east: { + el: this._createEast(), + width: 300, + right: 20 + }, + center: this._createCenter() + } + } + } +}); +$.shortcut("demo.border", Demo.BorderLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.center.js b/demo/js/layout/demo.center.js new file mode 100644 index 000000000..d33893622 --- /dev/null +++ b/demo/js/layout/demo.center.js @@ -0,0 +1,35 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.CenterLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-center" + }, + render: function () { + return { + type: "bi.center", + items: [{ + type: "bi.label", + text: "Center 1,这里虽然设置label的高度30,但是最终影响高度的是center布局", + cls: "layout-bg1", + whiteSpace: "normal" + },{ + type: "bi.label", + text: "Center 2,为了演示label是占满整个的,用了一个whiteSpace:normal", + cls: "layout-bg2", + whiteSpace: "normal" + },{ + type: "bi.label", + text: "Center 3", + cls: "layout-bg3" + },{ + type: "bi.label", + text: "Center 4", + cls: "layout-bg5" + }], + hgap: 20, + vgap: 20 + } + } +}); +$.shortcut("demo.center_layout", Demo.CenterLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.float_center.js b/demo/js/layout/demo.float_center.js new file mode 100644 index 000000000..248af4e80 --- /dev/null +++ b/demo/js/layout/demo.float_center.js @@ -0,0 +1,27 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.FloatCenterLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-float-center" + }, + render: function () { + return { + type: "bi.float_center", + items: [{ + type: "bi.label", + text: "floatCenter与center的不同在于,它可以控制最小宽度和最大宽度", + cls: "layout-bg1", + whiteSpace: "normal" + }, { + type: "bi.label", + text: "floatCenter与center的不同在于,它可以控制最小宽度和最大宽度", + cls: "layout-bg2", + whiteSpace: "normal" + }], + hgap: 20, + vgap: 20 + } + } +}); +$.shortcut("demo.float_center", Demo.FloatCenterLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.flow.js b/demo/js/layout/demo.flow.js new file mode 100644 index 000000000..4c0811486 --- /dev/null +++ b/demo/js/layout/demo.flow.js @@ -0,0 +1,85 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.FlowLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-flow" + }, + render: function () { + return { + type: "bi.center_adapt", + items: [{ + type: "bi.left", + items: [{ + type: "bi.label", + height: 30, + text: "Left-1", + cls: "layout-bg1", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Left-2", + cls: "layout-bg2", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Left-3", + cls: "layout-bg3", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Left-4", + cls: "layout-bg4", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Left-5", + cls: "layout-bg5", + hgap: 20 + }], + hgap: 20, + vgap: 20 + }, { + type: "bi.right", + items: [{ + type: "bi.label", + height: 30, + text: "Right-1", + cls: "layout-bg1", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Right-2", + cls: "layout-bg2", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Right-3", + cls: "layout-bg3", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Right-4", + cls: "layout-bg4", + hgap: 20 + }, { + type: "bi.label", + height: 30, + text: "Right-5", + cls: "layout-bg5", + hgap: 20 + }], + hgap: 20, + vgap: 20 + }] + } + } +}); +$.shortcut("demo.flow", Demo.FlowLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.grid.js b/demo/js/layout/demo.grid.js new file mode 100644 index 000000000..0b8aeb53c --- /dev/null +++ b/demo/js/layout/demo.grid.js @@ -0,0 +1,137 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.GridLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-grid" + }, + render: function () { + return { + type: "bi.grid", + columns: 5, + rows: 3, + items: [{ + column: 0, + row: 0, + el: { + type: "bi.label", + text: "column-0, row-0", + cls: "layout-bg1" + } + }, { + column: 1, + row: 0, + el: { + type: "bi.label", + text: "column-1, row-0", + cls: "layout-bg2" + } + }, { + column: 2, + row: 0, + el: { + type: "bi.label", + text: "column-2, row-0", + cls: "layout-bg6" + } + }, { + column: 3, + row: 0, + el: { + type: "bi.label", + text: "column-3, row-0", + cls: "layout-bg3" + } + }, { + column: 4, + row: 0, + el: { + type: "bi.label", + text: "column-4, row-0", + cls: "layout-bg4" + } + }, { + column: 0, + row: 1, + el: { + type: "bi.label", + text: "column-0, row-1", + cls: "layout-bg5" + } + }, { + column: 1, + row: 1, + el: { + type: "bi.label", + text: "column-1, row-1", + cls: "layout-bg6" + } + }, { + column: 2, + row: 1, + el: { + type: "bi.label", + text: "column-2, row-1", + cls: "layout-bg7" + } + }, { + column: 3, + row: 1, + el: { + type: "bi.label", + text: "column-3, row-1", + cls: "layout-bg1" + } + }, { + column: 4, + row: 1, + el: { + type: "bi.label", + text: "column-4, row-1", + cls: "layout-bg3" + } + }, { + column: 0, + row: 2, + el: { + type: "bi.label", + text: "column-0, row-2", + cls: "layout-bg2" + } + }, { + column: 1, + row: 2, + el: { + type: "bi.label", + text: "column-1, row-2", + cls: "layout-bg3" + } + }, { + column: 2, + row: 2, + el: { + type: "bi.label", + text: "column-2, row-2", + cls: "layout-bg4" + } + }, { + column: 3, + row: 2, + el: { + type: "bi.label", + text: "column-3, row-2", + cls: "layout-bg5" + } + }, { + column: 4, + row: 2, + el: { + type: "bi.label", + text: "column-4, row-2", + cls: "layout-bg6" + } + }] + } + } +}); +$.shortcut("demo.grid", Demo.GridLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.horizontal.js b/demo/js/layout/demo.horizontal.js new file mode 100644 index 000000000..5662ffb9b --- /dev/null +++ b/demo/js/layout/demo.horizontal.js @@ -0,0 +1,50 @@ +/** + * Created by User on 2017/3/21. + */ +Demo.Horizontal = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-horizontal" + }, + render: function () { + return { + type: "bi.vertical", + items: [{ + type: "bi.horizontal", + items: [{ + type: "bi.absolute", + items: [{ + el: { + type: "bi.text_button", + cls: "layout-bg1", + text: "这里设置了lgap(左边距),rgap(右边距),tgap(上边距),bgap(下边距)这里设置了lgap(左边距),rgap(右边距),tgap(上边距),bgap(下边距)", + height: 30 + }, + left: 0, + right: 0 + }], + width: 100, + height: 30 + }, { + type: "bi.absolute", + items: [{ + el: { + type: "bi.text_button", + cls: "layout-bg2", + text: "这里设置了lgap(左边距),rgap(右边距),tgap(上边距),bgap(下边距)这里设置了lgap(左边距),rgap(右边距),tgap(上边距),bgap(下边距)", + height: 30 + }, + left: 0, + right: 0 + }], + width: 200, + height: 30 + }] + }], + lgap: 20, + rgap: 80, + tgap: 80, + bgap: 50 + } + } +}); +$.shortcut("demo.horizontal", Demo.Horizontal); \ No newline at end of file diff --git a/demo/js/layout/demo.horizontal_adapt.js b/demo/js/layout/demo.horizontal_adapt.js new file mode 100644 index 000000000..8688906ce --- /dev/null +++ b/demo/js/layout/demo.horizontal_adapt.js @@ -0,0 +1,42 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.HorizontalAdapt = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-horizontal-adapt" + }, + + _createLayout: function () { + return BI.createWidget({ + type: "bi.horizontal_adapt", + vgap: 10, + items: [{ + type: "bi.label", + text: "Horizontal Adapt左右自适应", + cls: "layout-bg1", + width: 300, + height: 30 + }, { + type: "bi.label", + text: "Horizontal Adapt左右自适应", + cls: "layout-bg2", + //width: 300, + height: 30 + }] + }) + }, + + render: function () { + return { + type: "bi.grid", + columns: 1, + rows: 2, + items: [{ + column: 0, + row: 0, + el: this._createLayout() + }] + } + } +}); +$.shortcut("demo.horizontal_adapt", Demo.HorizontalAdapt); \ No newline at end of file diff --git a/demo/js/layout/demo.horizontal_auto.js b/demo/js/layout/demo.horizontal_auto.js new file mode 100644 index 000000000..a4837d609 --- /dev/null +++ b/demo/js/layout/demo.horizontal_auto.js @@ -0,0 +1,42 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.HorizontalAuto = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-horizontal-auto" + }, + + _createLayout: function () { + return BI.createWidget({ + type: "bi.horizontal_auto", + vgap: 10, + items: [{ + type: "bi.label", + text: "Horizontal Auto左右自适应", + cls: "layout-bg1", + width: 300, + height: 30 + }, { + type: "bi.label", + text: "Horizontal Auto左右自适应", + cls: "layout-bg2", + width: 300, + height: 30 + }] + }) + }, + + render: function () { + return { + type: "bi.grid", + columns: 1, + rows: 2, + items: [{ + column: 0, + row: 0, + el: this._createLayout() + }] + } + } +}); +$.shortcut("demo.horizontal_auto", Demo.HorizontalAuto); \ No newline at end of file diff --git a/demo/js/layout/demo.horizontal_float.js b/demo/js/layout/demo.horizontal_float.js new file mode 100644 index 000000000..217b832af --- /dev/null +++ b/demo/js/layout/demo.horizontal_float.js @@ -0,0 +1,35 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.HorizontalFloat = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-horizontal-float" + }, + + _createLayout: function () { + return BI.createWidget({ + type: "bi.horizontal_float", + vgap: 10, + items: [{ + type: "bi.label", + text: "Horizontal Float左右自适应", + cls: "layout-bg1", + width: 100 + }] + }) + }, + + render: function () { + return { + type: "bi.grid", + columns: 1, + rows: 2, + items: [{ + column: 0, + row: 0, + el: this._createLayout() + }] + } + } +}); +$.shortcut("demo.horizontal_float", Demo.HorizontalFloat); \ No newline at end of file diff --git a/demo/js/layout/demo.htape.js b/demo/js/layout/demo.htape.js new file mode 100644 index 000000000..fddfa2ca4 --- /dev/null +++ b/demo/js/layout/demo.htape.js @@ -0,0 +1,38 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.HtapeLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-htape" + }, + render: function () { + return { + type: "bi.htape", + items : [ + { + width: 100, + el : { + type : 'bi.label', + text : '1', + cls: "layout-bg1" + } + }, { + width: 200, + el : { + type : 'bi.label', + text : '2', + cls: "layout-bg2" + } + }, { + width: 'fill', + el : { + type : 'bi.label', + text : '3', + cls: "layout-bg3" + } + } + ] + } + } +}); +$.shortcut("demo.htape", Demo.HtapeLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.inline.js b/demo/js/layout/demo.inline.js new file mode 100644 index 000000000..d3bde0799 --- /dev/null +++ b/demo/js/layout/demo.inline.js @@ -0,0 +1,47 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.InlineLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-inline" + }, + render: function () { + return { + type: "bi.inline", + items: [{ + type: "bi.label", + height: 30, + text: "Left-1", + cls: "layout-bg1", + hgap: 200 + }, { + type: "bi.label", + height: 30, + text: "Left-2", + cls: "layout-bg2", + hgap: 200 + }, { + type: "bi.label", + height: 30, + text: "Left-3", + cls: "layout-bg3", + hgap: 200 + }, { + type: "bi.label", + height: 30, + text: "Left-4", + cls: "layout-bg4", + hgap: 200 + }, { + type: "bi.label", + height: 30, + text: "Left-5", + cls: "layout-bg5", + hgap: 200 + }], + hgap: 20, + vgap: 20 + } + } +}); +$.shortcut("demo.inline", Demo.InlineLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.left_right_vertical_adapt.js b/demo/js/layout/demo.left_right_vertical_adapt.js new file mode 100644 index 000000000..c92d3a9ea --- /dev/null +++ b/demo/js/layout/demo.left_right_vertical_adapt.js @@ -0,0 +1,44 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.LeftRightVerticalAdaptLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-left-right-vertical-adapt" + }, + render: function () { + return { + type: "bi.left_right_vertical_adapt", + lhgap: 10, + rhgap: 30, + items: { + left: [{ + type: "bi.label", + text: "左边的垂直居中", + cls: "layout-bg1", + width: 100, + height: 30 + }, { + type: "bi.label", + text: "左边的垂直居中", + cls: "layout-bg2", + width: 100, + height: 30 + }], + right: [{ + type: "bi.label", + text: "右边的垂直居中", + cls: "layout-bg1", + width: 100, + height: 30 + }, { + type: "bi.label", + text: "右边的垂直居中", + cls: "layout-bg2", + width: 100, + height: 30 + }] + } + } + } +}); +$.shortcut("demo.left_right_vertical_adapt", Demo.LeftRightVerticalAdaptLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.table.js b/demo/js/layout/demo.table.js new file mode 100644 index 000000000..617735556 --- /dev/null +++ b/demo/js/layout/demo.table.js @@ -0,0 +1,162 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.TableLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-table-layout" + }, + + _createTable1: function () { + return { + type: "bi.table", + items: BI.createItems([ + [ + { + el: { + cls: "layout-bg1" + } + }, + { + el: { + cls: "layout-bg2" + } + }, + { + el: { + cls: "layout-bg3" + } + } + ], + [ + { + el: { + cls: "layout-bg4" + } + }, + { + el: { + cls: "layout-bg5" + } + }, + { + el: { + cls: "layout-bg6" + } + } + ], + [ + { + el: { + cls: "layout-bg7" + } + }, + { + el: { + cls: "layout-bg8" + } + }, + { + el: { + cls: "layout-bg1" + } + } + ], + [ + { + el: { + cls: "layout-bg2" + } + }, + { + el: { + cls: "layout-bg3" + } + }, + { + el: { + cls: "layout-bg4" + } + } + ], + [ + { + el: { + cls: "layout-bg5" + } + }, + { + el: { + cls: "layout-bg6" + } + }, + { + el: { + cls: "layout-bg7" + } + } + ], + [ + { + el: { + cls: "layout-bg8" + } + }, + { + el: { + cls: "layout-bg1" + } + }, + { + el: { + cls: "layout-bg2" + } + } + ], + [ + { + el: { + cls: "layout-bg6" + } + }, + { + el: { + cls: "layout-bg7" + } + }, + { + el: { + cls: "layout-bg8" + } + } + ] + ], { + type: "bi.layout" + }), + columnSize: [100, "fill", 200], + rowSize: [10, 30, 50, 70, 90, 110, 130], + hgap: 20, + vgap: 10 + } + }, + + render: function () { + return { + type: "bi.grid", + columns: 1, + rows: 1, + items: [ + { + column: 0, + row: 0, + el: this._createTable1() + } + //, { + // column: 0, + // row: 1, + // el: this._createTable2() + //} + ] + } + } +}); +$.shortcut("demo.table_layout", Demo.TableLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.td.js b/demo/js/layout/demo.td.js new file mode 100644 index 000000000..2b21f41fb --- /dev/null +++ b/demo/js/layout/demo.td.js @@ -0,0 +1,59 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.TdLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-td" + }, + render: function () { + return { + type: "bi.vertical", + items: [{ + type: "bi.td", + columnSize: [100, 100, ""], + items: BI.createItems([ + [{ + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg1" + } + }, { + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg2" + } + }, { + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg3" + } + }], [{ + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg5" + } + }, { + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg6" + } + }, { + el: { + type: 'bi.label', + text: '这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写', + cls: "layout-bg7" + } + }] + ], { + whiteSpace: "normal" + }) + }] + } + } +}); +$.shortcut("demo.td", Demo.TdLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.vertical.js b/demo/js/layout/demo.vertical.js new file mode 100644 index 000000000..19d18fb6a --- /dev/null +++ b/demo/js/layout/demo.vertical.js @@ -0,0 +1,25 @@ +/** + * Created by User on 2017/3/21. + */ +Demo.VerticalLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-vertical" + }, + render: function () { + return { + type: "bi.vertical", + items: [{ + type: "bi.label", + cls: "layout-bg1", + text: "这里设置了hgap(水平间距),vgap(垂直间距)", + height: 30 + }, { + type: "bi.label", + cls: "layout-bg2", + text: "这里设置了hgap(水平间距),vgap(垂直间距)", + height: 30 + }] + } + } +}); +$.shortcut("demo.vertical", Demo.VerticalLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.vertical_adapt.js b/demo/js/layout/demo.vertical_adapt.js new file mode 100644 index 000000000..dc030e756 --- /dev/null +++ b/demo/js/layout/demo.vertical_adapt.js @@ -0,0 +1,42 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.VerticalAdaptLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-vertical-adapt" + }, + + _createLayout: function () { + return BI.createWidget({ + type: "bi.vertical_adapt", + vgap: 10, + items: [{ + type: "bi.label", + text: "Vertical Adapt上下自适应", + cls: "layout-bg1", + width: 300, + height: 30 + }, { + type: "bi.label", + text: "Vertical Adapt上下自适应", + cls: "layout-bg2", + width: 300, + height: 30 + }] + }) + }, + + render: function () { + return { + type: "bi.grid", + columns: 2, + rows: 1, + items: [{ + column: 0, + row: 0, + el: this._createLayout() + }] + } + } +}); +$.shortcut("demo.vertical_adapt", Demo.VerticalAdaptLayout); \ No newline at end of file diff --git a/demo/js/layout/demo.vtape.js b/demo/js/layout/demo.vtape.js new file mode 100644 index 000000000..6309482f8 --- /dev/null +++ b/demo/js/layout/demo.vtape.js @@ -0,0 +1,38 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.VtapeLayout = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-vtape" + }, + render: function () { + return { + type: "bi.vtape", + items : [ + { + height: 100, + el : { + type : 'bi.label', + text : '1', + cls: "layout-bg1" + } + }, { + height: 200, + el : { + type : 'bi.label', + text : '2', + cls: "layout-bg2" + } + }, { + height: 'fill', + el : { + type : 'bi.label', + text : '3', + cls: "layout-bg3" + } + } + ] + } + } +}); +$.shortcut("demo.vtape", Demo.VtapeLayout); \ No newline at end of file diff --git a/dist/core.css b/dist/core.css index 485d2d341..c533d6120 100644 --- a/dist/core.css +++ b/dist/core.css @@ -9807,7 +9807,7 @@ textarea::-webkit-scrollbar-thumb { /**** custom color(自定义颜色,用于特定场景) ****/ @font-face { font-family: 'bi'; - src: url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.woff') format('woff'), /* chrome、firefox */ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.svg#svgFontName') format('svg'); + src: url('font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('font/iconfont.woff') format('woff'), /* chrome、firefox */ url('font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('font/iconfont.svg#svgFontName') format('svg'); /* iOS 4.1- */ } diff --git a/dist/core.js b/dist/core.js index 806cd26fd..386c8eeb1 100644 --- a/dist/core.js +++ b/dist/core.js @@ -24841,7 +24841,7 @@ BI.FloatHorizontalLayout = BI.inherit(BI.Layout, { var self = this, o = this.options; this.left = BI.createWidget({ type: "bi.vertical", - items: items, + items: [item], hgap: o.hgap, vgap: o.vgap, tgap: o.tgap, @@ -24856,7 +24856,7 @@ BI.FloatHorizontalLayout = BI.inherit(BI.Layout, { items: [this.left] }); - return left; + return this.left; }, populate: function (items) { diff --git a/src/core/wrapper/layout/adapt/float.horizontal.js b/src/core/wrapper/layout/adapt/float.horizontal.js index 261ebc018..5d9044504 100644 --- a/src/core/wrapper/layout/adapt/float.horizontal.js +++ b/src/core/wrapper/layout/adapt/float.horizontal.js @@ -39,7 +39,7 @@ BI.FloatHorizontalLayout = BI.inherit(BI.Layout, { var self = this, o = this.options; this.left = BI.createWidget({ type: "bi.vertical", - items: items, + items: [item], hgap: o.hgap, vgap: o.vgap, tgap: o.tgap, @@ -54,7 +54,7 @@ BI.FloatHorizontalLayout = BI.inherit(BI.Layout, { items: [this.left] }); - return left; + return this.left; }, populate: function (items) { diff --git a/src/css/utils/widget.css b/src/css/utils/widget.css index cc3812b8d..0ccd6dba8 100644 --- a/src/css/utils/widget.css +++ b/src/css/utils/widget.css @@ -3,7 +3,7 @@ /**** custom color(自定义颜色,用于特定场景) ****/ @font-face { font-family: 'bi'; - src: url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.woff') format('woff'), /* chrome、firefox */ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('${servletURL}?op=resource&resource=/com/fr/bi/web/resources/fonts/iconfont.svg#svgFontName') format('svg'); + src: url('font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('font/iconfont.woff') format('woff'), /* chrome、firefox */ url('font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('font/iconfont.svg#svgFontName') format('svg'); /* iOS 4.1- */ } From 19d30ca18396b86a7db205366e8cce9674011da6 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 11:13:26 +0800 Subject: [PATCH 03/19] =?UTF-8?q?base=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/js/base/demo.canvas.js | 3 + demo/js/base/demo.collection.js | 3 + demo/js/base/demo.combo.js | 3 + demo/js/config/base.js | 172 +++++++++++++++++++++++++++++++- 4 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 demo/js/base/demo.canvas.js create mode 100644 demo/js/base/demo.collection.js create mode 100644 demo/js/base/demo.combo.js diff --git a/demo/js/base/demo.canvas.js b/demo/js/base/demo.canvas.js new file mode 100644 index 000000000..879f44652 --- /dev/null +++ b/demo/js/base/demo.canvas.js @@ -0,0 +1,3 @@ +/** + * Created by User on 2017/3/22. + */ diff --git a/demo/js/base/demo.collection.js b/demo/js/base/demo.collection.js new file mode 100644 index 000000000..879f44652 --- /dev/null +++ b/demo/js/base/demo.collection.js @@ -0,0 +1,3 @@ +/** + * Created by User on 2017/3/22. + */ diff --git a/demo/js/base/demo.combo.js b/demo/js/base/demo.combo.js new file mode 100644 index 000000000..879f44652 --- /dev/null +++ b/demo/js/base/demo.combo.js @@ -0,0 +1,3 @@ +/** + * Created by User on 2017/3/22. + */ diff --git a/demo/js/config/base.js b/demo/js/config/base.js index 59fe9506d..062d3e16f 100644 --- a/demo/js/config/base.js +++ b/demo/js/config/base.js @@ -3,6 +3,174 @@ Demo.BASE_CONFIG = [{ text: "基础控件" }, { pId: 2, - text: "bi.center_adapt", - value: "demo.center_adapt" + id: 5, + text: "组合" +}, { + pId: 2, + id: 8, + text: "tree" +}, { + pId: 2, + id: 7, + text: "button" +}, { + pId: 2, + id: 9, + text: "listitem" +}, { + pId: 2, + id: 10, + text: "editor" +}, { + pId: 2, + text: "bi.canvas", + value: "demo.canvas" +}, { + pId: 2, + text: "bi.label", + value: "demo.label" +}, { + pId: 2, + text: "bi.collection", + value: "demo.collection" +}, { + pId: 2, + text: "bi.farbtastic", + value: "demo.farbtastic" +}, { + pId: 2, + text: "bi.formulaeditor", + value: "demo.formulaeditor" +}, { + pId: 2, + text: "bi.message", + value: "demo.message" +}, { + pId: 2, + text: "bi.grid_view", + value: "demo.grid_view" +}, { + pId: 2, + id: 6, + text: "弹出层" +}, { + pId: 2, + text: "bi.pager", + value: "demo.pager" +}, { + pId: 2, + text: "bi.svg", + value: "demo.svg" +}, { + pId: 2, + text: "bi.table", + value: "demo.table" +}, { + pId: 5, + text: "bi.combo", + value: "demo.combo" +}, { + pId: 5, + text: "bi.expander", + value: "demo.expander" +}, { + pId: 5, + text: "bi.group_button", + value: "demo.group_button" +}, { + pId: 5, + text: "bi.group_combo", + value: "demo.group_combo" +}, { + pId: 5, + text: "bi.loader", + value: "demo.loader" +}, { + pId: 5, + text: "bi.navigation", + value: "demo.navigation" +}, { + pId: 5, + text: "bi.searcher", + value: "demo.searcher" +}, { + pId: 5, + text: "bi.switcher", + value: "demo.switcher" +}, { + pId: 5, + text: "bi.tab", + value: "demo.tab" +}, { + pId: 5, + text: "bi.tree_button", + value: "demo.tree_button" +}, { + pId: 6, + text: "bi.layer_float_box", + value: "demo.layer_float_box" +}, { + pId: 6, + text: "bi.layer_popup", + value: "demo.layer_popup" +}, { + pId: 6, + text: "bi.layer_scroll", + value: "demo.layer_scroll" +}, { + pId: 6, + text: "bi.layer_searcher", + value: "demo.layer_searcher" +}, { + pId: 7, + text: "bi.icon_button", + value: "demo.icon_button" +}, { + pId: 7, + text: "bi.image_button", + value: "demo.image_button" +}, { + pId: 7, + text: "bi.button", + value: "demo.button" +}, { + pId: 7, + text: "bi.text_button", + value: "demo.text_button" +}, { + pId: 8, + text: "bi.treeview", + value: "demo.treeview" +}, { + pId: 8, + text: "bi.synctree", + value: "demo.synctree" +}, { + pId: 8, + text: "bi.parttree", + value: "demo.parttree" +}, { + pId: 8, + text: "bi.customtree", + value: "demo.customtree" +}, { + pId: 9, + text: "bi.list_items", + value: "demo.list_items" +}, { + pId: 10, + text: "bi.code_editor", + value: "demo.code_editor" +}, { + pId: 10, + text: "bi.editor", + value: "demo.editor" +}, { + pId: 10, + text: "bi.multifile_editor", + value: "demo.multifile_editor" +}, { + pId: 10, + text: "bi.text_area_editor", + value: "demo.text_area_editor" }]; \ No newline at end of file From 23473d602e81cb2ceadd5193f74276fc71ffe4bc Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 11:15:08 +0800 Subject: [PATCH 04/19] add --- src/core/proto/jquery.js | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/core/proto/jquery.js diff --git a/src/core/proto/jquery.js b/src/core/proto/jquery.js new file mode 100644 index 000000000..408285a4f --- /dev/null +++ b/src/core/proto/jquery.js @@ -0,0 +1,61 @@ +/*! + * jLayout JQuery Plugin v0.11 + * + * Licensed under the revised BSD License. + * Copyright 2008, Bram Stein + * All rights reserved. + */ +if (jQuery) { + (function($){ + // richer:容器在其各个边缘留出的空间 + $.fn.insets = function () { + var p = this.padding(), + b = this.border(); + return { + 'top': p.top, + 'bottom': p.bottom + b.bottom + b.top, + 'left': p.left, + 'right': p.right + b.right + b.left + }; + }; + + // richer:获取 && 设置jQuery元素的边界 + $.fn.bounds = function (value) { + var tmp = {hasIgnoredBounds : true}; + + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + return this; + } + else { + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + return { + 'x': tmp.left, + 'y': tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + 'width': this.outerWidth(), + 'height': this.outerHeight() + }; + } + }; + })(jQuery); +}; \ No newline at end of file From ade1c308ad8f75e8c1dccbf1d7cfc8b4778dbff3 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 11:41:38 +0800 Subject: [PATCH 05/19] update --- demo/js/config/case.js | 114 ++++++++++++- demo/js/config/widget.js | 354 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 462 insertions(+), 6 deletions(-) diff --git a/demo/js/config/case.js b/demo/js/config/case.js index 8d026337e..9dd8c9da8 100644 --- a/demo/js/config/case.js +++ b/demo/js/config/case.js @@ -1,8 +1,116 @@ Demo.CASE_CONFIG = [{ id: 3, - text: "基础控件" + text: "实例控件" }, { pId: 3, - text: "bi.center_adapt", - value: "demo.center_adapt" + text: "bi.calendar", + value: "demo.calendar" +}, { + pId: 3, + text: "bi.zclip", + value: "demo.zclip" +}, { + pId: 3, + text: "bi.complex_calendar", + value: "demo.complex_calendar" +}, { + pId: 3, + text: "bi.calendar", + value: "demo.calendar" +}, { + pId: 3, + text: "bi.colorpicker", + value: "demo.colorpicker" +}, { + pId: 3, + text: "bi.bubble_combo", + value: "demo.bubble_combo" +}, { + pId: 3, + id: 11, + text: "editors" +}, { + pId: 11, + text: "bi.record_editor", + value: "demo.record_editor" +}, { + pId: 11, + text: "bi.shelter_editor", + value: "demo.shelter_editor" +}, { + pId: 11, + text: "bi.sign_editor", + value: "demo.sign_editor" +}, { + pId: 11, + text: "bi.state_editor", + value: "demo.state_editor" +}, { + pId: 3, + text: "各种checkbox", + value: "demo.checkboxes" +}, { + pId: 3, + text: "各种tip", + value: "demo.tips" +}, { + pId: 3, + text: "bi.branch_expander", + value: "demo.branch_expander" +}, { + pId: 3, + text: "bi.float_box", + value: "demo.float_box" +}, { + pId: 3, + text: "bi.float_box", + value: "demo.float_box" +}, { + pId: 3, + text: "bi.segment", + value: "demo.segment" +}, { + pId: 3, + id: 12, + text: "各种表格" +}, { + pId: 3, + id: 13, + text: "各种tree" +}, { + pId: 3, + text: "各种trigger", + value: "demo.triggers" +}, { + pId: 12, + text: "bi.adaptive_table", + value: "demo.adaptive_table" +}, { + pId: 12, + text: "bi.table_tree", + value: "demo.table_tree" +}, { + pId: 12, + text: "bi.layer_tree_table", + value: "demo.layer_tree_table" +}, { + pId: 13, + text: "bi.branch_tree", + value: "demo.branch_tree" +}, { + pId: 13, + text: "bi.display_tree", + value: "demo.display_tree" +}, { + pId: 13, + text: "bi.level_tree", + value: "demo.level_tree" +}, { + pId: 13, + text: "bi.simple_tree", + value: "demo.simple_tree" +}, { + pId: 13, + text: "bi.handstand_branch_tree", + value: "demo.handstand_branch_tree" }]; \ No newline at end of file diff --git a/demo/js/config/widget.js b/demo/js/config/widget.js index 4f9e86d2c..ea6f07a0f 100644 --- a/demo/js/config/widget.js +++ b/demo/js/config/widget.js @@ -1,8 +1,356 @@ Demo.WIDGET_CONFIG = [{ id: 4, - text: "基础控件" + text: "详细控件" }, { pId: 4, - text: "bi.center_adapt", - value: "demo.center_adapt" + text: "bi.loading_mask", + value: "demo.loadingmask" +}, { + pId: 4, + text: "可以切换的树", + value: "demo.switch_tree" +}, { + pId: 4, + text: "进度条", + value: "demo.progressbar" +}, { + pId: 4, + text: "bi.text_editor", + value: "demo.text_editor" +}, { + pId: 4, + text: "bi.search_editor", + value: "demo.search_editor" +}, { + pId: 4, + text: "bi.adapt_editor", + value: "demo.adapt_editor" +}, { + pId: 4, + text: "bi.sign_initial_editor", + value: "demo.sign_initial_editor" +}, { + pId: 4, + text: "bi.sign_style_editor", + value: "demo.sign_style_editor" +}, { + pId: 4, + text: "bi.year_combo", + value: "demo.year_combo" +}, { + pId: 4, + text: "bi.month_combo", + value: "demo.month_combo" +}, { + pId: 4, + text: "bi.quarter_combo", + value: "demo.quarter_combo" +}, { + pId: 4, + text: "bi.date_combo", + value: "demo.date_combo" +}, { + pId: 4, + text: "bi.down_list_combo", + value: "demo.down_list_combo" +}, { + pId: 4, + text: "bi.text_value_combo", + value: "demo.text_icon_combo" +}, { + pId: 4, + text: "bi.static_combo", + value: "demo.single_select_combo" +}, { + pId: 4, + text: "bi.text_value_down_list_combo", + value: "demo.text_icon_down_list_combo" +}, { + pId: 4, + text: "bi.param_date_combo", + value: "demo.param_date_combo" +}, { + pId: 4, + text: "bi.icon_combo", + value: "demo.icon_combo" +}, { + pId: 4, + text: "bi.formula_combo", + value: "demo.formula_combo" +}, { + pId: 4, + text: "bi.formula_insert", + value: "demo.formula_insert" +}, { + pId: 4, + text: "bi.formula_pane", + value: "demo.formula_pane" +}, { + pId: 4, + text: "bi.select_data_tree", + value: "demo.select_data_tree" +}, { + pId: 4, + text: "bi.select_data_switcher", + value: "demo.select_data_switcher" +}, { + pId: 4, + text: "bi.select_data_search_result", + value: "demo.select_data_search_result" +}, { + pId: 4, + text: "bi.select_data_searcher(点这)", + value: "demo.select_data_searcher" +}, { + pId: 4, + text: "bi.multidate_combo", + value: "demo.multidate_combo" +}, { + pId: 4, + text: "bi.time_interval", + value: "demo.time_interval" +}, { + pId: 4, + text: "bi.numerical_interval", + value: "demo.numerical_interval" +}, { + pId: 4, + text: "bi.multi_select_trigger", + value: "demo.multi_select_trigger" +}, { + pId: 4, + text: "bi.multi_select_search_pane", + value: "demo.multi_select_search_pane" +}, { + pId: 4, + text: "bi.multi_select_popup_view", + value: "demo.multi_select_popup_view" +}, { + pId: 4, + text: "bi.multi_select_check_pane", + value: "demo.multi_select_check_pane" +}, { + pId: 4, + text: "bi.multi_select_combo", + value: "demo.multi_select_combo" +}, { + pId: 4, + text: "bi.move2group_combo", + value: "demo.move2group_combo" +}, { + pId: 4, + text: "bi.copy2group_combo", + value: "demo.copy2group_combo" +}, { + pId: 4, + text: "bi.single_tree_combo", + value: "demo.single_tree_combo" +}, { + pId: 4, + text: "bi.multilayer_single_tree_combo", + value: "demo.multilayer_single_tree_combo" +}, { + pId: 4, + text: "bi.select_tree_combo", + value: "demo.select_tree_combo" +}, { + pId: 4, + text: "bi.multilayer_select_tree_combo", + value: "demo.multilayer_select_tree_combo" +}, { + pId: 4, + text: "bi.dialog", + value: "demo.dialog" +}, { + pId: 4, + text: "bi.multi_tree", + value: "demo.multi_tree" +}, { + pId: 4, + text: "bi.simple_select_data_searcher", + value: "demo.simple_select_data_searcher" +}, { + pId: 4, + text: "bi.filter_pane", + value: "demo.filter_pane" +}, { + pId: 4, + text: "bi.filter_operation", + value: "demo.filter_operation" +}, { + pId: 4, + text: "bi.filter", + value: "demo.filter" +}, { + pId: 4, + text: "bi.color_chooser", + value: "demo.color_chooser" +}, { + pId: 4, + text: "bi.text_toolbar", + value: "demo.text_toolbar" +}, { + pId: 4, + text: "bi.text_area", + value: "demo.text_area" +}, { + pId: 4, + text: "bi.path_chooser", + value: "demo.path_chooser" +}, { + pId: 4, + text: "bi.direction_path_chooser", + value: "demo.direction_path_chooser" +}, { + pId: 4, + text: "bi.file_manager", + value: "demo.file_manager" +}, { + pId: 4, + text: "bi.branch_relation", + value: "demo.branch_relation" +}, { + pId: 4, + text: "bi.relation_view", + value: "demo.relation_view" +}, { + pId: 4, + text: "bi.preview_table", + value: "demo.preview_table" +}, { + pId: 4, + text: "bi.adaptive_table", + value: "demo.adaptive_table" +}, { + pId: 4, + text: "bi.adaptive_table(冻结表头)", + value: "demo.adaptive_table2" +}, { + pId: 4, + text: "bi.custom_scroll_table", + value: "demo.custom_scroll_table" +}, { + pId: 4, + text: "bi.page_table", + value: "demo.page_table" +}, { + pId: 4, + text: "bi.page_table(冻结)", + value: "demo.page_table2" +}, { + pId: 4, + text: "bi.page_table(调整列宽)", + value: "demo.page_table3" +}, { + pId: 4, + text: "bi.excel_table", + value: "demo.excel_table" +}, { + pId: 4, + text: "bi.sortable_table", + value: "demo.sortable_table" +}, { + pId: 4, + text: "bi.excel_view_display_manager", + value: "demo.excel_view_display_manager" +}, { + pId: 4, + text: "bi.sequence_table", + value: "demo.sequence_table" +}, { + pId: 4, + text: "bi.sequence_table(带有汇总)", + value: "demo.sequence_table2" +}, { + pId: 4, + text: "bi.upload_image", + value: "demo.upload_image" +}, { + pId: 4, + text: "bi.web_page", + value: "demo.web_page" +}, { + pId: 4, + text: "bi.arrangement_droppable", + value: "demo.arrangement_droppable" +}, { + pId: 4, + text: "bi.arrangement", + value: "demo.arrangement" +}, { + pId: 4, + text: "bi.adaptive_arrangement", + value: "demo.adaptive_arrangement" +}, { + pId: 4, + text: "bi.arrangement(网格布局)", + value: "demo.grid_arrangement" +}, { + pId: 4, + text: "bi.adaptive_arrangement(网格布局)", + value: "demo.grid_adaptive_arrangement" +}, { + pId: 4, + text: "bi.simple_searcher", + value: "demo.simple_searcher" +}, { + pId: 4, + text: "选色", + value: "demo.select_color_combo" +}, { + pId: 4, + text: "bi.detail_chart", + value: "demo.detail_chart" +}, { + pId: 4, + text: "柱形", + value: "demo.column_charts" +}, { + pId: 4, + text: "条形图", + value: "demo.bar_charts" +}, { + pId: 4, + text: "面积图", + value: "demo.area_charts" +}, { + pId: 4, + text: "其他", + value: "demo.other_charts" +}, { + pId: 4, + text: "文本标签", + value: "demo.list_label" +}, { + pId: 4, + text: "树标签", + value: "demo.tree_label" +}, { + pId: 4, + text: "滑块", + value: "demo.slider" +}, { + pId: 4, + text: "区间双滑块", + value: "demo.interval_slider" +}, { + pId: 4, + text: "文本列表", + value: "demo.string_list" +}, { + pId: 4, + text: "树列表", + value: "demo.tree_list" +}, { + pId: 4, + text: "日期面板", + value: "demo.data_pane" +}, { + pId: 4, + text: "螺旋分析tab控件", + value: "demo.dynamic_group_tab" +}, { + pId: 4, + text: "数值微调器", + value: "demo.finetuning_number_editor" }]; \ No newline at end of file From ff651268ce40aa7b5f3712da3732617693fc42ea Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 14:15:31 +0800 Subject: [PATCH 06/19] add --- src/core/status.js | 46 -------------------------------- src/core/var.js | 65 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 47 deletions(-) delete mode 100644 src/core/status.js diff --git a/src/core/status.js b/src/core/status.js deleted file mode 100644 index 88c226f92..000000000 --- a/src/core/status.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * guy - * 状态常量 - */ - -_.extend(BI, { - Status: { - SUCCESS: 1, - WRONG: 2, - START: 3, - END: 4, - WAITING: 5, - READY: 6, - RUNNING: 7, - OUTOFBOUNDS: 8, - NULL: -1 - }, - Direction: { - Top: "top", - Bottom: "bottom", - Left: "left", - Right: "right", - Custom: "custom" - }, - Axis: { - Vertical: "vertical", - Horizontal: "horizontal" - }, - Selection: { - Default: -999, - None: -1, - Single: 0, - Multi: 1, - All: 2 - }, - HorizontalAlign: { - Left: "left", - Right: "right", - Center: "center" - }, - VerticalAlign: { - Middle: "middle", - Top: "top", - Bottom: "bottom" - } -}); \ No newline at end of file diff --git a/src/core/var.js b/src/core/var.js index 66f7b7e59..91c1e6338 100644 --- a/src/core/var.js +++ b/src/core/var.js @@ -14,5 +14,68 @@ _.extend(BI, { emptyStr: "", emptyFn: function () { }, - empty: null + empty: null, + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + }, + Status: { + SUCCESS: 1, + WRONG: 2, + START: 3, + END: 4, + WAITING: 5, + READY: 6, + RUNNING: 7, + OUTOFBOUNDS: 8, + NULL: -1 + }, + Direction: { + Top: "top", + Bottom: "bottom", + Left: "left", + Right: "right", + Custom: "custom" + }, + Axis: { + Vertical: "vertical", + Horizontal: "horizontal" + }, + Selection: { + Default: -999, + None: -1, + Single: 0, + Multi: 1, + All: 2 + }, + HorizontalAlign: { + Left: "left", + Right: "right", + Center: "center" + }, + VerticalAlign: { + Middle: "middle", + Top: "top", + Bottom: "bottom" + } }); \ No newline at end of file From fbc1900ec410e55bb8c5d3829e211f9f53a4e912 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 15:03:18 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gruntfile.js | 6 + demo/js/base/demo.canvas.js | 3 - demo/js/base/demo.collection.js | 3 - demo/js/base/demo.combo.js | 3 - demo/js/config/widget.js | 348 - demo/js/widget/demo.multiselectcombo.js | 88 + demo/js/widget/demo.multiselecttree.js | 14 + dist/base.js | 34259 ++++++++++------ dist/core.js | 228 +- dist/icon/check-box-disable.png | Bin 0 -> 196 bytes dist/icon/check-box-normal.png | Bin 0 -> 198 bytes src/base/collection/collection.js | 14 +- src/base/combination/combo.js | 58 +- src/base/combination/expander.js | 11 +- src/base/combination/group.button.js | 6 +- src/base/combination/loader.js | 4 + src/base/combination/map.button.js | 115 + src/base/combination/navigation.js | 4 + src/base/combination/searcher.js | 29 +- src/base/combination/switcher.js | 4 +- src/base/combination/tab.js | 4 +- src/base/combination/tree.button.js | 118 +- src/base/farbtastic/farbtastic.js | 2 + .../formula/codemirror/addon/formula-hint.js | 88 + .../formula/codemirror/addon/formula-mode.js | 80 + .../formula/codemirror/addon/show-hint.js | 432 + src/base/formula/codemirror/codemirror.js | 8736 ++++ src/base/formula/formulaeditor.js | 11 +- src/base/foundation/bi.message.js | 21 +- src/base/grid/grid.js | 10 +- src/base/layer/layer.popup.js | 19 +- src/base/pager/pager.js | 20 +- src/base/pane.js | 2 +- src/base/reqloading/loading.request.js | 192 + src/base/single/a/a.js | 5 +- src/base/single/bar/bar.loading.js | 4 +- src/base/single/button/button.basic.js | 63 +- src/base/single/button/buttons/button.icon.js | 3 +- .../single/button/buttons/button.image.js | 3 +- src/base/single/button/buttons/button.text.js | 29 +- .../button/listitem/blankiconicontextitem.js | 119 + src/base/single/editor/editor.code.js | 4 +- src/base/single/editor/editor.js | 4 +- src/base/single/editor/editor.textarea.js | 85 +- src/base/single/img/img.js | 4 +- src/base/single/input/checkbox.js | 1 - src/base/single/input/file.js | 72 +- src/base/single/input/input.js | 60 +- src/base/single/input/radio.js | 1 - src/base/single/label/label.js | 44 +- src/base/single/text.js | 4 + src/base/timeouttoast/widget.timeouttoast.js | 117 + src/base/tree/{3parttree.js => parttree.js} | 0 src/base/tree/{2synctree.js => synctree.js} | 38 +- src/base/tree/{1treeview.js => treeview.js} | 21 +- src/core/base.js | 286 +- src/core/controller.js | 2 +- src/core/loader/loader.style.js | 47 + src/core/var.js | 2 +- src/core/wrapper/layout/layout.card.js | 6 +- src/css/base/base.css | 21 + src/css/base/chart/chart.combine.css | 11 + src/css/base/combo/popup.bubble.css | 11 + src/css/base/dom.css | 9 + src/css/base/logintimeout/login.timeout.css | 32 + src/css/base/pager/pager.all.count.css | 9 + src/css/base/pager/pager.direction.css | 2 - src/css/base/reqloading/loading.request.css | 10 +- src/css/base/single/editor/editor.state.css | 6 +- .../single/editor/editor.state.simple.css | 6 +- src/css/base/single/text.css | 2 +- src/css/base/third/ztree/zTreeStyle.css | 44 +- .../base/timeouttoast/widget.timeouttoast.css | 34 + src/css/base/view/popupview.css | 1 + src/css/base/wrapper/flex.center.css | 38 + src/css/base/wrapper/flex.horizontal.css | 66 + src/css/base/wrapper/flex.vertical.center.css | 46 + src/css/base/wrapper/flex.wrapper.center.css | 41 + .../base/wrapper/flex.wrapper.horizontal.css | 67 + .../wrapper/flex.wrapper.vertical.center.css | 48 + src/less/base/base.less | 24 + src/less/base/chart/chart.combine.less | 13 + src/less/base/combo/combo.bubble.less | 16 + src/less/base/combo/popup.bubble.less | 8 + src/less/base/dom.less | 7 + src/less/base/logintimeout/login.timeout.less | 30 + .../{pager.all.less => pager.all.count.less} | 5 +- src/less/base/pager/pager.direction.less | 2 - src/less/base/pager/pager.number.less | 12 - src/less/base/pager/pager.skip.less | 12 - src/less/base/reqloading/loading.request.less | 19 +- src/less/base/single/editor/editor.state.less | 4 +- .../single/editor/editor.state.simple.less | 4 +- src/less/base/single/text.less | 2 +- src/less/base/table/table.grid.scrollbar.less | 8 +- .../base/third/jquery.mCustomScrollbar.less | 1796 - src/less/base/third/ztree/img/line_conn.gif | Bin 0 -> 45 bytes src/less/base/third/ztree/img/loading.gif | Bin 0 -> 381 bytes .../base/third/ztree/img/zTreeStandard.gif | Bin 0 -> 5564 bytes .../base/third/ztree/img/zTreeStandard.png | Bin 0 -> 11173 bytes src/less/base/third/ztree/zTreeStyle.less | 46 +- .../timeouttoast/widget.timeouttoast.less | 25 + src/less/base/view/popupview.less | 1 + 103 files changed, 33588 insertions(+), 14906 deletions(-) delete mode 100644 demo/js/base/demo.canvas.js delete mode 100644 demo/js/base/demo.collection.js delete mode 100644 demo/js/base/demo.combo.js create mode 100644 demo/js/widget/demo.multiselectcombo.js create mode 100644 demo/js/widget/demo.multiselecttree.js create mode 100644 dist/icon/check-box-disable.png create mode 100644 dist/icon/check-box-normal.png create mode 100644 src/base/combination/map.button.js create mode 100644 src/base/formula/codemirror/addon/formula-hint.js create mode 100644 src/base/formula/codemirror/addon/formula-mode.js create mode 100644 src/base/formula/codemirror/addon/show-hint.js create mode 100644 src/base/formula/codemirror/codemirror.js create mode 100644 src/base/reqloading/loading.request.js create mode 100644 src/base/single/button/listitem/blankiconicontextitem.js create mode 100644 src/base/timeouttoast/widget.timeouttoast.js rename src/base/tree/{3parttree.js => parttree.js} (100%) rename src/base/tree/{2synctree.js => synctree.js} (87%) rename src/base/tree/{1treeview.js => treeview.js} (95%) create mode 100644 src/core/loader/loader.style.js create mode 100644 src/css/base/base.css create mode 100644 src/css/base/chart/chart.combine.css create mode 100644 src/css/base/combo/popup.bubble.css create mode 100644 src/css/base/dom.css create mode 100644 src/css/base/logintimeout/login.timeout.css create mode 100644 src/css/base/pager/pager.all.count.css create mode 100644 src/css/base/timeouttoast/widget.timeouttoast.css create mode 100644 src/css/base/wrapper/flex.center.css create mode 100644 src/css/base/wrapper/flex.horizontal.css create mode 100644 src/css/base/wrapper/flex.vertical.center.css create mode 100644 src/css/base/wrapper/flex.wrapper.center.css create mode 100644 src/css/base/wrapper/flex.wrapper.horizontal.css create mode 100644 src/css/base/wrapper/flex.wrapper.vertical.center.css create mode 100644 src/less/base/base.less create mode 100644 src/less/base/chart/chart.combine.less create mode 100644 src/less/base/combo/combo.bubble.less create mode 100644 src/less/base/combo/popup.bubble.less create mode 100644 src/less/base/dom.less create mode 100644 src/less/base/logintimeout/login.timeout.less rename src/less/base/pager/{pager.all.less => pager.all.count.less} (50%) delete mode 100644 src/less/base/pager/pager.number.less delete mode 100644 src/less/base/pager/pager.skip.less delete mode 100644 src/less/base/third/jquery.mCustomScrollbar.less create mode 100644 src/less/base/third/ztree/img/line_conn.gif create mode 100644 src/less/base/third/ztree/img/loading.gif create mode 100644 src/less/base/third/ztree/img/zTreeStandard.gif create mode 100644 src/less/base/third/ztree/img/zTreeStandard.png create mode 100644 src/less/base/timeouttoast/widget.timeouttoast.less diff --git a/Gruntfile.js b/Gruntfile.js index c7f4f3e1b..65acb4824 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -40,6 +40,12 @@ module.exports = function (grunt) { 'src/base/single/text.js', 'src/base/single/button/button.basic.js', 'src/base/single/button/button.node.js', + 'src/base/combination/group.button.js', + 'src/base/combination/tree.button.js', + 'src/base/combination/map.button.js', + 'src/base/tree/treeview.js', + 'src/base/tree/synctree.js', + 'src/base/tree/parttree.js', 'src/base/**/*.js' ], dest: 'dist/base.js' diff --git a/demo/js/base/demo.canvas.js b/demo/js/base/demo.canvas.js deleted file mode 100644 index 879f44652..000000000 --- a/demo/js/base/demo.canvas.js +++ /dev/null @@ -1,3 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ diff --git a/demo/js/base/demo.collection.js b/demo/js/base/demo.collection.js deleted file mode 100644 index 879f44652..000000000 --- a/demo/js/base/demo.collection.js +++ /dev/null @@ -1,3 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ diff --git a/demo/js/base/demo.combo.js b/demo/js/base/demo.combo.js deleted file mode 100644 index 879f44652..000000000 --- a/demo/js/base/demo.combo.js +++ /dev/null @@ -1,3 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ diff --git a/demo/js/config/widget.js b/demo/js/config/widget.js index ea6f07a0f..414d0459e 100644 --- a/demo/js/config/widget.js +++ b/demo/js/config/widget.js @@ -1,356 +1,8 @@ Demo.WIDGET_CONFIG = [{ id: 4, text: "详细控件" -}, { - pId: 4, - text: "bi.loading_mask", - value: "demo.loadingmask" -}, { - pId: 4, - text: "可以切换的树", - value: "demo.switch_tree" -}, { - pId: 4, - text: "进度条", - value: "demo.progressbar" -}, { - pId: 4, - text: "bi.text_editor", - value: "demo.text_editor" -}, { - pId: 4, - text: "bi.search_editor", - value: "demo.search_editor" -}, { - pId: 4, - text: "bi.adapt_editor", - value: "demo.adapt_editor" -}, { - pId: 4, - text: "bi.sign_initial_editor", - value: "demo.sign_initial_editor" -}, { - pId: 4, - text: "bi.sign_style_editor", - value: "demo.sign_style_editor" -}, { - pId: 4, - text: "bi.year_combo", - value: "demo.year_combo" -}, { - pId: 4, - text: "bi.month_combo", - value: "demo.month_combo" -}, { - pId: 4, - text: "bi.quarter_combo", - value: "demo.quarter_combo" -}, { - pId: 4, - text: "bi.date_combo", - value: "demo.date_combo" -}, { - pId: 4, - text: "bi.down_list_combo", - value: "demo.down_list_combo" -}, { - pId: 4, - text: "bi.text_value_combo", - value: "demo.text_icon_combo" -}, { - pId: 4, - text: "bi.static_combo", - value: "demo.single_select_combo" -}, { - pId: 4, - text: "bi.text_value_down_list_combo", - value: "demo.text_icon_down_list_combo" -}, { - pId: 4, - text: "bi.param_date_combo", - value: "demo.param_date_combo" -}, { - pId: 4, - text: "bi.icon_combo", - value: "demo.icon_combo" -}, { - pId: 4, - text: "bi.formula_combo", - value: "demo.formula_combo" -}, { - pId: 4, - text: "bi.formula_insert", - value: "demo.formula_insert" -}, { - pId: 4, - text: "bi.formula_pane", - value: "demo.formula_pane" -}, { - pId: 4, - text: "bi.select_data_tree", - value: "demo.select_data_tree" -}, { - pId: 4, - text: "bi.select_data_switcher", - value: "demo.select_data_switcher" -}, { - pId: 4, - text: "bi.select_data_search_result", - value: "demo.select_data_search_result" -}, { - pId: 4, - text: "bi.select_data_searcher(点这)", - value: "demo.select_data_searcher" -}, { - pId: 4, - text: "bi.multidate_combo", - value: "demo.multidate_combo" -}, { - pId: 4, - text: "bi.time_interval", - value: "demo.time_interval" -}, { - pId: 4, - text: "bi.numerical_interval", - value: "demo.numerical_interval" -}, { - pId: 4, - text: "bi.multi_select_trigger", - value: "demo.multi_select_trigger" -}, { - pId: 4, - text: "bi.multi_select_search_pane", - value: "demo.multi_select_search_pane" -}, { - pId: 4, - text: "bi.multi_select_popup_view", - value: "demo.multi_select_popup_view" -}, { - pId: 4, - text: "bi.multi_select_check_pane", - value: "demo.multi_select_check_pane" }, { pId: 4, text: "bi.multi_select_combo", value: "demo.multi_select_combo" -}, { - pId: 4, - text: "bi.move2group_combo", - value: "demo.move2group_combo" -}, { - pId: 4, - text: "bi.copy2group_combo", - value: "demo.copy2group_combo" -}, { - pId: 4, - text: "bi.single_tree_combo", - value: "demo.single_tree_combo" -}, { - pId: 4, - text: "bi.multilayer_single_tree_combo", - value: "demo.multilayer_single_tree_combo" -}, { - pId: 4, - text: "bi.select_tree_combo", - value: "demo.select_tree_combo" -}, { - pId: 4, - text: "bi.multilayer_select_tree_combo", - value: "demo.multilayer_select_tree_combo" -}, { - pId: 4, - text: "bi.dialog", - value: "demo.dialog" -}, { - pId: 4, - text: "bi.multi_tree", - value: "demo.multi_tree" -}, { - pId: 4, - text: "bi.simple_select_data_searcher", - value: "demo.simple_select_data_searcher" -}, { - pId: 4, - text: "bi.filter_pane", - value: "demo.filter_pane" -}, { - pId: 4, - text: "bi.filter_operation", - value: "demo.filter_operation" -}, { - pId: 4, - text: "bi.filter", - value: "demo.filter" -}, { - pId: 4, - text: "bi.color_chooser", - value: "demo.color_chooser" -}, { - pId: 4, - text: "bi.text_toolbar", - value: "demo.text_toolbar" -}, { - pId: 4, - text: "bi.text_area", - value: "demo.text_area" -}, { - pId: 4, - text: "bi.path_chooser", - value: "demo.path_chooser" -}, { - pId: 4, - text: "bi.direction_path_chooser", - value: "demo.direction_path_chooser" -}, { - pId: 4, - text: "bi.file_manager", - value: "demo.file_manager" -}, { - pId: 4, - text: "bi.branch_relation", - value: "demo.branch_relation" -}, { - pId: 4, - text: "bi.relation_view", - value: "demo.relation_view" -}, { - pId: 4, - text: "bi.preview_table", - value: "demo.preview_table" -}, { - pId: 4, - text: "bi.adaptive_table", - value: "demo.adaptive_table" -}, { - pId: 4, - text: "bi.adaptive_table(冻结表头)", - value: "demo.adaptive_table2" -}, { - pId: 4, - text: "bi.custom_scroll_table", - value: "demo.custom_scroll_table" -}, { - pId: 4, - text: "bi.page_table", - value: "demo.page_table" -}, { - pId: 4, - text: "bi.page_table(冻结)", - value: "demo.page_table2" -}, { - pId: 4, - text: "bi.page_table(调整列宽)", - value: "demo.page_table3" -}, { - pId: 4, - text: "bi.excel_table", - value: "demo.excel_table" -}, { - pId: 4, - text: "bi.sortable_table", - value: "demo.sortable_table" -}, { - pId: 4, - text: "bi.excel_view_display_manager", - value: "demo.excel_view_display_manager" -}, { - pId: 4, - text: "bi.sequence_table", - value: "demo.sequence_table" -}, { - pId: 4, - text: "bi.sequence_table(带有汇总)", - value: "demo.sequence_table2" -}, { - pId: 4, - text: "bi.upload_image", - value: "demo.upload_image" -}, { - pId: 4, - text: "bi.web_page", - value: "demo.web_page" -}, { - pId: 4, - text: "bi.arrangement_droppable", - value: "demo.arrangement_droppable" -}, { - pId: 4, - text: "bi.arrangement", - value: "demo.arrangement" -}, { - pId: 4, - text: "bi.adaptive_arrangement", - value: "demo.adaptive_arrangement" -}, { - pId: 4, - text: "bi.arrangement(网格布局)", - value: "demo.grid_arrangement" -}, { - pId: 4, - text: "bi.adaptive_arrangement(网格布局)", - value: "demo.grid_adaptive_arrangement" -}, { - pId: 4, - text: "bi.simple_searcher", - value: "demo.simple_searcher" -}, { - pId: 4, - text: "选色", - value: "demo.select_color_combo" -}, { - pId: 4, - text: "bi.detail_chart", - value: "demo.detail_chart" -}, { - pId: 4, - text: "柱形", - value: "demo.column_charts" -}, { - pId: 4, - text: "条形图", - value: "demo.bar_charts" -}, { - pId: 4, - text: "面积图", - value: "demo.area_charts" -}, { - pId: 4, - text: "其他", - value: "demo.other_charts" -}, { - pId: 4, - text: "文本标签", - value: "demo.list_label" -}, { - pId: 4, - text: "树标签", - value: "demo.tree_label" -}, { - pId: 4, - text: "滑块", - value: "demo.slider" -}, { - pId: 4, - text: "区间双滑块", - value: "demo.interval_slider" -}, { - pId: 4, - text: "文本列表", - value: "demo.string_list" -}, { - pId: 4, - text: "树列表", - value: "demo.tree_list" -}, { - pId: 4, - text: "日期面板", - value: "demo.data_pane" -}, { - pId: 4, - text: "螺旋分析tab控件", - value: "demo.dynamic_group_tab" -}, { - pId: 4, - text: "数值微调器", - value: "demo.finetuning_number_editor" }]; \ No newline at end of file diff --git a/demo/js/widget/demo.multiselectcombo.js b/demo/js/widget/demo.multiselectcombo.js new file mode 100644 index 000000000..f1441fa7b --- /dev/null +++ b/demo/js/widget/demo.multiselectcombo.js @@ -0,0 +1,88 @@ +/** + * Created by User on 2017/3/22. + */ +var _strings = " 柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 "; +//各种通用数据 +var ITEMS = BI.map(_strings.match(/[^\s]+/g), function (i, v) { + return { + text: v, + value: v, + title: v + } +}); +Demo.MultiSelectCombo = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-multi-select-combo" + }, + + _createMultiSelectCombo: function () { + var self = this; + var widget = BI.createWidget({ + type: 'bi.multi_select_combo', + itemsCreator: BI.bind(this._itemsCreator, this), + width: 200 + }); + + widget.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { + BI.Msg.toast(JSON.stringify(this.getValue())); + }); + + return widget; + }, + + _getItemsByTimes: function (items, times) { + var res = []; + for (var i = (times - 1) * 3; items[i] && i < times * 3; i++) { + res.push(items[i]); + } + return res; + }, + + _hasNextByTimes: function (items, times) { + return times * 3 < items.length; + }, + + _itemsCreator: function (options, callback) { + var self = this; + var items = ITEMS; + if (options.keyword) { + var search = BI.Func.getSearchResult(items, options.keyword); + items = search.matched.concat(search.finded); + } + if (options.selected_values) {//过滤 + var filter = BI.makeObject(options.selected_values, true); + items = BI.filter(items, function (i, ob) { + return !filter[ob.value]; + }); + } + if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: items + }); + return; + } + if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({count: items.length}); + return; + } + BI.delay(function () { + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + }, 1000); + }, + + render: function () { + return { + type: 'bi.absolute', + scrolly: false, + items: [{ + el: this._createMultiSelectCombo(), + right: 10, + top: 10 + }] + } + } +}); +$.shortcut("demo.multi_select_combo", Demo.MultiSelectCombo); \ No newline at end of file diff --git a/demo/js/widget/demo.multiselecttree.js b/demo/js/widget/demo.multiselecttree.js new file mode 100644 index 000000000..437f12162 --- /dev/null +++ b/demo/js/widget/demo.multiselecttree.js @@ -0,0 +1,14 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.MultiSelectTree = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-multi-select-tree" + }, + render: function () { + return { + type: "bi.vertical", + } + } +}); +$.shortcut("demo.multi_select_tree", Demo.MultiSelectTree); \ No newline at end of file diff --git a/dist/base.js b/dist/base.js index f869ce10b..5b491a786 100644 --- a/dist/base.js +++ b/dist/base.js @@ -20561,7 +20561,7 @@ BI.Pane = BI.inherit(BI.Widget, { }); } BI.Maskers.show(self.getName()); - } else { + } else if (BI.isNull(this._loading)) { this._loading = BI.createWidget({ type: "bi.layout", cls: "loading-background", @@ -20870,6 +20870,10 @@ BI.Text = BI.inherit(BI.Single, { } }, + setStyle: function (css) { + this.text.element.css(css) + }, + setText: function (text) { BI.Text.superclass.setText.apply(this, arguments); this.options.text = text; @@ -20888,7 +20892,7 @@ BI.BasicButton = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.BasicButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-basic-button cursor-pointer", + baseCls: (conf.baseCls || "") + " bi-basic-button" + (conf.invalid ? "" : " cursor-pointer"), value: "", text: "", stopEvent: false, @@ -21001,42 +21005,36 @@ BI.BasicButton = BI.inherit(BI.Single, { var selected = false; hand.mousedown(function (e) { // if (e.button === 0) { - if (mouseDown === true) { - return; + $(document).bind("mouseup." + self.getName(), function (e) { + // if (e.button === 0) { + if (BI.DOM.isExist(self) && !hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { + self.setSelected(!self.isSelected()); + self._trigger(); } - if (self.isSelected()) { - selected = true; - } else { - clk(e); - } - mouseDown = true; - ev(e); + mouseDown = false; + $(document).unbind("mouseup." + self.getName()); + // } + }); + if (mouseDown === true) { + return; + } + if (self.isSelected()) { + selected = true; + } else { + clk(e); + } + mouseDown = true; + ev(e); // } }); hand.mouseup(function (e) { // if (e.button === 0) { - if (mouseDown === true && selected === true) { - clk(e); - } - mouseDown = false; - selected = false; - // } - }); - var checking = BI.debounce(function () { - if (!BI.DOM.isExist(self)) { - $(document).unbind("mouseup." + self.getName()); + if (BI.DOM.isExist(self) && mouseDown === true && selected === true) { + clk(e); } - }, 3000); - $(document).bind("mouseup." + this.getName(), function (e) { - // if (e.button === 0) { - if (BI.DOM.isExist(self)) { - if (!hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { - self.setSelected(!self.isSelected()); - self._trigger(); - } - mouseDown = false; - checking(); - } + mouseDown = false; + selected = false; + $(document).unbind("mouseup." + self.getName()); // } }); break; @@ -21163,8 +21161,13 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - destroyed: function () { + empty: function () { $(document).unbind("mouseup." + this.getName()); + BI.BasicButton.superclass.empty.apply(this, arguments); + }, + + destroy: function () { + BI.BasicButton.superclass.destroy.apply(this, arguments); } }); BI.BasicButton.EVENT_CHANGE = "BasicButton.EVENT_CHANGE";/** @@ -21222,2226 +21225,1972 @@ BI.NodeButton = BI.inherit(BI.BasicButton, { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, this.getValue(), this); } } -});BI.Resizers = new BI.ResizeController(); -BI.Layers = new BI.LayerController(); -BI.Maskers = new BI.MaskersController(); -BI.Bubbles = new BI.BubblesController(); -BI.Tooltips = new BI.TooltipsController(); -BI.Popovers = new BI.FloatBoxController(); -BI.Broadcasts = new BI.BroadcastController(); -/** - * canvas绘图 - * - * Created by GUY on 2015/11/18. - * @class BI.Canvas +});/** + * Created by GUY on 2015/6/26. + * @class BI.ButtonGroup * @extends BI.Widget */ -BI.Canvas = BI.inherit(BI.Widget, { +BI.ButtonGroup = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.Canvas.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-canvas" + return BI.extend(BI.ButtonGroup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-button-group", + behaviors: {}, + items: [ + { + el: {type: "bi.text_button", text: "", value: ""} + } + ], + chooseType: BI.Selection.Single, + layouts: [{ + type: "bi.center", + hgap: 0, + vgap: 0 + }] }) }, _init: function () { - BI.Canvas.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var canvas = document.createElement("canvas"); - if (!document.createElement('canvas').getContext) { - canvas = window.G_vmlCanvasManager.initElement(canvas); - } - this.element.append(canvas); - canvas.width = o.width; - canvas.height = o.height; - $(canvas).width("100%"); - $(canvas).height("100%"); - this.canvas = canvas; - this._queue = []; + BI.ButtonGroup.superclass._init.apply(this, arguments); + var behaviors = {}; + BI.each(this.options.behaviors, function (key, rule) { + behaviors[key] = BI.BehaviorFactory.createBehavior(key, { + rule: rule + }) + }); + this.behaviors = behaviors; + this.populate(this.options.items); }, - _getContext: function () { - if (!this.ctx) { - this.ctx = this.canvas.getContext('2d'); - } - return this.ctx; + _createBtns: function (items) { + var o = this.options; + return BI.createWidgets(BI.createItems(items, { + type: "bi.text_button" + })); }, - _attr: function (key, value) { - var self = this; - if (BI.isNull(key)) { - return; - } - if (BI.isObject(key)) { - BI.each(key, function (k, v) { - self._queue.push({k: k, v: v}); - }); - return; - } - this._queue.push({k: key, v: value}); - }, + _btnsCreator: function (items) { + var self = this, args = Array.prototype.slice.call(arguments), o = this.options; + var buttons = this._createBtns(items); + args[0] = buttons; - _line: function (x0, y0) { - var self = this; - var args = [].slice.call(arguments, 2); - if (BI.isOdd(args.length)) { - this._attr(BI.last(args)); - args = BI.initial(args); - } - this._attr("moveTo", [x0, y0]); - var odd = BI.filter(args, function (i) { - return i % 2 === 0; - }); - var even = BI.filter(args, function (i) { - return i % 2 !== 0; + BI.each(this.behaviors, function (i, behavior) { + behavior.doBehavior.apply(behavior, args); }); - args = BI.zip(odd, even); - BI.each(args, function (i, point) { - self._attr("lineTo", point); + BI.each(buttons, function (i, btn) { + btn.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (type === BI.Events.CLICK) { + switch (o.chooseType) { + case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: + self.setValue(btn.getValue()); + break; + case BI.ButtonGroup.CHOOSE_TYPE_NONE: + self.setValue([]); + break; + } + self.fireEvent(BI.ButtonGroup.EVENT_CHANGE, value, obj); + } + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + btn.on(BI.Events.DESTROY, function () { + BI.remove(self.buttons, btn); + }) }); - }, - line: function (x0, y0, x1, y1) { - this._line.apply(this, arguments); - this._attr("stroke", []); + return buttons; }, - rect: function (x, y, w, h, color) { - this._attr("fillStyle", color); - this._attr("fillRect", [x, y, w, h]); + _packageBtns: function (btns) { + var o = this.options; + + for (var i = o.layouts.length - 1; i > 0; i--) { + btns = BI.map(btns, function (k, it) { + return BI.extend({}, o.layouts[i], { + items: [ + BI.extend({}, o.layouts[i].el, { + el: it + }) + ] + }) + }) + } + return btns; }, - circle: function (x, y, radius, color) { - this._attr({ - fillStyle: color, - beginPath: [], - arc: [x, y, radius, 0, Math.PI * 2, true], - closePath: [], - fill: [] - }); + _packageItems: function (items, packBtns) { + return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); }, - hollow: function () { - this._attr("beginPath", []); - this._line.apply(this, arguments); - this._attr("closePath", []); - this._attr("stroke", []); + _packageLayout: function (items) { + var o = this.options, layout = BI.deepClone(o.layouts[0]); + + var lay = BI.formatEL(layout).el; + while (lay && lay.items && !BI.isEmpty(lay.items)) { + lay = BI.formatEL(lay.items[0]).el; + } + lay.items = items; + return layout; }, - solid: function () { - this.hollow.apply(this, arguments); - this._attr("fill", []); + + doBehavior: function () { + var args = Array.prototype.slice.call(arguments); + args.unshift(this.buttons); + BI.each(this.behaviors, function (i, behavior) { + behavior.doBehavior.apply(behavior, args); + }) }, - gradient: function (x0, y0, x1, y1, start, end) { - var grd = this._getContext().createLinearGradient(x0, y0, x1, y1); - grd.addColorStop(0, start); - grd.addColorStop(1, end); - return grd; + prependItems: function (items) { + var o = this.options; + var btns = this._btnsCreator.apply(this, arguments); + this.buttons = BI.concat(btns, this.buttons); + + //如果是一个简单的layout + if (o.layouts.length === 1 && !BI.isNotEmptyArray(o.layouts[0].items) + && this.layouts && this.layouts.prependItems) { + this.layouts.prependItems(btns); + return; + } + + var items = this._packageItems(items, this._packageBtns(btns)); + BI.createWidget(BI.extend(this._packageLayout(items))).element.children().prependTo(this.element); }, - reset: function () { - this._getContext().clearRect(0, 0, this.canvas.width, this.canvas.height); + addItems: function (items) { + var o = this.options; + var btns = this._btnsCreator.apply(this, arguments); + this.buttons = BI.concat(this.buttons, btns); + + //如果是一个简单的layout + if (o.layouts.length === 1 && !BI.isNotEmptyArray(o.layouts[0].items) + && this.layouts && this.layouts.addItems) { + this.layouts.addItems(btns); + return; + } + + var items = this._packageItems(items, this._packageBtns(btns)); + BI.createWidget(BI.extend(this._packageLayout(items))).element.children().appendTo(this.element); }, - stroke: function (callback) { + removeItemAt: function (indexes) { var self = this; - BI.nextTick(function () { - var ctx = self._getContext(); - BI.each(self._queue, function (i, q) { - if (BI.isFunction(ctx[q.k])) { - ctx[q.k].apply(ctx, q.v); - } else { - ctx[q.k] = q.v; - } - }); - self._queue = []; - callback && callback(); - }); - } -}); -$.shortcut("bi.canvas", BI.Canvas);/** - * Collection - * - * Created by GUY on 2016/1/15. - * @class BI.Collection - * @extends BI.Widget - */ -BI.Collection = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Collection.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-collection", - width: 400, - height: 300, - overflowX: true, - overflowY: true, - cellSizeAndPositionGetter: BI.emptyFn, - horizontalOverscanSize: 0, - verticalOverscanSize: 0, - scrollLeft: 0, - scrollTop: 0, - items: [] + indexes = BI.isArray(indexes) ? indexes : [indexes]; + var buttons = []; + BI.each(indexes, function (i, index) { + buttons.push(self.buttons[index]); }); + BI.each(buttons, function (i, btn) { + btn && btn.destroy(); + }) }, - _init: function () { - BI.Collection.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.renderedCells = []; - this.renderedKeys = []; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 150); - this.container = BI.createWidget({ - type: "bi.absolute" - }); - this.element.scroll(function () { - if (self._scrollLock === true) { - return; + removeItems: function (v) { + v = BI.isArray(v) ? v : [v]; + var indexes = []; + BI.each(this.buttons, function (i, item) { + if (BI.deepContains(v, item.getValue())) { + indexes.push(i); } - o.scrollLeft = self.element.scrollLeft(); - o.scrollTop = self.element.scrollTop(); - self._calculateChildrenToRender(); - self.fireEvent(BI.Collection.EVENT_SCROLL, { - scrollLeft: o.scrollLeft, - scrollTop: o.scrollTop - }); - }); - BI.createWidget({ - type: "bi.vertical", - element: this, - scrollable: o.overflowX === true && o.overflowY === true, - scrolly: o.overflowX === false && o.overflowY === true, - scrollx: o.overflowX === true && o.overflowY === false, - items: [this.container] }); - if (o.items.length > 0) { - this._calculateSizeAndPositionData(); - this._populate(); - } - }, - - mounted: function () { - var o = this.options; - if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } - }, - - destroyed: function () { - this._debounceRelease = null; + this.removeItemAt(indexes); }, - _calculateSizeAndPositionData: function () { - var o = this.options; - var cellMetadata = []; - var sectionManager = new BI.SectionManager(); - var height = 0; - var width = 0; - - for (var index = 0, len = o.items.length; index < len; index++) { - var cellMetadatum = o.cellSizeAndPositionGetter(index); - - if ( - cellMetadatum.height == null || isNaN(cellMetadatum.height) || - cellMetadatum.width == null || isNaN(cellMetadatum.width) || - cellMetadatum.x == null || isNaN(cellMetadatum.x) || - cellMetadatum.y == null || isNaN(cellMetadatum.y) - ) { - throw Error(); - } - - height = Math.max(height, cellMetadatum.y + cellMetadatum.height); - width = Math.max(width, cellMetadatum.x + cellMetadatum.width); + populate: function (items) { + this.options.items = items || []; + this.empty(); - cellMetadatum.index = index; - cellMetadata[index] = cellMetadatum; - sectionManager.registerCell(cellMetadatum, index); - } + this.buttons = this._btnsCreator.apply(this, arguments); + var items = this._packageItems(items, this._packageBtns(this.buttons)); - this._cellMetadata = cellMetadata; - this._sectionManager = sectionManager; - this._height = height; - this._width = width; + this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); }, - _cellRenderers: function (height, width, x, y) { - this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y); - return this._cellGroupRenderer() + setEnable: function (b) { + BI.ButtonGroup.superclass.setEnable.apply(this, arguments); + BI.each(this.buttons, function (i, item) { + item.setEnable(b); + }); }, - _cellGroupRenderer: function () { - var self = this, o = this.options; - var rendered = []; - BI.each(this._lastRenderedCellIndices, function (i, index) { - var cellMetadata = self._sectionManager.getCellMetadata(index); - rendered.push(cellMetadata); + setNotSelectedValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (BI.deepContains(v, item.getValue())) { + item.setSelected && item.setSelected(false); + } else { + item.setSelected && item.setSelected(true); + } }); - return rendered; }, - _calculateChildrenToRender: function () { - var self = this, o = this.options; - var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()); - var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()); - var left = Math.max(0, scrollLeft - o.horizontalOverscanSize); - var top = Math.max(0, scrollTop - o.verticalOverscanSize); - var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize); - var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize); - var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); - var renderedCells = [], renderedKeys = []; - for (var i = 0, len = childrenToDisplay.length; i < len; i++) { - var datum = childrenToDisplay[i]; - var index = BI.deepIndexOf(this.renderedKeys, datum.index); - if (index > -1) { - if (datum.width !== this.renderedCells[index]._width) { - this.renderedCells[index]._width = datum.width; - this.renderedCells[index].el.setWidth(datum.width); - } - if (datum.height !== this.renderedCells[index]._height) { - this.renderedCells[index]._height = datum.height; - this.renderedCells[index].el.setHeight(datum.height); - } - if (this.renderedCells[index].left !== datum.x) { - this.renderedCells[index].el.element.css("left", datum.x + "px"); - } - if (this.renderedCells[index].top !== datum.y) { - this.renderedCells[index].el.element.css("top", datum.y + "px"); - } - renderedCells.push(this.renderedCells[index]); + setEnabledValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (BI.deepContains(v, item.getValue())) { + item.setEnable(true); } else { - var child = BI.createWidget(BI.extend({ - type: "bi.label", - width: datum.width, - height: datum.height - }, o.items[datum.index], { - cls: (o.items[datum.index].cls || "") + " container-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : ""), - _left: datum.x, - _top: datum.y - })); - renderedCells.push({ - el: child, - left: datum.x, - top: datum.y, - _width: datum.width, - _height: datum.height - }); + item.setEnable(false); } - renderedKeys.push(datum.index); - } - //已存在的, 需要添加的和需要删除的 - var existSet = {}, addSet = {}, deleteArray = []; - BI.each(renderedKeys, function (i, key) { - if (BI.deepContains(self.renderedKeys, key)) { - existSet[i] = key; + }); + }, + + setValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (BI.deepContains(v, item.getValue())) { + item.setSelected && item.setSelected(true); } else { - addSet[i] = key; + item.setSelected && item.setSelected(false); } }); - BI.each(this.renderedKeys, function (i, key) { - if (BI.deepContains(existSet, key)) { - return; - } - if (BI.deepContains(addSet, key)) { - return; + }, + + getNotSelectedValue: function () { + var v = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !(item.isSelected && item.isSelected())) { + v.push(item.getValue()); } - deleteArray.push(i); - }); - BI.each(deleteArray, function (i, index) { - self.renderedCells[index].el.destroy(); - }); - var addedItems = []; - BI.each(addSet, function (index) { - addedItems.push(renderedCells[index]) }); - BI.createWidget({ - type: "bi.absolute", - element: this.container, - items: addedItems - }); - this.renderedCells = renderedCells; - this.renderedKeys = renderedKeys; + return v; }, - _getMaxScrollLeft: function () { - return Math.max(0, this._width - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); + getValue: function () { + var v = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && item.isSelected && item.isSelected()) { + v.push(item.getValue()); + } + }); + return v; }, - _getMaxScrollTop: function () { - return Math.max(0, this._height - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); + getAllButtons: function () { + return this.buttons; }, - _populate: function () { - var o = this.options; - if (o.items.length > 0) { - this.container.setWidth(this._width); - this.container.setHeight(this._height); + getAllLeaves: function () { + return this.buttons; + }, - this._calculateChildrenToRender(); - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } - }, - - setScrollLeft: function (scrollLeft) { - if (this.options.scrollLeft === scrollLeft) { - return; - } - this._scrollLock = true; - this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); - this._debounceRelease(); - this._calculateChildrenToRender(); - this.element.scrollLeft(this.options.scrollLeft); - }, - - setScrollTop: function (scrollTop) { - if (this.options.scrollTop === scrollTop) { - return; - } - this._scrollLock = true; - this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); - this._debounceRelease(); - this._calculateChildrenToRender(); - this.element.scrollTop(this.options.scrollTop); - }, - - setOverflowX: function (b) { - var self = this; - if (this.options.overflowX !== !!b) { - this.options.overflowX = !!b; - BI.nextTick(function () { - self.element.css({overflowX: !!b ? "auto" : "hidden"}); - }); - } - }, - - setOverflowY: function (b) { - var self = this; - if (this.options.overflowY !== !!b) { - this.options.overflowY = !!b; - BI.nextTick(function () { - self.element.css({overflowY: !!b ? "auto" : "hidden"}); - }); - } - }, - - getScrollLeft: function () { - return this.options.scrollLeft; + getSelectedButtons: function () { + var btns = []; + BI.each(this.buttons, function (i, item) { + if (item.isSelected && item.isSelected()) { + btns.push(item); + } + }); + return btns; }, - getScrollTop: function () { - return this.options.scrollTop; + getNotSelectedButtons: function () { + var btns = []; + BI.each(this.buttons, function (i, item) { + if (item.isSelected && !item.isSelected()) { + btns.push(item); + } + }); + return btns; }, - getMaxScrollLeft: function () { - return this._getMaxScrollLeft(); + getIndexByValue: function (value) { + var index = -1; + BI.any(this.buttons, function (i, item) { + if (item.isEnabled() && item.getValue() === value) { + index = i; + return true; + } + }); + return index; }, - getMaxScrollTop: function () { - return this._getMaxScrollTop(); + getNodeById: function (id) { + var node; + BI.any(this.buttons, function (i, item) { + if (item.isEnabled() && item.options.id === id) { + node = item; + return true; + } + }); + return node; }, - restore: function () { - BI.each(this.renderedCells, function (i, cell) { - cell.el.destroy(); + getNodeByValue: function (value) { + var node; + BI.any(this.buttons, function (i, item) { + if (item.isEnabled() && item.getValue() === value) { + node = item; + return true; + } }); - this.renderedCells = []; - this.renderedKeys = []; - this._scrollLock = false; + return node; }, - populate: function (items) { - if (items && items !== this.options.items) { - this.options.items = items; - this._calculateSizeAndPositionData(); - } - this._populate(); + destroy: function () { + BI.ButtonGroup.superclass.destroy.apply(this, arguments); } }); -BI.Collection.EVENT_SCROLL = "EVENT_SCROLL"; -$.shortcut('bi.collection_view', BI.Collection);/** - * @class BI.Combo - * @extends BI.Widget +BI.extend(BI.ButtonGroup, { + CHOOSE_TYPE_SINGLE: BI.Selection.Single, + CHOOSE_TYPE_MULTI: BI.Selection.Multi, + CHOOSE_TYPE_ALL: BI.Selection.All, + CHOOSE_TYPE_NONE: BI.Selection.None, + CHOOSE_TYPE_DEFAULT: BI.Selection.Default +}); +BI.ButtonGroup.EVENT_CHANGE = "EVENT_CHANGE"; + +$.shortcut("bi.button_group", BI.ButtonGroup);/** + * Created by GUY on 2015/8/10. + * @class BI.ButtonTree + * @extends BI.ButtonGroup */ -BI.Combo = BI.inherit(BI.Widget, { + +BI.ButtonTree = BI.inherit(BI.ButtonGroup, { _defaultConfig: function () { - return BI.extend(BI.Combo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-combo", - trigger: "click", - toggle: true, - direction: "bottom", //top||bottom||left||right||top,left||top,right||bottom,left||bottom,right - isDefaultInit: false, - isNeedAdjustHeight: true,//是否需要高度调整 - isNeedAdjustWidth: true, - adjustLength: 0,//调整的距离 - adjustXOffset: 0, - adjustYOffset: 0, - hideChecker: BI.emptyFn, - offsetStyle: "left", //left,right,center - el: {}, - popup: {}, - comboClass: "bi-combo-popup", - hoverClass: "bi-combo-hover" + return BI.extend(BI.ButtonTree.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-button-tree" }) }, _init: function () { - BI.Combo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this._initCombo(); - this._initPullDownAction(); - this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self.isEnabled() && this.isEnabled()) { - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } + BI.ButtonTree.superclass._init.apply(this, arguments); + }, - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); - } + setNotSelectedValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (!BI.isFunction(item.setSelected)) { + item.setNotSelectedValue(v); + return; + } + if (BI.deepContains(v, item.getValue())) { + item.setSelected(false); + } else { + item.setSelected(true); } }); + }, - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.combo.isEnabled()) { - self.element.addClass(o.hoverClass); + setEnabledValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (BI.isFunction(item.setEnabledValue)) { + item.setEnabledValue(v); + return; } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.isEnabled() && self.combo.isEnabled()) { - self.element.removeClass(o.hoverClass); + if (BI.deepContains(v, item.getValue())) { + item.setEnable(true); + } else { + item.setEnable(false); } }); + }, - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - {el: this.combo} - ] + setValue: function (v) { + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (i, item) { + if (!BI.isFunction(item.setSelected)) { + item.setValue(v); + return; + } + if (BI.deepContains(v, item.getValue())) { + item.setSelected(true); + } else { + item.setSelected(false); + } }); - o.isDefaultInit && (this._assertPopupView()); - BI.Resizers.add(this.getName(), BI.bind(function () { - if (this.isViewVisible()) { - this._hideView(); + }, + + getNotSelectedValue: function () { + var v = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !BI.isFunction(item.setSelected)) { + v = BI.concat(v, item.getNotSelectedValue()); + return; } - }, this)); + if (item.isEnabled() && item.isSelected && !item.isSelected()) { + v.push(item.getValue()); + } + }); + return v; }, - _toggle: function () { - this._assertPopupViewRender(); - if (this.popupView.isVisible()) { - this._hideView(); - } else { - if (this.isEnabled()) { - this._popupView(); + getValue: function () { + var v = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !BI.isFunction(item.setSelected)) { + v = BI.concat(v, item.getValue()); + return; } - } + if (item.isEnabled() && item.isSelected && item.isSelected()) { + v.push(item.getValue()); + } + }); + return v; }, - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = this.options.trigger.split(","); - BI.each(evs, function (i, ev) { - switch (ev) { - case "hover": - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.combo.isEnabled()) { - self._popupView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.isEnabled() && self.combo.isEnabled() && o.toggle === true) { - self._hideView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } - }); - break; - case "click": - if (ev) { - self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.combo.isEnabled()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, true)); - } - break; + getSelectedButtons: function () { + var btns = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !BI.isFunction(item.setSelected)) { + btns = btns.concat(item.getSelectedButtons()); + return; } - }) + if (item.isSelected && item.isSelected()) { + btns.push(item); + } + }); + return btns; }, - _initCombo: function () { - this.combo = BI.createWidget(this.options.el); + getNotSelectedButtons: function () { + var btns = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !BI.isFunction(item.setSelected)) { + btns = btns.concat(item.getNotSelectedButtons()); + return; + } + if (item.isSelected && !item.isSelected()) { + btns.push(item); + } + }); + return btns; }, - _assertPopupView: function () { - var self = this; - if (this.popupView == null) { - this.popupView = BI.createWidget(this.options.popup, { - type: "bi.popup_view" - }); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - self.combo.setValue(self.getValue()); - self.fireEvent(BI.Combo.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.popupView.setVisible(false); - BI.nextTick(function () { - self.fireEvent(BI.Combo.EVENT_AFTER_INIT); - }); - } + //获取所有的叶子节点 + getAllLeaves: function () { + var leaves = []; + BI.each(this.buttons, function (i, item) { + if (item.isEnabled() && !BI.isFunction(item.setSelected)) { + leaves = leaves.concat(item.getAllLeaves()); + return; + } + if (item.isEnabled()) { + leaves.push(item); + } + }); + return leaves; }, - _assertPopupViewRender: function () { - this._assertPopupView(); - if (!this._rendered) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - {el: this.popupView} - ] - }); - this._rendered = true; - } + getIndexByValue: function (value) { + var index = -1; + BI.any(this.buttons, function (i, item) { + var vs = item.getValue(); + if (item.isEnabled() && (vs === value || BI.contains(vs, value))) { + index = i; + return true; + } + }); + return index; }, - _hideIf: function (e) { - if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { - return; - } - if (this.element.find(e.target).length > 0) { - return; - } - var isHide = this.options.hideChecker.apply(this, [e]); - if (isHide === false) { - return; - } - this._hideView(); + getNodeById: function (id) { + var node; + BI.any(this.buttons, function (i, item) { + if (item.isEnabled()) { + if (item.attr("id") === id) { + node = item; + return true; + } else if (BI.isFunction(item.getNodeById)) { + if (node = item.getNodeById(id)) { + return true; + } + } + } + }); + return node; }, - _hideView: function () { - this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); - this.popupView && this.popupView.invisible(); - this.element.removeClass(this.options.comboClass); + getNodeByValue: function (value) { + var node; + BI.any(this.buttons, function (i, item) { + if (item.isEnabled()) { + if (item.getValue() === value) { + node = item; + return true; + } else if (BI.isFunction(item.getNodeByValue)) { + if (node = item.getNodeByValue(value)) { + return true; + } + } + } + }); + return node; + } +}); +BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; - $(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); - this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW); +$.shortcut("bi.button_tree", BI.ButtonTree);/** + * value作为key值缓存button, 不支持顺序读写 + * 适合用于频繁增删的一组button + * Created by GUY on 2015/8/10. + * @class BI.ButtonMap + * @extends BI.ButtonTree + */ + +BI.ButtonMap = BI.inherit(BI.ButtonTree, { + _defaultConfig: function () { + return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-button-map" + }) }, - _popupView: function () { - this._assertPopupViewRender(); - this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); + _init: function () { + BI.ButtonMap.superclass._init.apply(this, arguments); + }, - this.popupView.visible(); - this.adjustWidth(); - this.adjustHeight(); + _createBtns: function (items) { + var self = this, o = this.options; + var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); + var keys = BI.map(items, function (i, item) { + item = BI.stripEL(item); + if (!(item.id || item.value)) { + throw new Error("item必须包含id或value属性"); + } + return item.id || item.value; + }); + return BI.object(keys, buttons); + }, - this.element.addClass(this.options.comboClass); - $(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); - this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); + setValue: function (v) { + var self = this; + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (val, item) { + if (!BI.isFunction(item.setSelected)) { + item.setValue(v); + return; + } + if (v.contains(val)) { + item.setSelected && item.setSelected(true); + } else { + item.setSelected && item.setSelected(false); + } + }); }, - adjustWidth: function () { - var o = this.options; - if (!this.popupView) { - return; - } - if (o.isNeedAdjustWidth === true) { - this.resetListWidth(""); - var width = this.popupView.element.outerWidth(); - var maxW = this.element.outerWidth() || o.width; - if (width > maxW + 80) { - maxW = maxW + 80; - } else if (width > maxW) { - maxW = width; + setNotSelectedValue: function (v) { + var self = this; + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (val, item) { + if (!BI.isFunction(item.setSelected)) { + item.setNotSelectedValue(v); + return; } - this.resetListWidth(maxW < 100 ? 100 : maxW); - } + if (v.contains(val)) { + item.setSelected && item.setSelected(false); + } else { + item.setSelected && item.setSelected(true); + } + }); }, - adjustHeight: function () { - var o = this.options, p = {}; - if (!this.popupView) { - return; + populate: function (items) { + var self = this; + var args = [].slice.call(arguments); + var linkHashMap = new BI.LinkHashMap(); + var val = function (item) { + return item.id || item.value; + }; + if (!this.buttons) { + this.buttons = {}; } - var isVisible = this.popupView.isVisible(); - this.popupView.visible(); - switch (o.direction) { - case "bottom": - case "bottom,right": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'right', 'left'], o.offsetStyle); - break; - case "top": - case "top,right": - p = $.getComboPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'right', 'left'], o.offsetStyle); - break; - case "left": - case "left,bottom": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'bottom', 'top'], o.offsetStyle); - break; - case "right": - case "right,bottom": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'bottom', 'top'], o.offsetStyle); - break; - case "top,left": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'left', 'right'], o.offsetStyle); - break; - case "bottom,left": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'left', 'right'], o.offsetStyle); - break; - case "left,top": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'top', 'bottom'], o.offsetStyle); - break; - case "right,top": - p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'top', 'bottom'], o.offsetStyle); - break; - case "top,custom": - case "custom,top": - p = $.getTopAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); - break; - case "custom,bottom": - case "bottom,custom": - p = $.getBottomAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); - break; - case "left,custom": - case "custom,left": - p = $.getLeftAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); - delete p.top; - delete p.adaptHeight; - break; - case "custom,right": - case "right,custom": - p = $.getRightAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); - delete p.top; - delete p.adaptHeight; - break; - } - - if ("adaptHeight" in p) { - this.resetListHeight(p['adaptHeight']); - } - if ("left" in p) { - this.popupView.element.css({ - left: p.left - }); - } - if ("top" in p) { - this.popupView.element.css({ - top: p.top - }); - } - this.popupView.setVisible(isVisible); - }, - - resetListHeight: function (h) { - this._assertPopupView(); - this.popupView.resetHeight && this.popupView.resetHeight(h); - }, - - resetListWidth: function (w) { - this._assertPopupView(); - this.popupView.resetWidth && this.popupView.resetWidth(w); - }, - - populate: function (items) { - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - this.combo.populate.apply(this.combo, arguments); - }, - - setEnable: function (arg) { - BI.Combo.superclass.setEnable.apply(this, arguments); - this.combo && this.combo.setEnable(arg); - this.popupView && this.popupView.setEnable(arg); - !arg && this._hideView(); - }, - - setValue: function (v) { - this._assertPopupView(); - this.combo.setValue(v); - this.popupView && this.popupView.setValue(v); - }, - - getValue: function () { - this._assertPopupView(); - return this.popupView && this.popupView.getValue(); - }, - - isViewVisible: function () { - return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); - }, - - showView: function () { - if (this.isEnabled() && this.combo.isEnabled()) { - this._popupView(); - } - }, - - hideView: function () { - this._hideView(); - }, + //所有已存在的和新添加的 + var willCreated = []; + BI.each(items, function (i, item) { + item = BI.stripEL(item); + if (self.buttons[val(item)]) { + var ob = self.buttons[val(item)]; + args[0] = item.items; + args[2] = item; + ob.populate && ob.populate.apply(ob, args); + } else { + willCreated.push(item); + } + }); + //创建新元素 + args[0] = willCreated; + var newBtns = this._btnsCreator.apply(this, args); - getView: function () { - return this.popupView; - }, + //整理 + var array = []; + BI.each(items, function (i, item) { + item = BI.stripEL(item); + var button = self.buttons[val(item)] || newBtns[val(item)]; + linkHashMap.add(val(item), button); + array.push(button); + }); + this.buttons = linkHashMap.map; - doBehavior: function () { - this._assertPopupView(); - this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); - }, + BI.DOM.hang(this.buttons); + this.empty(); - toggle: function () { - this._toggle(); + var packages = this._packageItems(items, this._packageBtns(array)); + BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); }, - destroyed: function () { - $(document).unbind("mousedown." + this.getName()) - .unbind("mousewheel." + this.getName()) - .unbind("mouseenter." + this.getName()) - .unbind("mousemove." + this.getName()) - .unbind("mouseleave." + this.getName()); - this.popupView && this.popupView.destroy(); - BI.Resizers.remove(this.getName()); + getIndexByValue: function (value) { + throw new Error("不能使用getIndexByValue方法"); } }); -BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; -BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; +BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.combo", BI.Combo);/** - * - * 某个可以展开的节点 - * - * Created by GUY on 2015/9/10. - * @class BI.Expander - * @extends BI.Widget +$.shortcut("bi.button_map", BI.ButtonMap);/** + * guy + * 异步树 + * @class BI.TreeView + * @extends BI.Pane */ -BI.Expander = BI.inherit(BI.Widget, { +BI.TreeView = BI.inherit(BI.Pane, { _defaultConfig: function () { - return BI.extend(BI.Expander.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-expander", - trigger: "click", - toggle: true, - //direction: "bottom", //top,bottom四个方向 - isDefaultInit: false, //是否默认初始化子节点 - el: {}, - popup: {}, - expanderClass: "bi-expander-popup", - hoverClass: "bi-expander-hover" + return BI.extend(BI.TreeView.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree", + paras: {}, + itemsCreator: BI.emptyFn }) }, - _init: function () { - BI.Expander.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this._expanded = !!o.el.open; - this._initExpander(); - this._initPullDownAction(); - this.expander.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (self.isEnabled() && this.isEnabled()) { - if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Expander.EVENT_TRIGGER_CHANGE, value, obj); - } - } - }); + BI.TreeView.superclass._init.apply(this, arguments); + FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.core-3.5.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.excheck-3.5.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/css/base/third/ztree/zTreeStyle.css', 'css'); - this.element.hover(function () { - if (self.isEnabled() && self.expander.isEnabled()) { - self.element.addClass(o.hoverClass); - } - }, function () { - if (self.isEnabled() && self.expander.isEnabled()) { - self.element.removeClass(o.hoverClass); - } + this._stop = false; + this.container = BI.createWidget(); + + this._createTree(); + this.tip = BI.createWidget({ + type: "bi.loading_bar", + invisible: true, + handler: BI.bind(this._loadMore, this) }); BI.createWidget({ type: "bi.vertical", + scrollable: true, scrolly: false, element: this, - items: [ - {el: this.expander} - ] + items: [this.container, this.tip] }); - o.isDefaultInit && this._assertPopupView(); - if (this.expander.isOpened() === true) { - this._popupView(); - } - }, - _toggle: function () { - this._assertPopupViewRender(); - if (this.popupView.isVisible()) { - this._hideView(); - } else { - if (this.isEnabled()) { - this._popupView(); - } - } }, - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = this.options.trigger.split(","); - BI.each(evs, function (i, e) { - switch (e) { - case "hover": - self.element[e](function (e) { - if (self.isEnabled() && self.expander.isEnabled()) { - self._popupView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.expander); - self.fireEvent(BI.Expander.EVENT_EXPAND); - } - }, function () { - if (self.isEnabled() && self.expander.isEnabled() && o.toggle) { - self._hideView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.expander); - self.fireEvent(BI.Expander.EVENT_COLLAPSE); - } - }); - break; - default : - if (e) { - self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { - if (self.expander.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.expander.isEnabled()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isExpanded()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); - self.fireEvent(BI.Expander.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.expander); - self.fireEvent(BI.Expander.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, true)); - } - break; - } - }) + _createTree: function () { + this.id = "bi-tree" + BI.UUID(); + if (this.nodes) { + this.nodes.destroy(); + } + if (this.tree) { + this.tree.destroy(); + } + this.tree = BI.createWidget({ + type: "bi.layout", + element: "
    " + }); + BI.createWidget({ + type: "bi.default", + element: this.container, + items: [this.tree] + }); }, - _initExpander: function () { - this.expander = BI.createWidget(this.options.el); + //选择节点触发方法 + _selectTreeNode: function (treeId, treeNode) { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, treeNode, this); + this.fireEvent(BI.TreeView.EVENT_CHANGE, treeNode, this); }, - _assertPopupView: function () { + //配置属性 + _configSetting: function () { + var paras = this.options.paras; var self = this; - if (this.popupView == null) { - this.popupView = BI.createWidget(this.options.popup, { - type: "bi.button_group", - cls: "expander-popup", - layouts: [{ - type: "bi.vertical", - hgap: 0, - vgap: 0 - }] - }); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - //self.setValue(self.getValue()); - self.fireEvent(BI.Expander.EVENT_CHANGE, value, obj); + var setting = { + async: { + enable: true, + url: getUrl, + autoParam: ["id", "name"], + otherParam: FR.cjkEncodeDO(paras) + }, + check: { + enable: true + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true } - }); - this.popupView.setVisible(this.isExpanded()); - BI.nextTick(function () { - self.fireEvent(BI.Expander.EVENT_AFTER_INIT); - }); - } - }, + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + beforeExpand: beforeExpand, + onAsyncSuccess: onAsyncSuccess, + onAsyncError: onAsyncError, + beforeCheck: beforeCheck, + onCheck: onCheck, + onExpand: onExpand, + onCollapse: onCollapse, + onClick: onClick + } + }; + var className = "dark", perTime = 100; - _assertPopupViewRender: function () { - this._assertPopupView(); - if (!this._rendered) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - {el: this.popupView} - ] - }); - this._rendered = true; + function onClick(event, treeId, treeNode) { + self.nodes.checkNode(treeNode, !treeNode.checked, true, true); } - }, - - _hideView: function () { - this.fireEvent(BI.Expander.EVENT_BEFORE_HIDEVIEW); - this._expanded = false; - this.expander.setOpened(false); - this.popupView && this.popupView.invisible(); - this.element.removeClass(this.options.expanderClass); - this.fireEvent(BI.Expander.EVENT_AFTER_HIDEVIEW); - }, + function getUrl(treeId, treeNode) { + var parentNode = self._getParentValues(treeNode); + treeNode.times = treeNode.times || 1; + var param = "id=" + treeNode.id + + "×=" + (treeNode.times++) + + "&parent_values= " + window.encodeURIComponent(FR.jsonEncode(parentNode)) + + "&check_state=" + window.encodeURIComponent(FR.jsonEncode(treeNode.getCheckStatus())); - _popupView: function () { - this._assertPopupViewRender(); - this.fireEvent(BI.Expander.EVENT_BEFORE_POPUPVIEW); - this._expanded = true; - this.expander.setOpened(true); - this.popupView.visible(); - this.element.addClass(this.options.expanderClass); - this.fireEvent(BI.Expander.EVENT_AFTER_POPUPVIEW); - }, + return FR.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; + } - populate: function (items) { - //this._assertPopupView(); - this.popupView && this.popupView.populate.apply(this.popupView, arguments); - this.expander.populate.apply(this.expander, arguments); - }, + function beforeExpand(treeId, treeNode) { + if (!treeNode.isAjaxing) { + if (!treeNode.children) { + treeNode.times = 1; + ajaxGetNodes(treeNode, "refresh"); + } + return true; + } else { + BI.Msg.toast("Please Wait。", "warning"); + return false; + } + } - setEnable: function (arg) { - BI.Expander.superclass.setEnable.apply(this, arguments); - this.expander && this.expander.setEnable(arg); - this.popupView && this.popupView.setEnable(arg); - !arg && this._hideView(); - }, + function onAsyncSuccess(event, treeId, treeNode, msg) { + treeNode.halfCheck = false; + if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) { + return; + } + var zTree = self.nodes; + var totalCount = treeNode.count || 0; - setValue: function (v) { - //this._assertPopupView(); - this.expander.setValue(v); - this.popupView && this.popupView.setValue(v); - }, + //尝试去获取下一组节点,若获取值为空数组,表示获取完成 + // TODO by GUY + if (treeNode.children.length > totalCount) { + treeNode.count = treeNode.children.length; + BI.delay(function () { + ajaxGetNodes(treeNode); + }, perTime); + } else { + //treeNode.icon = ""; + zTree.updateNode(treeNode); + zTree.selectNode(treeNode.children[0]); + //className = (className === "dark" ? "":"dark"); + } + } - getValue: function () { - //this._assertPopupView(); - return this.popupView ? this.popupView.getValue() : []; - }, + function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) { + var zTree = self.nodes; + BI.Msg.toast("Error!", "warning"); + //treeNode.icon = ""; + //zTree.updateNode(treeNode); + } - isViewVisible: function () { - return this.isEnabled() && this.expander.isEnabled() && !!this.popupView && this.popupView.isVisible(); - }, + function ajaxGetNodes(treeNode, reloadType) { + var zTree = self.nodes; + if (reloadType == "refresh") { + //treeNode.icon = FR.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; + zTree.updateNode(treeNode); + } + zTree.reAsyncChildNodes(treeNode, reloadType, true); + } - isExpanded: function () { - return this._expanded; - }, + function beforeCheck(treeId, treeNode) { + treeNode.halfCheck = false; + if (treeNode.checked === true) { + //将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy + //所有的半选状态都需要取消halfCheck=true的情况 + function track(children) { + BI.each(children, function (i, ch) { + if (ch.halfCheck === true) { + ch.halfCheck = false; + track(ch.children); + } + }) + } - showView: function () { - if (this.isEnabled() && this.expander.isEnabled()) { - this._popupView(); + track(treeNode.children); + var treeObj = self.nodes; + var nodes = treeObj.getSelectedNodes(); + $.each(nodes, function (index, node) { + node.halfCheck = false; + }) + } } - }, - hideView: function () { - this._hideView(); - }, + function onCheck(event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } - getView: function () { - return this.popupView; - }, + function onExpand(event, treeId, treeNode) { + treeNode.halfCheck = false; + } - doBehavior: function () { - //this._assertPopupView(); - this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); - }, + function onCollapse(event, treeId, treeNode) { + } - getAllLeaves: function () { - return this.popupView && this.popupView.getAllLeaves(); + return setting; }, - getNodeById: function (id) { - if (this.expander.options.id === id) { - return this.expander; + _getParentValues: function (treeNode) { + if (!treeNode.getParentNode()) { + return []; } - return this.popupView && this.popupView.getNodeById(id); + var parentNode = treeNode.getParentNode(); + var result = this._getParentValues(parentNode); + result = result.concat([this._getNodeValue(parentNode)]); + return result; }, - getNodeByValue: function (value) { - if (this.expander.getValue() === value) { - return this.expander; - } - return this.popupView && this.popupView.getNodeByValue(value); + _getNodeValue: function (node) { + //去除标红 + return node.value || node.text.replace(/<[^>]+>/g, ""); }, - destroyed: function () { - this.popupView && this.popupView.destroy(); - } -}); -BI.Expander.EVENT_EXPAND = "EVENT_EXPAND"; -BI.Expander.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.Expander.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.Expander.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Expander.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.Expander.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.Expander.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.Expander.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.Expander.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - -$.shortcut("bi.expander", BI.Expander);/** - * Created by GUY on 2015/6/26. - * @class BI.ButtonGroup - * @extends BI.Widget - */ - -BI.ButtonGroup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ButtonGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-group", - behaviors: {}, - items: [ - { - el: {type: "bi.text_button", text: "", value: ""} - } - ], - chooseType: BI.Selection.Single, - layouts: [{ - type: "bi.center", - hgap: 0, - vgap: 0 - }] - }) + //获取半选框值 + _getHalfSelectedValues: function (map, node) { + var self = this; + var checkState = node.getCheckStatus(); + //将未选的去掉 + if (checkState.checked === false && checkState.half === false) { + return; + } + //如果节点已展开,并且是半选 + if (BI.isNotEmptyArray(node.children) && checkState.half === true) { + var children = node.children; + BI.each(children, function (i, ch) { + self._getHalfSelectedValues(map, ch); + }); + return; + } + var parent = node.parentValues || self._getParentValues(node); + var path = parent.concat(this._getNodeValue(node)); + if (BI.isNotEmptyArray(node.children) || checkState.half === false) { + this._buildTree(map, path); + return; + } + var storeValues = BI.deepClone(this.options.paras.selected_values); + var treeNode = this._getTree(storeValues, path); + this._addTreeNode(map, parent, this._getNodeValue(node), treeNode); }, - _init: function () { - BI.ButtonGroup.superclass._init.apply(this, arguments); - var behaviors = {}; - BI.each(this.options.behaviors, function (key, rule) { - behaviors[key] = BI.BehaviorFactory.createBehavior(key, { - rule: rule - }) + _getTree: function (map, values) { + var cur = map; + BI.any(values, function (i, value) { + if (cur[value] == null) { + return true; + } + cur = cur[value]; }); - this.behaviors = behaviors; - this.populate(this.options.items); + return cur; }, - _createBtns: function (items) { - var o = this.options; - return BI.createWidgets(BI.createItems(items, { - type: "bi.text_button" - })); + _addTreeNode: function (map, values, key, value) { + var cur = map; + BI.each(values, function (i, value) { + if (cur[value] == null) { + cur[value] = {}; + } + cur = cur[value]; + }); + cur[key] = value; }, - _btnsCreator: function (items) { - var self = this, args = Array.prototype.slice.call(arguments), o = this.options; - var buttons = this._createBtns(items); - args[0] = buttons; + //构造树节点 + _buildTree: function (map, values) { + var cur = map; + BI.each(values, function (i, value) { + if (cur[value] == null) { + cur[value] = {}; + } + cur = cur[value]; + }) + }, - BI.each(this.behaviors, function (i, behavior) { - behavior.doBehavior.apply(behavior, args); - }); - BI.each(buttons, function (i, btn) { - btn.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - switch (o.chooseType) { - case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: - self.setValue(btn.getValue()); - break; - case BI.ButtonGroup.CHOOSE_TYPE_NONE: - self.setValue([]); - break; + //获取选中的值 + _getSelectedValues: function () { + var self = this; + var hashMap = {}; + var rootNoots = this.nodes.getNodes(); + track(rootNoots); + function track(nodes) { + BI.each(nodes, function (i, node) { + var checkState = node.getCheckStatus(); + if (checkState.checked === true || checkState.half === true) { + if (checkState.half === true) { + self._getHalfSelectedValues(hashMap, node); + } else { + var parentValues = node.parentValues || self._getParentValues(node); + var values = parentValues.concat([self._getNodeValue(node)]); + self._buildTree(hashMap, values); } - self.fireEvent(BI.ButtonGroup.EVENT_CHANGE, value, obj); } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - btn.on(BI.Events.DESTROY, function () { - BI.remove(self.buttons, btn); - }) - }); - - return buttons; - }, - - _packageBtns: function (btns) { - var o = this.options; - - for (var i = o.layouts.length - 1; i > 0; i--) { - btns = BI.map(btns, function (k, it) { - return BI.extend({}, o.layouts[i], { - items: [ - BI.extend({}, o.layouts[i].el, { - el: it - }) - ] - }) }) } - return btns; - }, - _packageItems: function (items, packBtns) { - return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); + return hashMap; }, - _packageLayout: function (items) { - var o = this.options, layout = BI.deepClone(o.layouts[0]); - - var lay = BI.formatEL(layout).el; - while (lay && lay.items && !BI.isEmpty(lay.items)) { - lay = BI.formatEL(lay.items[0]).el; + //处理节点 + _dealWidthNodes: function (nodes) { + var self = this, o = this.options; + //处理标红 + if (BI.isKey(o.paras.keyword)) { + var keyword = o.paras.keyword; + var ns = BI.Tree.arrayFormat(nodes); + BI.each(ns, function (i, n) { + n.text = $("
    ").__textKeywordMarked__(n.text, keyword, n.py).html(); + }); } - lay.items = items; - return layout; + return nodes; }, + _loadMore: function () { + var self = this, o = this.options; + this.tip.setLoading(); + var op = BI.extend({}, o.paras, { + times: ++this.times + }); + o.itemsCreator(op, function (res) { + if (self._stop === true) { + return; + } + var hasNext = !!res.hasNext, nodes = res.items || []; - doBehavior: function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(this.buttons); - BI.each(this.behaviors, function (i, behavior) { - behavior.doBehavior.apply(behavior, args); - }) + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); }, - prependItems: function (items) { - var o = this.options; - var btns = this._btnsCreator.apply(this, arguments); - this.buttons = BI.concat(btns, this.buttons); - - //如果是一个简单的layout - if (o.layouts.length === 1 && !BI.isNotEmptyArray(o.layouts[0].items) - && this.layouts && this.layouts.prependItems) { - this.layouts.prependItems(btns); - return; - } - - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().prependTo(this.element); - }, - - addItems: function (items) { - var o = this.options; - var btns = this._btnsCreator.apply(this, arguments); - this.buttons = BI.concat(this.buttons, btns); - - //如果是一个简单的layout - if (o.layouts.length === 1 && !BI.isNotEmptyArray(o.layouts[0].items) - && this.layouts && this.layouts.addItems) { - this.layouts.addItems(btns); - return; - } - - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().appendTo(this.element); - }, - - removeItemAt: function (indexes) { - var self = this; - indexes = BI.isArray(indexes) ? indexes : [indexes]; - var buttons = []; - BI.each(indexes, function (i, index) { - buttons.push(self.buttons[index]); + //生成树内部方法 + _initTree: function (setting) { + var self = this, o = this.options; + self.fireEvent(BI.Events.INIT); + this.times = 1; + var tree = this.tree; + tree.empty(); + this.loading(); + this.tip.setVisible(false); + var callback = function (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + }; + var op = BI.extend({}, o.paras, { + times: 1, + type: BICst.TREE.TREE_REQ_TYPE.INIT_DATA }); - BI.each(buttons, function (i, btn) { - btn && btn.destroy(); - }) - }, - removeItems: function (v) { - v = BI.isArray(v) ? v : [v]; - var indexes = []; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - indexes.push(i); + o.itemsCreator(op, function (res) { + if (self._stop === true) { + return; + } + var hasNext = !!res.hasNext, nodes = res.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes)); } + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + op.times === 1 && self.fireEvent(BI.Events.AFTERINIT); }); - this.removeItemAt(indexes); }, - populate: function (items) { - this.options.items = items || []; - this.empty(); - - this.buttons = this._btnsCreator.apply(this, arguments); - var items = this._packageItems(items, this._packageBtns(this.buttons)); + //构造树结构, + initTree: function (nodes, setting) { + var setting = setting || { + async: { + enable: false + }, + check: { + enable: false + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "" + }, + callback: {} + }; + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, - this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); + start: function () { + this._stop = false; }, - setEnable: function (b) { - BI.ButtonGroup.superclass.setEnable.apply(this, arguments); - BI.each(this.buttons, function (i, item) { - item.setEnable(b); - }); + stop: function () { + this._stop = true; }, - setNotSelectedValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); + //生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._createTree(); + this.start(); + this._initTree(setting); }, - setEnabledValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setEnable(true); - } else { - item.setEnable(false); - } - }); + populate: function () { + this.stroke.apply(this, arguments); }, - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); + hasChecked: function () { + var treeObj = this.nodes; + return treeObj.getCheckedNodes(true).length > 0; }, - getNotSelectedValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !(item.isSelected && item.isSelected())) { - v.push(item.getValue()); - } - }); - return v; + checkAll: function (checked) { + this.nodes && this.nodes.checkAllNodes(checked); }, - getValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && item.isSelected && item.isSelected()) { - v.push(item.getValue()); - } - }); - return v; + expandAll: function (flag) { + this.nodes && this.nodes.expandAll(flag); }, - getAllButtons: function () { - return this.buttons; + setValue: function (value, param) { + this.setSelectedValue(value); + this.checkAll(false); + this.updateValue(value, param); + this.refresh(); }, - getAllLeaves: function () { - return this.buttons; + setSelectedValue: function (value) { + this.options.paras.selected_values = value || {}; + this.selected_values = BI.deepClone(value) || {}; }, - getSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isSelected && item.isSelected()) { - btns.push(item); - } + updateValue: function (values, param) { + if (!this.nodes) { + return; + } + param || (param = "value"); + var treeObj = this.nodes; + BI.each(values, function (v, op) { + var nodes = treeObj.getNodesByParam(param, v, null); + BI.each(nodes, function (j, node) { + BI.extend(node, {checked: true}, op); + treeObj.updateNode(node); + }) }); - return btns; }, - getNotSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isSelected && !item.isSelected()) { - btns.push(item); - } - }); - return btns; + refresh: function () { + this.nodes && this.nodes.refresh(); }, - getIndexByValue: function (value) { - var index = -1; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.getValue() === value) { - index = i; - return true; - } - }); - return index; + getValue: function () { + if (!this.nodes) { + return null; + } + return this._getSelectedValues(); }, - getNodeById: function (id) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.options.id === id) { - node = item; - return true; - } - }); - return node; + empty: function () { + BI.isNotNull(this.nodes) && this.nodes.destroy(); }, - getNodeByValue: function (value) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.getValue() === value) { - node = item; - return true; - } - }); - return node; + destroy: function () { + this.stop(); + this.nodes && this.nodes.destroy(); + BI.TreeView.superclass.destroy.apply(this, arguments); } }); -BI.extend(BI.ButtonGroup, { - CHOOSE_TYPE_SINGLE: BI.Selection.Single, - CHOOSE_TYPE_MULTI: BI.Selection.Multi, - CHOOSE_TYPE_ALL: BI.Selection.All, - CHOOSE_TYPE_NONE: BI.Selection.None, - CHOOSE_TYPE_DEFAULT: BI.Selection.Default +BI.extend(BI.TreeView, { + REQ_TYPE_INIT_DATA: 1, + REQ_TYPE_ADJUST_DATA: 2, + REQ_TYPE_CALCULATE_SELECT_DATA: 3, + REQ_TYPE_SELECTED_DATA: 4 }); -BI.ButtonGroup.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.button_group", BI.ButtonGroup); -/** - * Created by GUY on 2015/8/10. - */ +BI.TreeView.EVENT_CHANGE = "EVENT_CHANGE"; +BI.TreeView.EVENT_INIT = BI.Events.INIT; +BI.TreeView.EVENT_AFTERINIT = BI.Events.AFTERINIT; -BI.ComboGroup = BI.inherit(BI.Widget, { +$.shortcut("bi.tree", BI.TreeView);/** + * guy + * 同步树 + * @class BI.SyncTree + * @extends BI.TreeView + */ +BI.SyncTree = BI.inherit(BI.TreeView, { _defaultConfig: function () { - return BI.extend(BI.ComboGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-combo-group", - - //以下这些属性对每一个combo都是公用的 - trigger: "click,hover", - direction: "right", - adjustLength: 0, - isDefaultInit: false, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - - el: {type: "bi.text_button", text: "", value: ""}, - children: [], - - popup: { - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical" - }] - } - } - }) + return BI.extend(BI.SyncTree.superclass._defaultConfig.apply(this, arguments), {}) }, - _init: function () { - BI.ComboGroup.superclass._init.apply(this, arguments); - this.populate(this.options.el); + BI.SyncTree.superclass._init.apply(this, arguments); }, - populate: function (item) { - var self = this, o = this.options; - var children = o.children; - if (BI.isEmpty(children)) { - throw new Error("ComboGroup构造错误"); - } - BI.each(children, function (i, ch) { - var son = BI.formatEL(ch).el.children; - ch = BI.formatEL(ch).el; - if (!BI.isEmpty(son)) { - ch.el = BI.clone(ch); - ch.children = son; - ch.type = "bi.combo_group"; - ch.action = o.action; - ch.height = o.height; - ch.direction = o.direction; - ch.isDefaultInit = o.isDefaultInit; - ch.isNeedAdjustHeight = o.isNeedAdjustHeight; - ch.isNeedAdjustWidth = o.isNeedAdjustWidth; - ch.adjustLength = o.adjustLength; - ch.popup = o.popup; - } - }) - this.combo = BI.createWidget({ - type: "bi.combo", - element: this, - height: o.height, - trigger: o.trigger, - direction: o.direction, - isDefaultInit: o.isDefaultInit, - isNeedAdjustWidth: o.isNeedAdjustWidth, - isNeedAdjustHeight: o.isNeedAdjustHeight, - adjustLength: o.adjustLength, - el: item, - popup: BI.extend({}, o.popup, { - el: BI.extend({ - items: children - }, o.popup.el) - }) - }) - this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.ComboGroup.EVENT_CHANGE, obj); + //配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, + otherParam: FR.cjkEncodeDO(paras) + }, + check: { + enable: true + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + beforeCheck: beforeCheck, + onCheck: onCheck, + beforeExpand: beforeExpand, + onExpand: onExpand, + onCollapse: onCollapse, + onClick: onClick } - }) - }, + }; - setEnable: function (b) { - BI.ComboGroup.superclass.setEnable.apply(this, arguments); - this.combo && this.combo.setEnable(b); - }, + function onClick(event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + zTree.checkNode(treeNode, !treeNode.checked, true, true); + } - getValue: function () { - return this.combo.getValue(); - }, + function beforeCheck(treeId, treeNode) { + treeNode.halfCheck = false; + if (treeNode.checked === true) { + //将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy + //所有的半选状态都需要取消halfCheck=true的情况 + function track(children) { + BI.each(children, function (i, ch) { + if (ch.halfCheck === true) { + ch.halfCheck = false; + track(ch.children); + } + }) + } - setValue: function (v) { - this.combo.setValue(v); - } -}); -BI.ComboGroup.EVENT_CHANGE = "EVENT_CHANGE"; + track(treeNode.children); -$.shortcut("bi.combo_group", BI.ComboGroup);/** - * 加载控件 - * - * Created by GUY on 2015/8/31. - * @class BI.Loader - * @extends BI.Widget - */ -BI.Loader = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Loader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-loader", + var treeObj = $.fn.zTree.getZTreeObj(treeId); + var nodes = treeObj.getSelectedNodes(); + BI.each(nodes, function (index, node) { + node.halfCheck = false; + }) + } + } - direction: "top", - isDefaultInit: true,//是否默认初始化数据 - logic: { - dynamic: true, - scrolly: true - }, + function beforeExpand(treeId, treeNode) { + self._expandNode(treeId, treeNode); + } - //下面是button_group的属性 - el: { - type: "bi.button_group" - }, + function onCheck(event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } - items: [], - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, + function onExpand(event, treeId, treeNode) { + treeNode.halfCheck = false; + } - //下面是分页信息 - count: false, - prev: false, - next: {}, - hasPrev: BI.emptyFn, - hasNext: BI.emptyFn - }) - }, + function onCollapse(event, treeId, treeNode) { + treeNode.halfCheck = false; + } - _prevLoad: function () { - var self = this, o = this.options; - this.prev.setLoading(); - o.itemsCreator.apply(this, [{times: --this.times}, function () { - self.prev.setLoaded(); - self.prependItems.apply(self, arguments); - }]); + return setting; }, - _nextLoad: function () { + _selectTreeNode: function (treeId, treeNode) { var self = this, o = this.options; - this.next.setLoading(); - o.itemsCreator.apply(this, [{times: ++this.times}, function () { - self.next.setLoaded(); - self.addItems.apply(self, arguments); - }]); + var parent_values = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); + var name = this._getNodeValue(treeNode) +// var values = parent_values.concat([name]); + if (treeNode.checked === true) { + } else { + var tNode = treeNode; + var pNode = this._getTree(this.selected_values, parent_values); + if (BI.isNotNull(pNode[name])) { + delete pNode[name]; + } + while (tNode != null && BI.isEmpty(pNode)) { + parent_values = parent_values.slice(0, parent_values.length - 1); + tNode = tNode.getParentNode(); + if (tNode != null) { + pNode = this._getTree(this.selected_values, parent_values); + name = this._getNodeValue(tNode); + delete pNode[name]; + } + } + } + BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); }, - _init: function () { - BI.Loader.superclass._init.apply(this, arguments); + //展开节点 + _expandNode: function (treeId, treeNode) { var self = this, o = this.options; - if (o.itemsCreator === false) { - o.prev = false; - o.next = false; - } - if (o.prev !== false) { - this.prev = BI.createWidget(BI.extend({ - type: "bi.loading_bar" - }, o.prev)); - this.prev.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._prevLoad(); - } - }); - } - - this.button_group = BI.createWidget(o.el, { - type: "bi.button_group", - chooseType: 0, - items: o.items, - behaviors: {}, - layouts: [{ - type: "bi.vertical" - }] + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + "id": treeNode.id, + "times": 1, + "parent_values": parentValues.concat(this._getNodeValue(treeNode)), + "check_state": treeNode.getCheckStatus() }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Loader.EVENT_CHANGE, obj); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); } - }); - - if (o.next !== false) { - this.next = BI.createWidget(BI.extend({ - type: "bi.loading_bar" - }, o.next)); - this.next.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._nextLoad(); - } - }) - } + }; + var times = 1; - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ - scrolly: true - }, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.prev, this.button_group, this.next) - })))); + function callback(nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); - o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { - o.isDefaultInit && BI.isEmpty(o.items) && this.populate(); - }, this)); - if (BI.isNotEmptyArray(o.items)) { - this.populate(o.items); + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } } - }, - hasPrev: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; + if (!treeNode.children) { + o.itemsCreator(op, complete) } - return !!o.hasPrev.apply(this, [{ - times: this.times, - count: this.count - }]) }, - hasNext: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; + _join: function (valueA, valueB) { + var self = this; + var map = {}; + track([], valueA, valueB); + track([], valueB, valueA); + function track(parent, node, compare) { + BI.each(node, function (n, item) { + if (BI.isNull(compare[n])) { + self._addTreeNode(map, parent, n, item); + } else if (BI.isEmpty(compare[n])) { + self._addTreeNode(map, parent, n, {}); + } else { + track(parent.concat([n]), node[n], compare[n]); + } + }) } - return !!o.hasNext.apply(this, [{ - times: this.times, - count: this.count - }]) - }, - prependItems: function (items) { - this.count += items.length; - if (this.next !== false) { - if (this.hasPrev()) { - this.options.items = this.options.items.concat(items); - this.prev.setLoaded(); - } else { - this.prev.setEnd(); - } - } - this.button_group.prependItems.apply(this.button_group, arguments); + return map; }, - addItems: function (items) { - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.options.items = this.options.items.concat(items); - this.next.setLoaded(); - } else { - this.next.setEnd(); - } - } - this.button_group.addItems.apply(this.button_group, arguments); + hasChecked: function () { + return !BI.isEmpty(this.selected_values) || BI.SyncTree.superclass.hasChecked.apply(this, arguments); }, - populate: function (items) { - var self = this, o = this.options; - if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { - o.itemsCreator.apply(this, [{times: 1}, function () { - if (arguments.length === 0) { - throw new Error("arguments can not be null!!!"); - } - self.populate.apply(self, arguments); - o.onLoaded(); - }]); - return; + getValue: function () { + if (!this.nodes) { + return {}; } - this.options.items = items; - this.times = 1; - this.count = 0; - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.next.setLoaded(); - } else { - this.next.invisible(); - } + var checkedValues = this._getSelectedValues(); + if (BI.isEmpty(checkedValues)) { + return this.selected_values; } - if (BI.isObject(this.prev)) { - if (this.hasPrev()) { - this.prev.setLoaded(); - } else { - this.prev.invisible(); - } + if (BI.isEmpty(this.selected_values)) { + return checkedValues; } - this.button_group.populate.apply(this.button_group, arguments); - }, - - setEnable: function (v) { - this.button_group.setEnable(v); - }, - - doBehavior: function () { - this.button_group.doBehavior.apply(this.button_group, arguments); - }, - - setNotSelectedValue: function () { - this.button_group.setNotSelectedValue.apply(this.button_group, arguments); + return this._join(checkedValues, this.selected_values); }, - getNotSelectedValue: function () { - return this.button_group.getNotSelectedValue(); - }, + //生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + //取消选中时使用 + this.selected_values = BI.deepClone(this.options.paras.selected_values) || {}; + var setting = this._configSetting(); + this._initTree(setting); + } +}); - setValue: function () { - this.button_group.setValue.apply(this.button_group, arguments); +$.shortcut("bi.sync_tree", BI.SyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.PartTree + * @extends BI.SyncTree + */ +BI.PartTree = BI.inherit(BI.SyncTree, { + _defaultConfig: function () { + return BI.extend(BI.PartTree.superclass._defaultConfig.apply(this, arguments), {}) }, - getValue: function () { - return this.button_group.getValue.apply(this.button_group, arguments); + _init: function () { + BI.PartTree.superclass._init.apply(this, arguments); }, - getAllButtons: function () { - return this.button_group.getAllButtons(); + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.last_search_value = d.last_search_value; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); }, - getAllLeaves: function () { - return this.button_group.getAllLeaves(); + _selectTreeNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parent_values = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); + var name = this._getNodeValue(treeNode) +// var values = parent_values.concat([name]); + if (treeNode.checked === true) { + BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); + } else { + o.itemsCreator(BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA, + selected_values: this.selected_values, + not_selected_value: name, + parent_values: parent_values + }), function (new_values) { + if (BI.isEqual(self.selected_values, new_values)) { + var tNode = treeNode; + var pNode = self._getTree(new_values, parent_values); + if (pNode[name]) { + delete pNode[name]; + } + while (tNode != null && BI.isEmpty(pNode)) { + parent_values = parent_values.slice(0, parent_values.length - 1); + tNode = tNode.getParentNode(); + if (tNode != null) { + pNode = self._getTree(new_values, parent_values); + name = self._getNodeValue(tNode); + delete pNode[name]; + } + } + } + self.selected_values = new_values; + BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); + }); + } }, - getSelectedButtons: function () { - return this.button_group.getSelectedButtons(); - }, + _getSelectedValues: function () { + var self = this; + var hashMap = {}; + var rootNoots = this.nodes.getNodes(); + track(rootNoots); + function track(nodes) { + BI.each(nodes, function (i, node) { + var checkState = node.getCheckStatus(); + if (checkState.checked === false) { + return true; + } + var parentValues = node.parentValues || self._getParentValues(node); + //把文字中的html去掉,其实就是把文字颜色去掉 + var values = parentValues.concat([self._getNodeValue(node)]); + self._buildTree(hashMap, values); +// if(checkState.checked === true && checkState.half === false && nodes[i].flag === true){ +// continue; +// } + if (BI.isNotEmptyArray(node.children)) { + track(node.children); + return true; + } + if (checkState.half === true) { + self._getHalfSelectedValues(hashMap, node); + } + }) + } - getNotSelectedButtons: function () { - return this.button_group.getNotSelectedButtons(); + return hashMap; }, - getIndexByValue: function (value) { - return this.button_group.getIndexByValue(value); - }, + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.last_search_value = d.last_search_value; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes)); + } + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; - getNodeById: function (id) { - return this.button_group.getNodeById(id); - }, + function callback(nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } - getNodeByValue: function (value) { - return this.button_group.getNodeByValue(value); + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); }, - empty: function () { - this.button_group.empty(); - BI.each([this.prev, this.next], function (i, ob) { - ob && ob.setVisible(false); + getValue: function () { + var o = this.options; + var result = BI.PartTree.superclass.getValue.apply(this, arguments); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selected_values: result + }, function (res) { + result = res; }); + return result; + }, + + //生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.last_search_value; + //取消选中时使用 + this.selected_values = BI.deepClone(o.paras.selected_values) || {}; + //delete this.options.paras.selected_values; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); } }); -BI.Loader.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.loader", BI.Loader);/** - * Created by GUY on 2015/6/26. - */ -BI.Navigation = BI.inherit(BI.Widget, { - _defaultConfig: function(){ - return BI.extend(BI.Navigation.superclass._defaultConfig.apply(this,arguments), { - direction: "bottom",//top, bottom, left, right, custom - logic: { - dynamic: false - }, - defaultShowIndex: 0, - tab: { - type: "bi.button_group", - items: [], - layouts: [] - }, - cardCreator: function(v){ - return BI.createWidget(); - }, +$.shortcut("bi.part_tree", BI.PartTree);BI.Resizers = new BI.ResizeController(); +BI.Layers = new BI.LayerController(); +BI.Maskers = new BI.MaskersController(); +BI.Bubbles = new BI.BubblesController(); +BI.Tooltips = new BI.TooltipsController(); +BI.Popovers = new BI.FloatBoxController(); +BI.Broadcasts = new BI.BroadcastController(); +/** + * canvas绘图 + * + * Created by GUY on 2015/11/18. + * @class BI.Canvas + * @extends BI.Widget + */ +BI.Canvas = BI.inherit(BI.Widget, { - afterCardCreated: BI.emptyFn, - afterCardShow: BI.emptyFn + _defaultConfig: function () { + return BI.extend(BI.Canvas.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-canvas" }) }, - _init: function(){ - BI.Navigation.superclass._init.apply(this,arguments); + _init: function () { + BI.Canvas.superclass._init.apply(this, arguments); var self = this, o = this.options; - this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); - this.cardMap = {}; - this.showIndex = 0; - this.layout = BI.createWidget({ - type: "bi.card" - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) - })))); - - - new BI.ShowListener({ - eventObj: this.tab, - cardLayout: this.layout, - cardNameCreator: function(v){ - return self.showIndex + v; - }, - cardCreator: function(v){ - var card = o.cardCreator(v); - self.cardMap[v] = card; - return card; - }, - afterCardCreated: BI.bind(this.afterCardCreated, this), - afterCardShow: BI.bind(this.afterCardShow, this) - }) - if(o.defaultShowIndex !== false){ - this.setSelect(o.defaultShowIndex); + var canvas = document.createElement("canvas"); + if (!document.createElement('canvas').getContext) { + canvas = window.G_vmlCanvasManager.initElement(canvas); } + this.element.append(canvas); + canvas.width = o.width; + canvas.height = o.height; + $(canvas).width("100%"); + $(canvas).height("100%"); + this.canvas = canvas; + this._queue = []; }, - afterCardCreated: function(v){ - var self = this; - this.cardMap[v].on(BI.Controller.EVENT_CHANGE, function(type, value, obj){ - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if(type === BI.Events.CLICK) { - self.fireEvent(BI.Navigation.EVENT_CHANGE, obj); - } - }) - this.options.afterCardCreated.apply(this, arguments); + _getContext: function () { + if (!this.ctx) { + this.ctx = this.canvas.getContext('2d'); + } + return this.ctx; }, - afterCardShow: function(v){ - this.showIndex = v; - this.options.afterCardShow.apply(this, arguments); + _attr: function (key, value) { + var self = this; + if (BI.isNull(key)) { + return; + } + if (BI.isObject(key)) { + BI.each(key, function (k, v) { + self._queue.push({k: k, v: v}); + }); + return; + } + this._queue.push({k: key, v: value}); }, - populate: function(){ - var card = this.layout.getShowingCard(); - if(card){ - return card.populate.apply(card, arguments); + _line: function (x0, y0) { + var self = this; + var args = [].slice.call(arguments, 2); + if (BI.isOdd(args.length)) { + this._attr(BI.last(args)); + args = BI.initial(args); } + this._attr("moveTo", [x0, y0]); + var odd = BI.filter(args, function (i) { + return i % 2 === 0; + }); + var even = BI.filter(args, function (i) { + return i % 2 !== 0; + }); + args = BI.zip(odd, even); + BI.each(args, function (i, point) { + self._attr("lineTo", point); + }); }, - setSelect: function(v){ - this.showIndex = v; - if(!this.layout.isCardExisted(v)){ - var card = this.options.cardCreator(v); - this.cardMap[v] = card; - this.layout.addCardByName(v, card); - this.afterCardCreated(v); - } - this.layout.showCardByName(v); - BI.nextTick(BI.bind(this.afterCardShow, this, v)); + line: function (x0, y0, x1, y1) { + this._line.apply(this, arguments); + this._attr("stroke", []); }, - getSelect: function(){ - return this.showIndex; + rect: function (x, y, w, h, color) { + this._attr("fillStyle", color); + this._attr("fillRect", [x, y, w, h]); }, - getSelectedCard: function(){ - if(BI.isKey(this.showIndex)){ - return this.cardMap[this.showIndex]; - } + circle: function (x, y, radius, color) { + this._attr({ + fillStyle: color, + beginPath: [], + arc: [x, y, radius, 0, Math.PI * 2, true], + closePath: [], + fill: [] + }); }, - /** - * @override - */ - setValue: function(v){ - var card = this.layout.getShowingCard(); - if(card){ - card.setValue(v); - } + hollow: function () { + this._attr("beginPath", []); + this._line.apply(this, arguments); + this._attr("closePath", []); + this._attr("stroke", []); }, - /** - * @override - */ - getValue: function(){ - var card = this.layout.getShowingCard(); - if(card){ - return card.getValue(); - } + solid: function () { + this.hollow.apply(this, arguments); + this._attr("fill", []); }, - empty: function(){ - this.layout.deleteAllCard(); - this.cardMap = {}; + gradient: function (x0, y0, x1, y1, start, end) { + var grd = this._getContext().createLinearGradient(x0, y0, x1, y1); + grd.addColorStop(0, start); + grd.addColorStop(1, end); + return grd; + }, + + reset: function () { + this._getContext().clearRect(0, 0, this.canvas.width, this.canvas.height); + }, + + stroke: function (callback) { + var self = this; + BI.nextTick(function () { + var ctx = self._getContext(); + BI.each(self._queue, function (i, q) { + if (BI.isFunction(ctx[q.k])) { + ctx[q.k].apply(ctx, q.v); + } else { + ctx[q.k] = q.v; + } + }); + self._queue = []; + callback && callback(); + }); } }); -BI.Navigation.EVENT_CHANGE = "EVENT_CHANGE"; - -$.shortcut("bi.navigation", BI.Navigation);/** - * 搜索逻辑控件 +$.shortcut("bi.canvas", BI.Canvas);/** + * Collection * - * Created by GUY on 2015/9/28. - * @class BI.Searcher + * Created by GUY on 2016/1/15. + * @class BI.Collection * @extends BI.Widget */ - -BI.Searcher = BI.inherit(BI.Widget, { +BI.Collection = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.Searcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-searcher", - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - vgap: 0, - hgap: 0, - - isDefaultInit: false, - isAutoSearch: true, //是否自动搜索 - isAutoSync: true, //是否自动同步数据, 即是否保持搜索面板和adapter面板状态值的统一 - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - - //isAutoSearch为false时启用 - onSearch: function (op, callback) { - callback([]) - }, - - - el: { - type: "bi.search_editor" - }, - - popup: { - type: "bi.searcher_view" - }, - - adapter: null, - masker: { //masker层 - offset: {} - } - }) + return BI.extend(BI.Collection.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-collection", + width: 400, + height: 300, + overflowX: true, + overflowY: true, + cellSizeAndPositionGetter: BI.emptyFn, + horizontalOverscanSize: 0, + verticalOverscanSize: 0, + scrollLeft: 0, + scrollTop: 0, + items: [] + }); }, _init: function () { - BI.Searcher.superclass._init.apply(this, arguments); + BI.Collection.superclass._init.apply(this, arguments); var self = this, o = this.options; - - this.editor = BI.createWidget(o.el, { - type: "bi.search_editor" + this.renderedCells = []; + this.renderedKeys = []; + this._scrollLock = false; + this._debounceRelease = BI.debounce(function () { + self._scrollLock = false; + }, 150); + this.container = BI.createWidget({ + type: "bi.absolute" + }); + this.element.scroll(function () { + if (self._scrollLock === true) { + return; + } + o.scrollLeft = self.element.scrollLeft(); + o.scrollTop = self.element.scrollTop(); + self._calculateChildrenToRender(); + self.fireEvent(BI.Collection.EVENT_SCROLL, { + scrollLeft: o.scrollLeft, + scrollTop: o.scrollTop + }); }); - BI.createWidget({ type: "bi.vertical", element: this, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - hgap: o.hgap, - items: [this.editor] + scrollable: o.overflowX === true && o.overflowY === true, + scrolly: o.overflowX === false && o.overflowY === true, + scrollx: o.overflowX === true && o.overflowY === false, + items: [this.container] }); - o.isDefaultInit && (this._assertPopupView()); + if (o.items.length > 0) { + this._calculateSizeAndPositionData(); + this._populate(); + } + if (o.scrollLeft !== 0 || o.scrollTop !== 0) { + BI.nextTick(function () { + self.element.scrollTop(o.scrollTop); + self.element.scrollLeft(o.scrollLeft); + }); + } + }, - var search = BI.debounce(BI.bind(this._search, this), BI.EVENT_RESPONSE_TIME, true); - this.editor.on(BI.Controller.EVENT_CHANGE, function (type) { - switch (type) { - case BI.Events.STARTEDIT: - self._startSearch(); - break; - case BI.Events.EMPTY: - self._stopSearch(); - break; - case BI.Events.CHANGE: - search(); - break; - case BI.Events.PAUSE: - self._pauseSearch(); - break; + _calculateSizeAndPositionData: function () { + var o = this.options; + var cellMetadata = []; + var sectionManager = new BI.SectionManager(); + var height = 0; + var width = 0; + + for (var index = 0, len = o.items.length; index < len; index++) { + var cellMetadatum = o.cellSizeAndPositionGetter(index); + + if ( + cellMetadatum.height == null || isNaN(cellMetadatum.height) || + cellMetadatum.width == null || isNaN(cellMetadatum.width) || + cellMetadatum.x == null || isNaN(cellMetadatum.x) || + cellMetadatum.y == null || isNaN(cellMetadatum.y) + ) { + throw Error(); } - }) - }, - _assertPopupView: function () { - var self = this, o = this.options; - if (!BI.Maskers.has(this.getName())) { - this.popupView = BI.createWidget(o.popup, { - type: "bi.searcher_view", - chooseType: o.chooseType - }); - BI.Maskers.create(this.getName(), o.adapter, { - offset: o.masker.offset, - container: this, - render: this.popupView - }); + height = Math.max(height, cellMetadatum.y + cellMetadatum.height); + width = Math.max(width, cellMetadatum.x + cellMetadatum.width); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - if (o.isAutoSync) { - var values = o.adapter.getValue(); - if (!obj.isSelected()) { - o.adapter.setValue(BI.deepWithout(values, obj.getValue())); - } else { - switch (o.chooseType) { - case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: - o.adapter.setValue([obj.getValue()]); - break; - case BI.ButtonGroup.CHOOSE_TYPE_MULTI: - values.push(obj.getValue()); - o.adapter.setValue(values); - break; - } - } - } - self.fireEvent(BI.Searcher.EVENT_CHANGE, value, obj); - } - }); - BI.nextTick(function () { - self.fireEvent(BI.Searcher.EVENT_AFTER_INIT); - }); + cellMetadatum.index = index; + cellMetadata[index] = cellMetadatum; + sectionManager.registerCell(cellMetadatum, index); } - }, - _startSearch: function () { - this._assertPopupView(); - this._stop = false; - this._isSearching = true; - this.fireEvent(BI.Searcher.EVENT_START); - this.popupView.startSearch && this.popupView.startSearch(); - //搜索前先清空dom - BI.Maskers.get(this.getName()).empty(); - BI.nextTick(function (name) { - BI.Maskers.show(name); - }, this.getName()); + this._cellMetadata = cellMetadata; + this._sectionManager = sectionManager; + this._height = height; + this._width = width; }, - _pauseSearch: function () { - var o = this.options, name = this.getName(); - this._stop = true; - BI.Maskers.hide(name); - if (BI.Maskers.has(name) && this._isSearching === true) { - this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); - this.fireEvent(BI.Searcher.EVENT_PAUSE); - } - this._isSearching = false; + _cellRenderers: function (height, width, x, y) { + this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y); + return this._cellGroupRenderer() }, - _stopSearch: function () { - var o = this.options, name = this.getName(); - this._stop = true; - BI.Maskers.hide(name); - if (BI.Maskers.has(name) && this._isSearching === true) { - //搜索后清空dom - BI.nextTick(function () { - BI.Maskers.has(name) && BI.Maskers.get(name).empty(); - }); - this.popupView && this.popupView.stopSearch && this.popupView.stopSearch(); - this.fireEvent(BI.Searcher.EVENT_STOP); - } - this._isSearching = false; + _cellGroupRenderer: function () { + var self = this, o = this.options; + var rendered = []; + BI.each(this._lastRenderedCellIndices, function (i, index) { + var cellMetadata = self._sectionManager.getCellMetadata(index); + rendered.push(cellMetadata); + }); + return rendered; }, - _search: function () { - var self = this, o = this.options, keyword = this.editor.getValue(); - if (keyword === "" || this._stop) { - return; - } - if (o.isAutoSearch) { - var items = (o.adapter.getItems && o.adapter.getItems()) || o.adapter.attr("items") || []; - var finding = BI.Func.getSearchResult(items, keyword); - var matched = finding.matched, finded = finding.finded; - this.popupView.populate(finded, matched, keyword); - o.isAutoSync && this.popupView.setValue(o.adapter.getValue()); - self.fireEvent(BI.Searcher.EVENT_SEARCHING); - return; - } - this.popupView.loading && this.popupView.loading(); - o.onSearch({ - times: 1, - keyword: keyword, - selectedValues: o.adapter.getValue() - }, function (searchResult, matchResult) { - if (!self._stop) { - var args = [].slice.call(arguments); - if (args.length > 0) { - args.push(keyword); + _calculateChildrenToRender: function () { + var self = this, o = this.options; + var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()); + var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()); + var left = Math.max(0, scrollLeft - o.horizontalOverscanSize); + var top = Math.max(0, scrollTop - o.verticalOverscanSize); + var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize); + var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize); + var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); + var renderedCells = [], renderedKeys = []; + for (var i = 0, len = childrenToDisplay.length; i < len; i++) { + var datum = childrenToDisplay[i]; + var index = BI.deepIndexOf(this.renderedKeys, datum.index); + if (index > -1) { + if (datum.width !== this.renderedCells[index]._width) { + this.renderedCells[index]._width = datum.width; + this.renderedCells[index].el.setWidth(datum.width); } - BI.Maskers.show(self.getName()); - self.popupView.populate.apply(self.popupView, args); - o.isAutoSync && self.popupView.setValue(o.adapter.getValue()); - self.popupView.loaded && self.popupView.loaded(); - self.fireEvent(BI.Searcher.EVENT_SEARCHING); + if (datum.height !== this.renderedCells[index]._height) { + this.renderedCells[index]._height = datum.height; + this.renderedCells[index].el.setHeight(datum.height); + } + if (this.renderedCells[index].left !== datum.x) { + this.renderedCells[index].el.element.css("left", datum.x + "px"); + } + if (this.renderedCells[index].top !== datum.y) { + this.renderedCells[index].el.element.css("top", datum.y + "px"); + } + renderedCells.push(this.renderedCells[index]); + } else { + var child = BI.createWidget(BI.extend({ + type: "bi.label", + width: datum.width, + height: datum.height + }, o.items[datum.index], { + cls: (o.items[datum.index].cls || "") + " container-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : ""), + _left: datum.x, + _top: datum.y + })); + renderedCells.push({ + el: child, + left: datum.x, + top: datum.y, + _width: datum.width, + _height: datum.height + }); + } + renderedKeys.push(datum.index); + } + //已存在的, 需要添加的和需要删除的 + var existSet = {}, addSet = {}, deleteArray = []; + BI.each(renderedKeys, function (i, key) { + if (BI.deepContains(self.renderedKeys, key)) { + existSet[i] = key; + } else { + addSet[i] = key; + } + }); + BI.each(this.renderedKeys, function (i, key) { + if (BI.deepContains(existSet, key)) { + return; + } + if (BI.deepContains(addSet, key)) { + return; } + deleteArray.push(i); + }); + BI.each(deleteArray, function (i, index) { + self.renderedCells[index].el.destroy(); + }); + var addedItems = []; + BI.each(addSet, function (index) { + addedItems.push(renderedCells[index]) + }); + BI.createWidget({ + type: "bi.absolute", + element: this.container, + items: addedItems }); + this.renderedCells = renderedCells; + this.renderedKeys = renderedKeys; }, - setAdapter: function (adapter) { - this.options.adapter = adapter; - BI.Maskers.remove(this.getName()); + _getMaxScrollLeft: function () { + return Math.max(0, this._width - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); }, - doSearch: function () { - if (this.isSearching()) { - this._search(); - } + _getMaxScrollTop: function () { + return Math.max(0, this._height - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); }, - stopSearch: function () { - this._stopSearch();//先停止搜索,然后再去设置editor为空 - //important:停止搜索必须退出编辑状态,这里必须加上try(input框不显示时blur会抛异常) - try { - this.editor.blur(); - } catch (e) { - if (!this.editor.blur) { - throw new Error("editor没有实现blur方法"); - } - } finally { - this.editor.setValue(""); - } - }, + _populate: function () { + var o = this.options; + if (o.items.length > 0) { + this.container.setWidth(this._width); + this.container.setHeight(this._height); - isSearching: function () { - return this._isSearching; + this._calculateChildrenToRender(); + this.element.scrollTop(o.scrollTop); + this.element.scrollLeft(o.scrollLeft); + } }, - isViewVisible: function () { - return this.editor.isEnabled() && BI.Maskers.isVisible(this.getName()); + setScrollLeft: function (scrollLeft) { + if (this.options.scrollLeft === scrollLeft) { + return; + } + this._scrollLock = true; + this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); + this._debounceRelease(); + this._calculateChildrenToRender(); + this.element.scrollLeft(this.options.scrollLeft); }, - getView: function () { - return this.popupView; + setScrollTop: function (scrollTop) { + if (this.options.scrollTop === scrollTop) { + return; + } + this._scrollLock = true; + this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); + this._debounceRelease(); + this._calculateChildrenToRender(); + this.element.scrollTop(this.options.scrollTop); }, - hasMatched: function () { - this._assertPopupView(); - return this.popupView.hasMatched(); + setOverflowX: function (b) { + var self = this; + if (this.options.overflowX !== !!b) { + this.options.overflowX = !!b; + BI.nextTick(function () { + self.element.css({overflowX: !!b ? "auto" : "hidden"}); + }); + } }, - adjustHeight: function () { - if (BI.Maskers.has(this.getName()) && BI.Maskers.get(this.getName()).isVisible()) { - BI.Maskers.show(this.getName()); + setOverflowY: function (b) { + var self = this; + if (this.options.overflowY !== !!b) { + this.options.overflowY = !!b; + BI.nextTick(function () { + self.element.css({overflowY: !!b ? "auto" : "hidden"}); + }); } }, - adjustView: function () { - this.isViewVisible() && BI.Maskers.show(this.getName()); + getScrollLeft: function () { + return this.options.scrollLeft; }, - setValue: function (v) { - this._assertPopupView(); - this.popupView && this.popupView.setValue(v); + getScrollTop: function () { + return this.options.scrollTop; }, - getKeyword: function () { - return this.editor.getValue(); + getMaxScrollLeft: function () { + return this._getMaxScrollLeft(); }, - getValue: function () { - var o = this.options; - if (o.isAutoSync) { - return o.adapter.getValue(); - } - if (this.isSearching()) { - return this.popupView.getValue(); - } else { - return o.adapter.getValue(); - } + getMaxScrollTop: function () { + return this._getMaxScrollTop(); }, - populate: function (result, searchResult, keyword) { - var o = this.options; - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - if (o.isAutoSync) { - this.popupView.setValue(o.adapter.getValue()); - } + restore: function () { + BI.each(this.renderedCells, function (i, cell) { + cell.el.destroy(); + }); + this.renderedCells = []; + this.renderedKeys = []; + this._scrollLock = false; }, - empty: function () { - this.popupView && this.popupView.empty(); - }, - - destroyed: function () { - this.popupView && this.popupView.destroy(); - BI.Maskers.remove(this.getName()); + populate: function (items) { + if (items && items !== this.options.items) { + this.options.items = items; + this._calculateSizeAndPositionData(); + } + this._populate(); } }); -BI.Searcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Searcher.EVENT_START = "EVENT_START"; -BI.Searcher.EVENT_STOP = "EVENT_STOP"; -BI.Searcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Searcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.Searcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - -$.shortcut("bi.searcher", BI.Searcher);/** - * - * 切换显示或隐藏面板 - * - * Created by GUY on 2015/11/2. - * @class BI.Switcher +BI.Collection.EVENT_SCROLL = "EVENT_SCROLL"; +$.shortcut('bi.collection_view', BI.Collection);/** + * @class BI.Combo * @extends BI.Widget */ -BI.Switcher = BI.inherit(BI.Widget, { +BI.Combo = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.Switcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-switcher", - direction: BI.Direction.Top, + var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-combo", trigger: "click", toggle: true, + direction: "bottom", //top||bottom||left||right||top,left||top,right||bottom,left||bottom,right + isDefaultInit: false, + isNeedAdjustHeight: true,//是否需要高度调整 + isNeedAdjustWidth: true, + stopEvent: false, + stopPropagation: false, + adjustLength: 0,//调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + hideChecker: BI.emptyFn, + offsetStyle: "left", //left,right,center el: {}, popup: {}, - adapter: null, - masker: {}, - switcherClass: "bi-switcher-popup", - hoverClass: "bi-switcher-hover" + comboClass: "bi-combo-popup", + hoverClass: "bi-combo-hover" }) }, _init: function () { - BI.Switcher.superclass._init.apply(this, arguments); + BI.Combo.superclass._init.apply(this, arguments); var self = this, o = this.options; - this._initSwitcher(); + this._initCombo(); this._initPullDownAction(); - this.switcher.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (self.isEnabled() && this.isEnabled()) { if (type === BI.Events.EXPAND) { self._popupView(); @@ -23452,35 +23201,43 @@ BI.Switcher = BI.inherit(BI.Widget, { if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); } + if (type === BI.Events.CLICK) { - self.fireEvent(BI.Switcher.EVENT_TRIGGER_CHANGE, value, obj); + self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); } } }); - this.element.hover(function () { - if (self.isEnabled() && self.switcher.isEnabled()) { + self.element.on("mouseenter." + self.getName(), function (e) { + if (self.isEnabled() && self.combo.isEnabled()) { self.element.addClass(o.hoverClass); } - }, function () { - if (self.isEnabled() && self.switcher.isEnabled()) { + }); + self.element.on("mouseleave." + self.getName(), function (e) { + if (self.isEnabled() && self.combo.isEnabled()) { self.element.removeClass(o.hoverClass); } }); + BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [ - {el: this.switcher} + {el: this.combo} ] }); o.isDefaultInit && (this._assertPopupView()); + BI.Resizers.add(this.getName(), BI.bind(function () { + if (this.isViewVisible()) { + this._hideView(); + } + }, this)); }, _toggle: function () { - this._assertPopupView(); - if (this.isExpanded()) { + this._assertPopupViewRender(); + if (this.popupView.isVisible()) { this._hideView(); } else { if (this.isEnabled()) { @@ -23492,11504 +23249,21666 @@ BI.Switcher = BI.inherit(BI.Widget, { _initPullDownAction: function () { var self = this, o = this.options; var evs = this.options.trigger.split(","); - BI.each(evs, function (i, e) { - switch (e) { + var st = function (e) { + if (o.stopEvent) { + e.stopEvent(); + } + if (o.stopPropagation) { + e.stopPropagation(); + } + }; + BI.each(evs, function (i, ev) { + switch (ev) { case "hover": - self.element[e](function (e) { - if (self.isEnabled() && self.switcher.isEnabled()) { + self.element.on("mouseenter." + self.getName(), function (e) { + if (self.isEnabled() && self.combo.isEnabled()) { self._popupView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.switcher); - self.fireEvent(BI.Switcher.EVENT_EXPAND); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Combo.EVENT_EXPAND); } - }, function () { - if (self.isEnabled() && self.switcher.isEnabled() && o.toggle) { + }); + self.element.on("mouseleave." + self.getName(), function (e) { + if (self.isEnabled() && self.combo.isEnabled() && o.toggle === true) { self._hideView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.switcher); - self.fireEvent(BI.Switcher.EVENT_COLLAPSE); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); + self.fireEvent(BI.Combo.EVENT_COLLAPSE); } }); break; - default : - if (e) { - self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { - if (self.switcher.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.switcher.isEnabled()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isExpanded()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.switcher); - self.fireEvent(BI.Switcher.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.switcher); - self.fireEvent(BI.Switcher.EVENT_COLLAPSE); - } + case "click": + var debounce = BI.debounce(function (e) { + if (self.combo.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.combo.isEnabled()) { + o.toggle ? self._toggle() : self._popupView(); + if (self.isViewVisible()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Combo.EVENT_EXPAND); + } else { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); + self.fireEvent(BI.Combo.EVENT_COLLAPSE); } } - }, BI.EVENT_RESPONSE_TIME, true)); - } + } + }, BI.EVENT_RESPONSE_TIME, true); + self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function(e){ + debounce(e); + st(e); + }); break; } - }) + }); }, - _initSwitcher: function () { - this.switcher = BI.createWidget(this.options.el); + _initCombo: function () { + this.combo = BI.createWidget(this.options.el); }, _assertPopupView: function () { - var self = this, o = this.options; - if (!this._created) { - this.popupView = BI.createWidget(o.popup, { - type: "bi.button_group", - element: o.adapter && BI.Maskers.create(this.getName(), o.adapter, BI.extend({container: this}, o.masker)), - cls: "switcher-popup", - layouts: [{ - type: "bi.vertical", - hgap: 0, - vgap: 0 - }] + var self = this; + if (this.popupView == null) { + this.popupView = BI.createWidget(this.options.popup, { + type: "bi.popup_view" }); this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { - self.fireEvent(BI.Switcher.EVENT_CHANGE, value, obj); + self.combo.setValue(self.getValue()); + self.fireEvent(BI.Combo.EVENT_CHANGE, value, obj); } + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); - if (o.direction !== BI.Direction.Custom && !o.adapter) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - {el: this.popupView} - ] - }); - } - this._created = true; + this.popupView.setVisible(false); BI.nextTick(function () { - self.fireEvent(BI.Switcher.EVENT_AFTER_INIT); + self.fireEvent(BI.Combo.EVENT_AFTER_INIT); }); } }, - _hideView: function () { - this.fireEvent(BI.Switcher.EVENT_BEFORE_HIDEVIEW); - var self = this, o = this.options; - o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); - BI.nextTick(function () { - o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); - self.element.removeClass(o.switcherClass); - self.fireEvent(BI.Switcher.EVENT_AFTER_HIDEVIEW); - }); - }, - - _popupView: function () { - var self = this, o = this.options; + _assertPopupViewRender: function () { this._assertPopupView(); - this.fireEvent(BI.Switcher.EVENT_BEFORE_POPUPVIEW); - o.adapter ? BI.Maskers.show(this.getName()) : self.popupView.setVisible(true); - BI.nextTick(function (name) { - o.adapter ? BI.Maskers.show(name) : self.popupView.setVisible(true); - self.element.addClass(o.switcherClass); - self.fireEvent(BI.Switcher.EVENT_AFTER_POPUPVIEW); - }, this.getName()); + if (!this._rendered) { + BI.createWidget({ + type: "bi.vertical", + scrolly: false, + element: this, + items: [ + {el: this.popupView} + ] + }); + this._rendered = true; + } }, - populate: function (items) { - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - this.switcher.populate.apply(this.switcher, arguments); + _hideIf: function (e) { + if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { + return; + } + if (this.element.find(e.target).length > 0) { + return; + } + var isHide = this.options.hideChecker.apply(this, [e]); + if (isHide === false) { + return; + } + this._hideView(); }, - setEnable: function (arg) { - BI.Switcher.superclass.setEnable.apply(this, arguments); - this.switcher && this.switcher.setEnable(arg); - this.popupView && this.popupView.setEnable(arg); - !arg && this._hideView(); - }, + _hideView: function () { + this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); + this.popupView && this.popupView.invisible(); + this.element.removeClass(this.options.comboClass); - setValue: function (v) { - this._assertPopupView(); - this.switcher.setValue(v); - this.popupView && this.popupView.setValue(v); + $(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); + this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW); }, - getValue: function () { - this._assertPopupView(); - return this.popupView ? this.popupView.getValue() : []; - }, + _popupView: function () { + this._assertPopupViewRender(); + this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); - isViewVisible: function () { - return this.isEnabled() && this.switcher.isEnabled() && - (this.options.adapter ? BI.Maskers.isVisible(this.getName()) : (this.popupView && this.popupView.isVisible())); - }, + this.popupView.visible(); + this.adjustWidth(); + this.adjustHeight(); - isExpanded: function () { - return this.isViewVisible(); + this.element.addClass(this.options.comboClass); + $(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); + this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); }, - showView: function () { - if (this.isEnabled() && this.switcher.isEnabled()) { - this._popupView(); + adjustWidth: function () { + var o = this.options; + if (!this.popupView) { + return; + } + if (o.isNeedAdjustWidth === true) { + this.resetListWidth(""); + var width = this.popupView.element.outerWidth(); + var maxW = this.element.outerWidth() || o.width; + if (width > maxW + 80) { + maxW = maxW + 80; + } else if (width > maxW) { + maxW = width; + } + this.resetListWidth(maxW < 100 ? 100 : maxW); } }, - hideView: function () { - this._hideView(); - }, - - getView: function () { - return this.popupView; - }, + adjustHeight: function () { + var o = this.options, p = {}; + if (!this.popupView) { + return; + } + var isVisible = this.popupView.isVisible(); + this.popupView.visible(); + switch (o.direction) { + case "bottom": + case "bottom,right": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'right', 'left'], o.offsetStyle); + break; + case "top": + case "top,right": + p = $.getComboPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'right', 'left'], o.offsetStyle); + break; + case "left": + case "left,bottom": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'bottom', 'top'], o.offsetStyle); + break; + case "right": + case "right,bottom": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'bottom', 'top'], o.offsetStyle); + break; + case "top,left": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'left', 'right'], o.offsetStyle); + break; + case "bottom,left": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'left', 'right'], o.offsetStyle); + break; + case "left,top": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'top', 'bottom'], o.offsetStyle); + break; + case "right,top": + p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'top', 'bottom'], o.offsetStyle); + break; + case "top,custom": + case "custom,top": + p = $.getTopAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); + break; + case "custom,bottom": + case "bottom,custom": + p = $.getBottomAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); + break; + case "left,custom": + case "custom,left": + p = $.getLeftAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); + delete p.top; + delete p.adaptHeight; + break; + case "custom,right": + case "right,custom": + p = $.getRightAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); + delete p.top; + delete p.adaptHeight; + break; + } - adjustView: function () { - this.isViewVisible() && BI.Maskers.show(this.getName()); + if ("adaptHeight" in p) { + this.resetListHeight(p['adaptHeight']); + } + if ("left" in p) { + this.popupView.element.css({ + left: p.left + }); + } + if ("top" in p) { + this.popupView.element.css({ + top: p.top + }); + } + this.position = p; + this.popupView.setVisible(isVisible); }, - doBehavior: function () { + resetListHeight: function (h) { this._assertPopupView(); - this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); + this.popupView.resetHeight && this.popupView.resetHeight(h); }, - getAllLeaves: function () { - return this.popupView && this.popupView.getAllLeaves(); + resetListWidth: function (w) { + this._assertPopupView(); + this.popupView.resetWidth && this.popupView.resetWidth(w); }, - getNodeById: function (id) { - if (this.switcher.attr("id") === id) { - return this.switcher; - } - return this.popupView && this.popupView.getNodeById(id); + populate: function (items) { + this._assertPopupView(); + this.popupView.populate.apply(this.popupView, arguments); + this.combo.populate.apply(this.combo, arguments); }, - getNodeByValue: function (value) { - if (this.switcher.getValue() === value) { - return this.switcher; - } - return this.popupView && this.popupView.getNodeByValue(value); + setEnable: function (arg) { + BI.Combo.superclass.setEnable.apply(this, arguments); + this.combo && this.combo.setEnable(arg); + this.popupView && this.popupView.setEnable(arg); + !arg && this.isViewVisible() && this._hideView(); }, - empty: function () { - this.popupView && this.popupView.empty(); + setValue: function (v) { + this._assertPopupView(); + this.combo.setValue(v); + this.popupView && this.popupView.setValue(v); }, - destroyed: function () { - this.popupView && this.popupView.destroy(); - } -}); -BI.Switcher.EVENT_EXPAND = "EVENT_EXPAND"; -BI.Switcher.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.Switcher.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.Switcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Switcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.Switcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.Switcher.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.Switcher.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.Switcher.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - -$.shortcut("bi.switcher", BI.Switcher);/** - * Created by GUY on 2015/6/26. - */ - -BI.Tab = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Tab.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tab", - direction: "top",//top, bottom, left, right, custom - logic: { - dynamic: false - }, - defaultShowIndex: 0, - tab: false, - cardCreator: function (v) { - return BI.createWidget(); - } - }) + getValue: function () { + this._assertPopupView(); + return this.popupView && this.popupView.getValue(); }, - _init: function () { - BI.Tab.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isObject(o.tab)) { - this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); - this.tab.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }) - } - this.cardMap = {}; - this.layout = BI.createWidget({ - type: "bi.card" - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) - })))); - - var listener = new BI.ShowListener({ - eventObj: this.tab, - cardLayout: this.layout, - cardCreator: function (v) { - var card = o.cardCreator.apply(self, arguments); - self.cardMap[v] = card; - return card; - }, - afterCardShow: function (v) { - self.curr = v; - } - }); - listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { - self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); - }); - if (o.defaultShowIndex !== false) { - this.setSelect(o.defaultShowIndex); - } + isViewVisible: function () { + return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); }, - _assertCard: function (v) { - if (!this.layout.isCardExisted(v)) { - var card = this.options.cardCreator(v); - this.cardMap[v] = card; - this.layout.addCardByName(v, card); + showView: function () { + if (this.isEnabled() && this.combo.isEnabled()) { + this._popupView(); } }, - setSelect: function (v) { - this.tab && this.tab.setValue(v); - this._assertCard(v); - this.layout.showCardByName(v); - if (this.curr !== v) { - this.curr = v; - } + hideView: function () { + this._hideView(); }, - getSelect: function () { - return this.curr; + getView: function () { + return this.popupView; }, - getSelectedTab: function () { - return this.layout.getShowingCard(); + getPopupPosition: function () { + return this.position; }, - getTab: function (v) { - this._assertCard(v); - return this.layout.getCardByName(v); + doBehavior: function () { + this._assertPopupView(); + this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); }, - setValue: function (v) { - var card = this.layout.getShowingCard(); - if (card) { - card.setValue(v); - } + toggle: function () { + this._toggle(); }, - getValue: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.getValue(); - } - }, + destroy: function () { + $(document).unbind("mousedown." + this.getName()) + .unbind("mousewheel." + this.getName()) + .unbind("mouseenter." + this.getName()) + .unbind("mousemove." + this.getName()) + .unbind("mouseleave." + this.getName()); + BI.Resizers.remove(this.getName()); + BI.Combo.superclass.destroy.apply(this, arguments); + } +}); +BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; +BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; +BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; +BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - populate: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.populate && card.populate.apply(card, arguments); - } - }, - - empty: function () { - this.layout.deleteAllCard(); - this.cardMap = {}; - }, - destroyed: function () { - this.layout.deleteAllCard(); - this.cardMap = {}; - } -}); -BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; +BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; +BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; -$.shortcut("bi.tab", BI.Tab);/** - * Created by GUY on 2015/8/10. - * @class BI.ButtonTree - * @extends BI.ButtonGroup +$.shortcut("bi.combo", BI.Combo);/** + * + * 某个可以展开的节点 + * + * Created by GUY on 2015/9/10. + * @class BI.Expander + * @extends BI.Widget */ - -BI.ButtonTree = BI.inherit(BI.ButtonGroup, { +BI.Expander = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.ButtonTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-tree" + return BI.extend(BI.Expander.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-expander", + trigger: "click", + toggle: true, + //direction: "bottom", //top,bottom四个方向 + isDefaultInit: false, //是否默认初始化子节点 + el: {}, + popup: {}, + expanderClass: "bi-expander-popup", + hoverClass: "bi-expander-hover" }) }, _init: function () { - BI.ButtonTree.superclass._init.apply(this, arguments); - }, - - setNotSelectedValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - return; - } - if (BI.deepContains(v, item.getValue())) { - item.setSelected(false); - } else { - item.setSelected(true); + BI.Expander.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this._expanded = !!o.el.open; + this._initExpander(); + this._initPullDownAction(); + this.expander.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (type === BI.Events.EXPAND) { + self._popupView(); } - }); - }, - - setEnabledValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.isFunction(item.setEnabledValue)) { - item.setEnabledValue(v); - return; + if (type === BI.Events.COLLAPSE) { + self._hideView(); } - if (BI.deepContains(v, item.getValue())) { - item.setEnable(true); - } else { - item.setEnable(false); + if (self.isEnabled() && this.isEnabled()) { + if (type === BI.Events.EXPAND) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.fireEvent(BI.Expander.EVENT_EXPAND); + } + if(type === BI.Events.COLLAPSE) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.fireEvent(BI.Expander.EVENT_COLLAPSE); + } + if (type === BI.Events.CLICK) { + self.fireEvent(BI.Expander.EVENT_TRIGGER_CHANGE, value, obj); + } } }); - }, - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - return; + this.element.hover(function () { + if (self.isEnabled() && self.expander.isEnabled()) { + self.element.addClass(o.hoverClass); } - if (BI.deepContains(v, item.getValue())) { - item.setSelected(true); - } else { - item.setSelected(false); + }, function () { + if (self.isEnabled() && self.expander.isEnabled()) { + self.element.removeClass(o.hoverClass); } }); - }, - - getNotSelectedValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - v = BI.concat(v, item.getNotSelectedValue()); - return; - } - if (item.isEnabled() && item.isSelected && !item.isSelected()) { - v.push(item.getValue()); - } + BI.createWidget({ + type: "bi.vertical", + scrolly: false, + element: this, + items: [ + {el: this.expander} + ] }); - return v; + o.isDefaultInit && this._assertPopupView(); + if (this.expander.isOpened() === true) { + this._popupView(); + } }, - getValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - v = BI.concat(v, item.getValue()); - return; - } - if (item.isEnabled() && item.isSelected && item.isSelected()) { - v.push(item.getValue()); + _toggle: function () { + this._assertPopupViewRender(); + if (this.popupView.isVisible()) { + this._hideView(); + } else { + if (this.isEnabled()) { + this._popupView(); } - }); - return v; + } }, - getSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - btns = btns.concat(item.getSelectedButtons()); - return; - } - if (item.isSelected && item.isSelected()) { - btns.push(item); + _initPullDownAction: function () { + var self = this, o = this.options; + var evs = this.options.trigger.split(","); + BI.each(evs, function (i, e) { + switch (e) { + case "hover": + self.element[e](function (e) { + if (self.isEnabled() && self.expander.isEnabled()) { + self._popupView(); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.expander); + self.fireEvent(BI.Expander.EVENT_EXPAND); + } + }, function () { + if (self.isEnabled() && self.expander.isEnabled() && o.toggle) { + self._hideView(); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.expander); + self.fireEvent(BI.Expander.EVENT_COLLAPSE); + } + }); + break; + default : + if (e) { + self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { + if (self.expander.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.expander.isEnabled()) { + o.toggle ? self._toggle() : self._popupView(); + if (self.isExpanded()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); + self.fireEvent(BI.Expander.EVENT_EXPAND); + } else { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.expander); + self.fireEvent(BI.Expander.EVENT_COLLAPSE); + } + } + } + }, BI.EVENT_RESPONSE_TIME, true)); + } + break; } - }); - return btns; + }) }, - getNotSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - btns = btns.concat(item.getNotSelectedButtons()); - return; - } - if (item.isSelected && !item.isSelected()) { - btns.push(item); - } - }); - return btns; + _initExpander: function () { + this.expander = BI.createWidget(this.options.el); }, - //获取所有的叶子节点 - getAllLeaves: function () { - var leaves = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - leaves = leaves.concat(item.getAllLeaves()); - return; - } - if (item.isEnabled()) { - leaves.push(item); - } - }); - return leaves; + _assertPopupView: function () { + var self = this; + if (this.popupView == null) { + this.popupView = BI.createWidget(this.options.popup, { + type: "bi.button_group", + cls: "expander-popup", + layouts: [{ + type: "bi.vertical", + hgap: 0, + vgap: 0 + }] + }); + this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + //self.setValue(self.getValue()); + self.fireEvent(BI.Expander.EVENT_CHANGE, value, obj); + } + }); + this.popupView.setVisible(this.isExpanded()); + BI.nextTick(function () { + self.fireEvent(BI.Expander.EVENT_AFTER_INIT); + }); + } }, - getIndexByValue: function (value) { - var index = -1; - BI.any(this.buttons, function (i, item) { - var vs = item.getValue(); - if (item.isEnabled() && (vs === value || BI.contains(vs, value))) { - index = i; - return true; - } - }); - return index; - }, - - getNodeById: function (id) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled()) { - if (item.attr("id") === id) { - node = item; - return true; - } else if (BI.isFunction(item.getNodeById)) { - if (node = item.getNodeById(id)) { - return true; - } - } - } - }); - return node; + _assertPopupViewRender: function () { + this._assertPopupView(); + if (!this._rendered) { + BI.createWidget({ + type: "bi.vertical", + scrolly: false, + element: this, + items: [ + {el: this.popupView} + ] + }); + this._rendered = true; + } }, - getNodeByValue: function (value) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled()) { - if (item.getValue() === value) { - node = item; - return true; - } else if (BI.isFunction(item.getNodeByValue)) { - if (node = item.getNodeByValue(value)) { - return true; - } - } - } - }); - return node; - } -}); -BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; - -$.shortcut("bi.button_tree", BI.ButtonTree); + _hideView: function () { + this.fireEvent(BI.Expander.EVENT_BEFORE_HIDEVIEW); + this._expanded = false; + this.expander.setOpened(false); + this.popupView && this.popupView.invisible(); + this.element.removeClass(this.options.expanderClass); -/** - * value作为key值缓存button, 不支持顺序读写 - * 适合用于频繁增删的一组button - * Created by GUY on 2015/8/10. - * @class BI.ButtonMap - * @extends BI.ButtonTree - */ + this.fireEvent(BI.Expander.EVENT_AFTER_HIDEVIEW); + }, -BI.ButtonMap = BI.inherit(BI.ButtonTree, { - _defaultConfig: function () { - return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-map" - }) + _popupView: function () { + this._assertPopupViewRender(); + this.fireEvent(BI.Expander.EVENT_BEFORE_POPUPVIEW); + this._expanded = true; + this.expander.setOpened(true); + this.popupView.visible(); + this.element.addClass(this.options.expanderClass); + this.fireEvent(BI.Expander.EVENT_AFTER_POPUPVIEW); }, - _init: function () { - BI.ButtonMap.superclass._init.apply(this, arguments); + populate: function (items) { + //this._assertPopupView(); + this.popupView && this.popupView.populate.apply(this.popupView, arguments); + this.expander.populate.apply(this.expander, arguments); }, - _createBtns: function (items) { - var self = this, o = this.options; - var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); - var keys = BI.map(items, function (i, item) { - item = BI.stripEL(item); - if (!(item.id || item.value)) { - throw new Error("item必须包含id或value属性"); - } - return item.id || item.value; - }); - return BI.object(keys, buttons); + setEnable: function (arg) { + BI.Expander.superclass.setEnable.apply(this, arguments); + this.expander && this.expander.setEnable(arg); + this.popupView && this.popupView.setEnable(arg); + !arg && this._hideView(); }, setValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); + //this._assertPopupView(); + this.expander.setValue(v); + this.popupView && this.popupView.setValue(v); }, - setNotSelectedValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); + getValue: function () { + //this._assertPopupView(); + return this.popupView ? this.popupView.getValue() : []; }, - populate: function (items) { - var self = this; - var args = [].slice.call(arguments); - var linkHashMap = new BI.LinkHashMap(); - var val = function (item) { - return item.id || item.value; - }; - if (!this.buttons) { - this.buttons = {}; - } - //所有已存在的和新添加的 - var willCreated = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - if (self.buttons[val(item)]) { - var ob = self.buttons[val(item)]; - args[0] = item.items; - args[2] = item; - ob.populate && ob.populate.apply(ob, args); - } else { - willCreated.push(item); - } - }); - //创建新元素 - args[0] = willCreated; - var newBtns = this._btnsCreator.apply(this, args); + isViewVisible: function () { + return this.isEnabled() && this.expander.isEnabled() && !!this.popupView && this.popupView.isVisible(); + }, - //整理 - var array = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - var button = self.buttons[val(item)] || newBtns[val(item)]; - linkHashMap.add(val(item), button); - array.push(button); - }); - this.buttons = linkHashMap.map; + isExpanded: function () { + return this._expanded; + }, - BI.DOM.hang(this.buttons); - this.empty(); + showView: function () { + if (this.isEnabled() && this.expander.isEnabled()) { + this._popupView(); + } + }, - var packages = this._packageItems(items, this._packageBtns(array)); - BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); + hideView: function () { + this._hideView(); }, - getIndexByValue: function (value) { - throw new Error("不能使用getIndexByValue方法"); - } -}); -BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; + getView: function () { + return this.popupView; + }, -$.shortcut("bi.button_map", BI.ButtonMap);/** - * 表示当前对象 - * - * Created by GUY on 2015/9/7. - * @class BI.EL - * @extends BI.Widget - */ -BI.EL = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.EL.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-el", - el: {}, - layout: {} - }); + doBehavior: function () { + //this._assertPopupView(); + this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); }, - _init: function () { - BI.EL.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.ele = BI.createWidget(o.el); - BI.createWidget(o.layout, { - type: "bi.adaptive", - element: this, - items: [this.ele] - }); - this.ele.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }) + + getAllLeaves: function () { + return this.popupView && this.popupView.getAllLeaves(); }, - setValue: function (v) { - this.ele.setValue(v); + getNodeById: function (id) { + if (this.expander.options.id === id) { + return this.expander; + } + return this.popupView && this.popupView.getNodeById(id); }, - getValue: function () { - return this.ele.getValue(); + getNodeByValue: function (value) { + if (this.expander.getValue() === value) { + return this.expander; + } + return this.popupView && this.popupView.getNodeByValue(value); }, - populate: function () { - this.ele.populate.apply(this, arguments); + destroy: function () { + BI.Expander.superclass.destroy.apply(this, arguments); } }); -$.shortcut('bi.el', BI.EL);/** - * 选色控件 - * - * Created by GUY on 2015/11/16. - * @class BI.Farbtastic - * @extends BI.Widget - */ -BI.Farbtastic = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.Farbtastic.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-farbtastic", - width: 195, - height: 195 +BI.Expander.EVENT_EXPAND = "EVENT_EXPAND"; +BI.Expander.EVENT_COLLAPSE = "EVENT_COLLAPSE"; +BI.Expander.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; +BI.Expander.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Expander.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + +BI.Expander.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.Expander.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; +BI.Expander.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; +BI.Expander.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + +$.shortcut("bi.expander", BI.Expander);/** + * Created by GUY on 2015/8/10. + */ + +BI.ComboGroup = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.ComboGroup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-combo-group", + + //以下这些属性对每一个combo都是公用的 + trigger: "click,hover", + direction: "right", + adjustLength: 0, + isDefaultInit: false, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + + el: {type: "bi.text_button", text: "", value: ""}, + children: [], + + popup: { + el: { + type: "bi.button_tree", + chooseType: 0, + layouts: [{ + type: "bi.vertical" + }] + } + } }) }, _init: function () { - BI.Farbtastic.superclass._init.apply(this, arguments); - var self = this; + BI.ComboGroup.superclass._init.apply(this, arguments); + this.populate(this.options.el); + }, - this.farbtastic = $.farbtastic(this.element, function (v) { - self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); - }); + populate: function (item) { + var self = this, o = this.options; + var children = o.children; + if (BI.isEmpty(children)) { + throw new Error("ComboGroup构造错误"); + } + BI.each(children, function (i, ch) { + var son = BI.formatEL(ch).el.children; + ch = BI.formatEL(ch).el; + if (!BI.isEmpty(son)) { + ch.el = BI.clone(ch); + ch.children = son; + ch.type = "bi.combo_group"; + ch.action = o.action; + ch.height = o.height; + ch.direction = o.direction; + ch.isDefaultInit = o.isDefaultInit; + ch.isNeedAdjustHeight = o.isNeedAdjustHeight; + ch.isNeedAdjustWidth = o.isNeedAdjustWidth; + ch.adjustLength = o.adjustLength; + ch.popup = o.popup; + } + }) + this.combo = BI.createWidget({ + type: "bi.combo", + element: this, + height: o.height, + trigger: o.trigger, + direction: o.direction, + isDefaultInit: o.isDefaultInit, + isNeedAdjustWidth: o.isNeedAdjustWidth, + isNeedAdjustHeight: o.isNeedAdjustHeight, + adjustLength: o.adjustLength, + el: item, + popup: BI.extend({}, o.popup, { + el: BI.extend({ + items: children + }, o.popup.el) + }) + }) + this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.ComboGroup.EVENT_CHANGE, obj); + } + }) }, - setValue: function (color) { - this.farbtastic.setColor(color); + setEnable: function (b) { + BI.ComboGroup.superclass.setEnable.apply(this, arguments); + this.combo && this.combo.setEnable(b); }, getValue: function () { - return this.farbtastic.color; + return this.combo.getValue(); + }, + + setValue: function (v) { + this.combo.setValue(v); } }); -BI.Farbtastic.EVENT_CHANGE = "Farbtastic.EVENT_CHANGE"; -$.shortcut("bi.farbtastic", BI.Farbtastic);; -(function ($) { - /** - * 公式编辑控件 - * @class BI.FormulaEditor - * @extends BI.Widget - */ - BI.FormulaEditor = BI.inherit(BI.Single, { - _defaultConfig: function () { - return $.extend(BI.FormulaEditor.superclass._defaultConfig.apply(), { - baseCls: 'bi-formula-editor', - watermark: '', - value: '', - fieldTextValueMap: {} - }); - }, - _init: function () { - BI.FormulaEditor.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.editor = CodeMirror(this.element[0], { - textWrapping: true, - lineWrapping: true, - lineNumbers: false, - mode: 'formula' - }); - this.editor.on("change", function (cm, change) { - self._checkWaterMark(); - CodeMirror.showHint(cm, CodeMirror.formulaHint, {completeSingle: false}); - BI.nextTick(function () { - self.fireEvent(BI.FormulaEditor.EVENT_CHANGE) - }); - }); - - this.editor.on("focus", function () { - self._checkWaterMark(); - self.fireEvent(BI.FormulaEditor.EVENT_FOCUS); - }); +BI.ComboGroup.EVENT_CHANGE = "EVENT_CHANGE"; - this.editor.on("blur", function () { - self.fireEvent(BI.FormulaEditor.EVENT_BLUR); - }); +$.shortcut("bi.combo_group", BI.ComboGroup);/** + * 加载控件 + * + * Created by GUY on 2015/8/31. + * @class BI.Loader + * @extends BI.Widget + */ +BI.Loader = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.Loader.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-loader", + direction: "top", + isDefaultInit: true,//是否默认初始化数据 + logic: { + dynamic: true, + scrolly: true + }, - if (BI.isKey(o.value)) { - self.setValue(o.value); - } + //下面是button_group的属性 + el: { + type: "bi.button_group" + }, - if (BI.isKey(this.options.watermark)) { - var self = this; - this.watermark = BI.createWidget({ - type: "bi.label", - cls: "bi-water-mark", - text: this.options.watermark, - whiteSpace: "nowrap", - textAlign: "left" - }); - BI.createWidget({ - type: "bi.absolute", - element: self, - items: [{ - el: self.watermark, - left: 0, - top: 0 - }] - }); + items: [], + itemsCreator: BI.emptyFn, + onLoaded: BI.emptyFn, - this.watermark.element.bind( - "mousedown", function (e) { - self.insertString(""); - self.editor.focus(); - e.stopEvent(); - } - ); - this.watermark.element.bind("click", function (e) { - self.editor.focus(); - e.stopEvent(); - }); - this.watermark.element.css({ - position: "absolute", - left: 3, - right: 3, - top: 6, - bottom: 0 - }); - } - }, + //下面是分页信息 + count: false, + prev: false, + next: {}, + hasPrev: BI.emptyFn, + hasNext: BI.emptyFn + }) + }, - _checkWaterMark: function () { - var o = this.options; - if (!this.disabledWarterMark && BI.isEmptyString(this.editor.getValue()) && BI.isKey(o.watermark)) { - this.watermark && this.watermark.visible(); - } else { - this.watermark && this.watermark.invisible(); - } - }, + _prevLoad: function () { + var self = this, o = this.options; + this.prev.setLoading(); + o.itemsCreator.apply(this, [{times: --this.times}, function () { + self.prev.setLoaded(); + self.prependItems.apply(self, arguments); + }]); + }, - disableWarterMark: function () { - this.disabledWarterMark = true; - this._checkWaterMark(); - }, + _nextLoad: function () { + var self = this, o = this.options; + this.next.setLoading(); + o.itemsCreator.apply(this, [{times: ++this.times}, function () { + self.next.setLoaded(); + self.addItems.apply(self, arguments); + }]); + }, - /** - * 添加字段 - * @param field - */ - insertField: function (field) { - var from = this.editor.getCursor(); - this.editor.replaceSelection(field); - var to = this.editor.getCursor(); - this.editor.markText(from, to, {className: 'fieldName', atomic: true, startStyle : "start", endStyle:"end"}); - this.editor.replaceSelection(" "); - this.editor.focus(); - }, + _init: function () { + BI.Loader.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (o.itemsCreator === false) { + o.prev = false; + o.next = false; + } + if (o.prev !== false) { + this.prev = BI.createWidget(BI.extend({ + type: "bi.loading_bar" + }, o.prev)); + this.prev.on(BI.Controller.EVENT_CHANGE, function (type) { + if (type === BI.Events.CLICK) { + self._prevLoad(); + } + }); + } - insertFunction: function (fn) { - var from = this.editor.getCursor(); - this.editor.replaceSelection(fn); - var to = this.editor.getCursor(); - this.editor.markText(from, to, {className: "#function", atomic: true}); - this.editor.replaceSelection("() "); - to = this.editor.getCursor(); - to.ch = to.ch - 2; - this.editor.setCursor(to); - this.editor.focus(); - }, - insertOperator: function (op) { - var from = this.editor.getCursor(); - this.editor.replaceSelection(op); - var to = this.editor.getCursor(); - this.editor.markText(from, to, {className: "%operator", atomic: true}); - this.editor.replaceSelection(" "); - this.editor.focus(); - }, + this.button_group = BI.createWidget(o.el, { + type: "bi.button_group", + chooseType: 0, + items: o.items, + behaviors: {}, + layouts: [{ + type: "bi.vertical" + }] + }); + this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.Loader.EVENT_CHANGE, obj); + } + }); - setFunction: function (v) { - var from = this.editor.getCursor(); - this.editor.replaceSelection(v); - var to = this.editor.getCursor(); - this.editor.markText(from, to, {className: "#function", atomic: true}); - }, + if (o.next !== false) { + this.next = BI.createWidget(BI.extend({ + type: "bi.loading_bar" + }, o.next)); + this.next.on(BI.Controller.EVENT_CHANGE, function (type) { + if (type === BI.Events.CLICK) { + self._nextLoad(); + } + }) + } - insertString: function (str) { - this.editor.replaceSelection(str); - this.editor.focus(); - }, + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ + scrolly: true + }, o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.prev, this.button_group, this.next) + })))); - getFormulaString: function () { - return this.editor.getValue(); - }, + o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { + o.isDefaultInit && BI.isEmpty(o.items) && this.populate(); + }, this)); + if (BI.isNotEmptyArray(o.items)) { + this.populate(o.items); + } + }, - getUsedFields: function () { - var fieldMap = this.options.fieldTextValueMap; - var fields = []; - this.editor.getValue(true, function (line) { - var value = line.text; - _.forEach(line.markedSpans, function (i, ms) { - switch (i.marker.className) { - case "fieldName": - var dId = fieldMap[value.substr(i.from, i.to - i.from)]; - if (!fields.contains(dId)) { - fields.push(dId); - } + hasPrev: function () { + var o = this.options; + if (BI.isNumber(o.count)) { + return this.count < o.count; + } + return !!o.hasPrev.apply(this, [{ + times: this.times, + count: this.count + }]) + }, - } - }); - }); - return fields; - }, + hasNext: function () { + var o = this.options; + if (BI.isNumber(o.count)) { + return this.count < o.count; + } + return !!o.hasNext.apply(this, [{ + times: this.times, + count: this.count + }]) + }, - getCheckString: function () { - return this.editor.getValue(true, function (line) { - var rawText = line.text, value = line.text, num = 0; - value.text = rawText; - _.forEach(line.markedSpans, function (i, ms) { + prependItems: function (items) { + this.count += items.length; + if (this.next !== false) { + if (this.hasPrev()) { + this.options.items = this.options.items.concat(items); + this.prev.setLoaded(); + } else { + this.prev.setEnd(); + } + } + this.button_group.prependItems.apply(this.button_group, arguments); + }, - switch (i.marker.className) { - case "fieldName": - var fieldNameLength = i.to - i.from; - value = value.substr(0, i.from + num) + "$a" + value.substr(i.to + num, value.length); - num = num + 2 - fieldNameLength; - break; - } + addItems: function (items) { + this.count += items.length; + if (BI.isObject(this.next)) { + if (this.hasNext()) { + this.options.items = this.options.items.concat(items); + this.next.setLoaded(); + } else { + this.next.setEnd(); + } + } + this.button_group.addItems.apply(this.button_group, arguments); + }, - }); - return value; - }); - }, + populate: function (items) { + var self = this, o = this.options; + if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { + o.itemsCreator.apply(this, [{times: 1}, function () { + if (arguments.length === 0) { + throw new Error("arguments can not be null!!!"); + } + self.populate.apply(self, arguments); + o.onLoaded(); + }]); + return; + } + this.options.items = items; + this.times = 1; + this.count = 0; + this.count += items.length; + if (BI.isObject(this.next)) { + if (this.hasNext()) { + this.next.setLoaded(); + } else { + this.next.invisible(); + } + } + if (BI.isObject(this.prev)) { + if (this.hasPrev()) { + this.prev.setLoaded(); + } else { + this.prev.invisible(); + } + } + this.button_group.populate.apply(this.button_group, arguments); + }, - getValue: function () { - var fieldMap = this.options.fieldTextValueMap; - return this.editor.getValue("\n", function (line) { - var rawText = line.text, value = line.text, num = 0; - value.text = rawText; - _.forEach(line.markedSpans, function (i, ms) { - switch (i.marker.className) { - case "fieldName": - var fieldNameLength = i.to - i.from; - var fieldId = fieldMap[value.substr(i.from + num, fieldNameLength)]; - value = value.substr(0, i.from + num) + "$\{" + fieldMap[value.substr(i.from + num, fieldNameLength)] + "\}" + value.substr(i.to + num, value.length); - num += fieldId.length - fieldNameLength + 3; - break; - } - }); - return value; - }); - }, + setEnable: function (v) { + this.button_group.setEnable(v); + }, - setValue: function (value) { - this.editor.setValue(value); - }, + doBehavior: function () { + this.button_group.doBehavior.apply(this.button_group, arguments); + }, - setFieldTextValueMap: function (fieldTextValueMap) { - this.options.fieldTextValueMap = fieldTextValueMap; - }, + setNotSelectedValue: function () { + this.button_group.setNotSelectedValue.apply(this.button_group, arguments); + }, - refresh: function () { - var self = this; - BI.nextTick(function () { - self.editor.refresh(); - }); - } + getNotSelectedValue: function () { + return this.button_group.getNotSelectedValue(); + }, - }); - BI.FormulaEditor.EVENT_CHANGE = "EVENT_CHANGE"; - BI.FormulaEditor.EVENT_BLUR = "EVENT_BLUR"; - BI.FormulaEditor.EVENT_FOCUS = "EVENT_FOCUS"; - $.shortcut("bi.formula", BI.FormulaEditor); -})(jQuery); -/** - * z-index在1亿层级 - * 弹出提示消息框,用于模拟阻塞操作(通过回调函数实现) - * @class BI.Msg - */ -$.extend(BI, { - Msg: function () { + setValue: function () { + this.button_group.setValue.apply(this.button_group, arguments); + }, - var messageShow, $mask, $pop; + getValue: function () { + return this.button_group.getValue.apply(this.button_group, arguments); + }, - return { - toast: function (message, level, context) { - context = context || $("body"); - var toast = BI.createWidget({ - type: "bi.toast", - level: level, - text: message - }); - BI.createWidget({ - type: "bi.absolute", - element: context, - items: [{ - el: toast, - left: "50%", - top: 0 - }] - }); - if (toast.element.outerWidth() > context.outerWidth()) { - toast.setWidth(context.width()); - } - toast.element.css({"margin-left": -1 * toast.element.outerWidth() / 2}); - toast.invisible(); - toast.element.slideDown(500, function () { - BI.delay(function () { - toast.element.slideUp(500, function () { - toast.destroy(); - }) - }, 5000) - }) - }, - _show: function (hasCancel, title, message, callback) { - $mask = $('
    ').css({ - position: 'absolute', - 'zIndex': 99999998, - top: 0, - left: 0, - right: 0, - bottom: 0, - opacity: 0.1 - }).appendTo('body'); - $pop = $('
    ').css({ - position: 'absolute', - 'zIndex': 99999999, - top: 0, - left: 0, - right: 0, - bottom: 0 - }).appendTo('body'); - var close = function () { - messageShow.destroy(); - $mask.remove(); - }; - var controlItems = []; - if (hasCancel === true) { - controlItems.push({ - el: { - type: 'bi.button', - text: BI.i18nText("BI-Cancel"), - height: 30, - level: 'ignore', - handler: function () { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [false]); - } - } - } - }); - } - controlItems.push({ - el: { - type: 'bi.button', - text: BI.i18nText("BI-OK"), - height: 30, - handler: function () { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [true]); - } - } - } - }); - var conf = { - element: $pop, - type: 'bi.center_adapt', - items: [ - { - type: 'bi.border', - cls: 'bi-message-content', - items: { - 'north': { - el: { - type: 'bi.border', - cls: 'bi-message-title', - items: { - center: { - el: { - type: 'bi.label', - text: title || BI.i18nText("BI-Prompt"), - textAlign: 'left', - hgap: 20, - height: 50 - } - }, - east: { - el: { - type: 'bi.icon_button', - cls: 'bi-message-close close-font', -// height: 50, - handler: function () { - close(); - } - }, - width: 60 - } - } - }, - height: 50 - }, - 'center': { - el: { - type: "bi.text", - cls: "bi-message-text", - tgap: 60, - hgap: 20, - lineHeight: 30, - whiteSpace: "normal", - text: message - } - }, - 'south': { - el: { - type: "bi.absolute", - items: [{ - el: { - type: 'bi.right_vertical_adapt', - hgap: 5, - items: controlItems - }, - top: 0, - left: 20, - right: 20, - bottom: 0 - }] + getAllButtons: function () { + return this.button_group.getAllButtons(); + }, - }, - height: 60 - } - }, - width: 400, - height: 300 - } - ] - }; + getAllLeaves: function () { + return this.button_group.getAllLeaves(); + }, - messageShow = BI.createWidget(conf); - } - }; - }() -});/** - * Grid - * - * Created by GUY on 2016/1/11. - * @class BI.Grid - * @extends BI.Widget - */ -BI.Grid = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Grid.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-grid", - width: 400, - height: 300, - overflowX: true, - overflowY: true, - overscanColumnCount: 0, - overscanRowCount: 0, - rowHeightGetter: BI.emptyFn, - columnWidthGetter: BI.emptyFn, - estimatedColumnSize: 100, - estimatedRowSize: 30, - scrollLeft: 0, - scrollTop: 0, - items: [] - }); + getSelectedButtons: function () { + return this.button_group.getSelectedButtons(); }, - _init: function () { - BI.Grid.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.renderedCells = []; - this.renderedKeys = []; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 150); - this.container = BI.createWidget({ - type: "bi.absolute" - }); - this.element.scroll(function () { - if (self._scrollLock === true) { - return; - } - o.scrollLeft = self.element.scrollLeft(); - o.scrollTop = self.element.scrollTop(); - self._calculateChildrenToRender(); - self.fireEvent(BI.Grid.EVENT_SCROLL, { - scrollLeft: o.scrollLeft, - scrollTop: o.scrollTop - }); - }); - BI.createWidget({ - type: "bi.vertical", - element: this, - scrollable: o.overflowX === true && o.overflowY === true, - scrolly: o.overflowX === false && o.overflowY === true, - scrollx: o.overflowX === true && o.overflowY === false, - items: [this.container] - }); - if (o.items.length > 0) { - this._populate(); - } + getNotSelectedButtons: function () { + return this.button_group.getNotSelectedButtons(); }, - mounted: function () { - var o = this.options; - if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } + getIndexByValue: function (value) { + return this.button_group.getIndexByValue(value); }, - _getOverscanIndices: function (cellCount, overscanCellsCount, startIndex, stopIndex) { - return { - overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), - overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) - } + getNodeById: function (id) { + return this.button_group.getNodeById(id); }, - _calculateChildrenToRender: function () { - var self = this, o = this.options; + getNodeByValue: function (value) { + return this.button_group.getNodeByValue(value); + }, - var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()), - overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount; + empty: function () { + this.button_group.empty(); + BI.each([this.prev, this.next], function (i, ob) { + ob && ob.setVisible(false); + }); + }, - if (height > 0 && width > 0) { - var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); - var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); - - var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft); - var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); - - this._renderedColumnStartIndex = visibleColumnIndices.start; - this._renderedColumnStopIndex = visibleColumnIndices.stop; - this._renderedRowStartIndex = visibleRowIndices.start; - this._renderedRowStopIndex = visibleRowIndices.stop; - - var overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex) - - var overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex); + destroy: function () { + BI.Loader.superclass.destroy.apply(this, arguments); + } +}); +BI.Loader.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.loader", BI.Loader);/** + * Created by GUY on 2015/6/26. + */ - var columnStartIndex = overscanColumnIndices.overscanStartIndex; - var columnStopIndex = overscanColumnIndices.overscanStopIndex; - var rowStartIndex = overscanRowIndices.overscanStartIndex; - var rowStopIndex = overscanRowIndices.overscanStopIndex; +BI.Navigation = BI.inherit(BI.Widget, { + _defaultConfig: function(){ + return BI.extend(BI.Navigation.superclass._defaultConfig.apply(this,arguments), { + direction: "bottom",//top, bottom, left, right, custom + logic: { + dynamic: false + }, + defaultShowIndex: 0, + tab: { + type: "bi.button_group", + items: [], + layouts: [] + }, + cardCreator: function(v){ + return BI.createWidget(); + }, - var renderedCells = [], renderedKeys = []; + afterCardCreated: BI.emptyFn, + afterCardShow: BI.emptyFn + }) + }, - for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { - var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); + _init: function(){ + BI.Navigation.superclass._init.apply(this,arguments); + var self = this, o = this.options; + this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); + this.cardMap = {}; + this.showIndex = 0; + this.layout = BI.createWidget({ + type: "bi.card" + }); + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) + })))); - for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { - var key = [rowIndex, columnIndex]; - var columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); - var index = BI.deepIndexOf(this.renderedKeys, key); - if (index > -1) { - if (columnDatum.size !== this.renderedCells[index]._width) { - this.renderedCells[index]._width = columnDatum.size; - this.renderedCells[index].el.setWidth(columnDatum.size); - } - if (rowDatum.size !== this.renderedCells[index]._height) { - this.renderedCells[index]._height = rowDatum.size; - this.renderedCells[index].el.setHeight(rowDatum.size); - } - if (this.renderedCells[index].left !== columnDatum.offset + horizontalOffsetAdjustment) { - this.renderedCells[index].el.element.css("left", (columnDatum.offset + horizontalOffsetAdjustment) + "px"); - } - if (this.renderedCells[index].top !== rowDatum.offset + verticalOffsetAdjustment) { - this.renderedCells[index].el.element.css("top", (rowDatum.offset + verticalOffsetAdjustment) + "px"); - } - renderedCells.push(this.renderedCells[index]); - } else { - var child = BI.createWidget(BI.extend({ - type: "bi.label", - width: columnDatum.size, - height: rowDatum.size - }, o.items[rowIndex][columnIndex], { - cls: (o.items[rowIndex][columnIndex].cls || "") + " grid-cell" + (rowIndex === 0 ? " first-row" : "") + (columnIndex === 0 ? " first-col" : ""), - _rowIndex: rowIndex, - _columnIndex: columnIndex, - _left: columnDatum.offset + horizontalOffsetAdjustment, - _top: rowDatum.offset + verticalOffsetAdjustment - })); - renderedCells.push({ - el: child, - left: columnDatum.offset + horizontalOffsetAdjustment, - top: rowDatum.offset + verticalOffsetAdjustment, - _width: columnDatum.size, - _height: rowDatum.size - }); - } - renderedKeys.push(key); - } - } - //已存在的, 需要添加的和需要删除的 - var existSet = {}, addSet = {}, deleteArray = []; - BI.each(renderedKeys, function (i, key) { - if (BI.deepContains(self.renderedKeys, key)) { - existSet[i] = key; - } else { - addSet[i] = key; - } - }); - BI.each(this.renderedKeys, function (i, key) { - if (BI.deepContains(existSet, key)) { - return; - } - if (BI.deepContains(addSet, key)) { - return; - } - deleteArray.push(i); - }); - BI.each(deleteArray, function (i, index) { - self.renderedCells[index].el.destroy(); - }); - var addedItems = []; - BI.each(addSet, function (index) { - addedItems.push(renderedCells[index]) - }); - BI.createWidget({ - type: "bi.absolute", - element: this.container, - items: addedItems - }); - this.renderedCells = renderedCells; - this.renderedKeys = renderedKeys; + new BI.ShowListener({ + eventObj: this.tab, + cardLayout: this.layout, + cardNameCreator: function(v){ + return self.showIndex + v; + }, + cardCreator: function(v){ + var card = o.cardCreator(v); + self.cardMap[v] = card; + return card; + }, + afterCardCreated: BI.bind(this.afterCardCreated, this), + afterCardShow: BI.bind(this.afterCardShow, this) + }) + if(o.defaultShowIndex !== false){ + this.setSelect(o.defaultShowIndex); } }, - _getMaxScrollLeft: function () { - return Math.max(0, this._columnSizeAndPositionManager.getTotalSize() - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); + afterCardCreated: function(v){ + var self = this; + this.cardMap[v].on(BI.Controller.EVENT_CHANGE, function(type, value, obj){ + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if(type === BI.Events.CLICK) { + self.fireEvent(BI.Navigation.EVENT_CHANGE, obj); + } + }) + this.options.afterCardCreated.apply(this, arguments); }, - _getMaxScrollTop: function () { - return Math.max(0, this._rowSizeAndPositionManager.getTotalSize() - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); + afterCardShow: function(v){ + this.showIndex = v; + this.options.afterCardShow.apply(this, arguments); }, - _populate: function () { - var self = this, o = this.options; - if (o.items.length > 0) { - this.columnCount = o.items[0].length; - this.rowCount = o.items.length; - this.container.setWidth(this.columnCount * o.estimatedColumnSize); - this.container.setHeight(this.rowCount * o.estimatedRowSize); - - this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, o.columnWidthGetter, o.estimatedColumnSize); - this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, o.rowHeightGetter, o.estimatedRowSize); - - this._calculateChildrenToRender(); - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); + populate: function(){ + var card = this.layout.getShowingCard(); + if(card){ + return card.populate.apply(card, arguments); } }, - setScrollLeft: function (scrollLeft) { - if (this.options.scrollLeft === scrollLeft) { - return; + setSelect: function(v){ + this.showIndex = v; + if(!this.layout.isCardExisted(v)){ + var card = this.options.cardCreator(v); + this.cardMap[v] = card; + this.layout.addCardByName(v, card); + this.afterCardCreated(v); } - this._scrollLock = true; - this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); - this._debounceRelease(); - this._calculateChildrenToRender(); - this.element.scrollLeft(this.options.scrollLeft); + this.layout.showCardByName(v); + BI.nextTick(BI.bind(this.afterCardShow, this, v)); }, - setScrollTop: function (scrollTop) { - if (this.options.scrollTop === scrollTop) { - return; - } - this._scrollLock = true; - this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); - this._debounceRelease(); - this._calculateChildrenToRender(); - this.element.scrollTop(this.options.scrollTop); + getSelect: function(){ + return this.showIndex; }, - setOverflowX: function (b) { - var self = this; - if (this.options.overflowX !== !!b) { - this.options.overflowX = !!b; - BI.nextTick(function () { - self.element.css({overflowX: !!b ? "auto" : "hidden"}); - }); + getSelectedCard: function(){ + if(BI.isKey(this.showIndex)){ + return this.cardMap[this.showIndex]; } }, - setOverflowY: function (b) { - var self = this; - if (this.options.overflowY !== !!b) { - this.options.overflowY = !!b; - BI.nextTick(function () { - self.element.css({overflowY: !!b ? "auto" : "hidden"}); - }); + /** + * @override + */ + setValue: function(v){ + var card = this.layout.getShowingCard(); + if(card){ + card.setValue(v); } }, - getScrollLeft: function () { - return this.options.scrollLeft; + /** + * @override + */ + getValue: function(){ + var card = this.layout.getShowingCard(); + if(card){ + return card.getValue(); + } }, - getScrollTop: function () { - return this.options.scrollTop; + empty: function(){ + this.layout.deleteAllCard(); + this.cardMap = {}; }, - getMaxScrollLeft: function () { - return this._getMaxScrollLeft(); - }, - - getMaxScrollTop: function () { - return this._getMaxScrollTop(); - }, - - setEstimatedColumnSize: function (width) { - this.options.estimatedColumnSize = width; - }, - - setEstimatedRowSize: function (height) { - this.options.estimatedRowSize = height; - }, - - restore: function () { - BI.each(this.renderedCells, function (i, cell) { - cell.el.destroy(); - }); - this.renderedCells = []; - this.renderedKeys = []; - this._scrollLock = false; - }, - - populate: function (items) { - if (items && items !== this.options.items) { - this.options.items = items; - this.restore(); - } - this._populate(); - } -}); -BI.Grid.EVENT_SCROLL = "EVENT_SCROLL"; -$.shortcut('bi.grid_view', BI.Grid);/** - * floatBox弹出层, - * @class BI.FloatBox - * @extends BI.Widget - */ -BI.FloatBox = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.FloatBox.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-float-box", - width: 600, - height: 500 - }) - }, - _init: function () { - BI.FloatBox.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.showAction = new BI.ShowAction({ - tar: this - }); - this._center = BI.createWidget(); - this._north = BI.createWidget(); - this.element.draggable({ - cursor: BICst.cursorUrl, - handle: ".bi-message-title", - drag: function (e, ui) { - var W = $("body").width(), H = $("body").height(); - if (ui.position.left + o.width > W) { - ui.position.left = W - o.width; - } - if (ui.position.top + o.height > H) { - ui.position.top = H - o.height; - } - if (ui.position.left < 0) { - ui.position.left = 0; - } - if (ui.position.top < 0) { - ui.position.top = 0; - } - } - }); - this._south = BI.createWidget(); - BI.createWidget({ - type: 'bi.border', - element: this, - items: { - 'north': { - el: { - type: 'bi.border', - cls: 'bi-message-title', - items: { - center: { - el: { - type: "bi.absolute", - items: [{ - el: this._north, - left: 10, - top: 0, - right: 0, - bottom: 0 - }] - } - }, - east: { - el: { - type: 'bi.icon_button', - cls: 'bi-message-close close-font', - height: 50, - handler: function () { - self.currentSectionProvider.close(); - } - }, - width: 60 - } - } - }, - height: 50 - }, - 'center': { - el: { - type: "bi.absolute", - items: [{ - el: this._center, - left: 10, - top: 10, - right: 10, - bottom: 10 - }] - } - }, - 'south': { - el: { - type: "bi.absolute", - items: [{ - el: this._south, - left: 10, - top: 0, - right: 10, - bottom: 0 - }] - }, - height: 60 - } - } - }) - }, - - populate: function (sectionProvider) { - var self = this; - this.currentSectionProvider = sectionProvider; - sectionProvider.rebuildNorth(this._north); - sectionProvider.rebuildCenter(this._center); - sectionProvider.rebuildSouth(this._south); - if (sectionProvider instanceof BI.Widget) { - sectionProvider.on(BI.PopoverSection.EVENT_CLOSE, function () { - self.close(); - }) - } - }, - - show: function () { - this.showAction.actionPerformed(); - }, - - hide: function () { - this.showAction.actionBack(); - }, - - open: function () { - this.show(); - this.fireEvent(BI.FloatBox.EVENT_FLOAT_BOX_OPEN); - }, - - close: function () { - this.hide(); - this.fireEvent(BI.FloatBox.EVENT_FLOAT_BOX_CLOSED); - }, - - setZindex: function (zindex) { - this.element.css({"z-index": zindex}); + destroy: function(){ + BI.Navigation.superclass.destroy.apply(this, arguments); } }); +BI.Navigation.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.float_box", BI.FloatBox); - -BI.FloatBox.EVENT_FLOAT_BOX_CLOSED = "EVENT_FLOAT_BOX_CLOSED"; -BI.FloatBox.EVENT_FLOAT_BOX_OPEN = "EVENT_FLOAT_BOX_CLOSED"; -/** - * 下拉框弹出层, zIndex在1000w - * @class BI.PopupView +$.shortcut("bi.navigation", BI.Navigation);/** + * 搜索逻辑控件 + * + * Created by GUY on 2015/9/28. + * @class BI.Searcher * @extends BI.Widget */ -BI.PopupView = BI.inherit(BI.Widget, { + +BI.Searcher = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-view", - maxWidth: 'auto', - minWidth: 100, - //maxHeight: 200, - minHeight: 25, + return BI.extend(BI.Searcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-searcher", lgap: 0, rgap: 0, tgap: 0, bgap: 0, vgap: 0, hgap: 0, - direction: BI.Direction.Top, //工具栏的方向 - stopEvent: false,//是否停止mousedown、mouseup事件 - stopPropagation: false, //是否停止mousedown、mouseup向上冒泡 - logic: { - dynamic: true + + isDefaultInit: false, + isAutoSearch: true, //是否自动搜索 + isAutoSync: true, //是否自动同步数据, 即是否保持搜索面板和adapter面板状态值的统一 + chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, + + //isAutoSearch为false时启用 + onSearch: function (op, callback) { + callback([]) }, - tool: false, //自定义工具栏 - tabs: [], //导航栏 - buttons: [], //toolbar栏 el: { - type: "bi.button_group", - items: [], - chooseType: 0, - behaviors: {}, - layouts: [{ - type: "bi.vertical" - }] + type: "bi.search_editor" + }, + + popup: { + type: "bi.searcher_view" + }, + + adapter: null, + masker: { //masker层 + offset: {} } }) }, _init: function () { - BI.PopupView.superclass._init.apply(this, arguments); + BI.Searcher.superclass._init.apply(this, arguments); var self = this, o = this.options; - var fn = function (e) { - e.stopPropagation(); - }, stop = function (e) { - e.stopEvent(); - return false; - }; - this.element.css({ - "z-index": BI.zIndex_popup, - "min-width": o.minWidth + "px", - "max-width": o.maxWidth + "px" - }).bind({"click": fn, "mousewheel": fn}); - - o.stopPropagation && this.element.bind({"mousedown": fn, "mouseup": fn, "mouseover": fn}); - o.stopEvent && this.element.bind({"mousedown": stop, "mouseup": stop, "mouseover": stop}); - this.tool = this._createTool(); - this.tab = this._createTab(); - this.view = this._createView(); - this.toolbar = this._createToolBar(); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.PopupView.EVENT_CHANGE); - } + this.editor = BI.createWidget(o.el, { + type: "bi.search_editor" }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - scrolly: false, + BI.createWidget({ + type: "bi.vertical", + element: this, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, vgap: o.vgap, hgap: o.hgap, - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, - BI.extend({ - cls: "list-view-outer" - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tool, this.tab, this.view, this.toolbar) - }))) - ) - })))); + items: [this.editor] + }); + o.isDefaultInit && (this._assertPopupView()); + + var search = BI.debounce(BI.bind(this._search, this), BI.EVENT_RESPONSE_TIME, true); + this.editor.on(BI.Controller.EVENT_CHANGE, function (type) { + switch (type) { + case BI.Events.STARTEDIT: + self._startSearch(); + break; + case BI.Events.EMPTY: + self._stopSearch(); + break; + case BI.Events.CHANGE: + search(); + break; + case BI.Events.PAUSE: + self._pauseSearch(); + break; + } + }) }, - _createView: function () { - var o = this.options; - this.button_group = BI.createWidget(o.el, {type: "bi.button_group"}); - this.button_group.element.css({"min-height": o.minHeight + "px"}); - return this.button_group; + _assertPopupView: function () { + var self = this, o = this.options; + if (!BI.Maskers.has(this.getName())) { + this.popupView = BI.createWidget(o.popup, { + type: "bi.searcher_view", + chooseType: o.chooseType + }); + BI.Maskers.create(this.getName(), o.adapter, BI.extend({ + container: this, + render: this.popupView + }, o.masker)); + + this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + if (o.isAutoSync) { + var values = o.adapter && o.adapter.getValue(); + if (!obj.isSelected()) { + o.adapter && o.adapter.setValue(BI.deepWithout(values, obj.getValue())); + } else { + switch (o.chooseType) { + case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: + o.adapter && o.adapter.setValue([obj.getValue()]); + break; + case BI.ButtonGroup.CHOOSE_TYPE_MULTI: + values.push(obj.getValue()); + o.adapter && o.adapter.setValue(values); + break; + } + } + } + self.fireEvent(BI.Searcher.EVENT_CHANGE, value, obj); + } + }); + BI.nextTick(function () { + self.fireEvent(BI.Searcher.EVENT_AFTER_INIT); + }); + } }, - _createTool: function () { - var o = this.options; - if (false === o.tool) { - return; + _startSearch: function () { + this._assertPopupView(); + this._stop = false; + this._isSearching = true; + this.fireEvent(BI.Searcher.EVENT_START); + this.popupView.startSearch && this.popupView.startSearch(); + //搜索前先清空dom + BI.Maskers.get(this.getName()).empty(); + BI.nextTick(function (name) { + BI.Maskers.show(name); + }, this.getName()); + }, + + _pauseSearch: function () { + var o = this.options, name = this.getName(); + this._stop = true; + BI.nextTick(function (name) { + BI.Maskers.hide(name); + }, this.getName()); + if (BI.Maskers.has(name) && this._isSearching === true) { + this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); + this.fireEvent(BI.Searcher.EVENT_PAUSE); } - return BI.createWidget(o.tool) + this._isSearching = false; }, - _createTab: function () { - var o = this.options; - if (o.tabs.length === 0) { - return; + _stopSearch: function () { + var o = this.options, name = this.getName(); + this._stop = true; + BI.Maskers.hide(name); + if (BI.Maskers.has(name) && this._isSearching === true) { + //搜索后清空dom + BI.nextTick(function () { + BI.Maskers.has(name) && BI.Maskers.get(name).empty(); + }); + this.popupView && this.popupView.stopSearch && this.popupView.stopSearch(); + this.fireEvent(BI.Searcher.EVENT_STOP); } - return BI.createWidget({ - type: "bi.center", - cls: "list-view-tab", - height: 25, - items: o.tabs - }) + this._isSearching = false; }, - _createToolBar: function () { - var o = this.options; - if (o.buttons.length === 0) { + _search: function () { + var self = this, o = this.options, keyword = this.editor.getValue(); + if (keyword === "" || this._stop) { return; } + if (o.isAutoSearch) { + var items = (o.adapter.getItems && o.adapter.getItems()) || o.adapter.attr("items") || []; + var finding = BI.Func.getSearchResult(items, keyword); + var matched = finding.matched, finded = finding.finded; + this.popupView.populate(finded, matched, keyword); + o.isAutoSync && this.popupView.setValue(o.adapter.getValue()); + self.fireEvent(BI.Searcher.EVENT_SEARCHING); + return; + } + this.popupView.loading && this.popupView.loading(); + o.onSearch({ + times: 1, + keyword: keyword, + selectedValues: o.adapter && o.adapter.getValue() + }, function (searchResult, matchResult) { + if (!self._stop) { + var args = [].slice.call(arguments); + if (args.length > 0) { + args.push(keyword); + } + BI.Maskers.show(self.getName()); + self.popupView.populate.apply(self.popupView, args); + o.isAutoSync && self.popupView.setValue(o.adapter && o.adapter.getValue()); + self.popupView.loaded && self.popupView.loaded(); + self.fireEvent(BI.Searcher.EVENT_SEARCHING); + } + }); + }, - return BI.createWidget({ - type: "bi.center", - cls: "list-view-toolbar", - height: 30, - items: BI.createItems(o.buttons, { - once: false, - shadow: true, - isShadowShowingOnSelected: true - }) - }) + setAdapter: function (adapter) { + this.options.adapter = adapter; + BI.Maskers.remove(this.getName()); }, - populate: function (items) { - this.button_group.populate.apply(this.button_group, arguments); + doSearch: function () { + if (this.isSearching()) { + this._search(); + } }, - resetWidth: function (w) { - this.options.width = w; - this.element.width(w); + stopSearch: function () { + this._stopSearch();//先停止搜索,然后再去设置editor为空 + //important:停止搜索必须退出编辑状态,这里必须加上try(input框不显示时blur会抛异常) + try { + this.editor.blur(); + } catch (e) { + if (!this.editor.blur) { + throw new Error("editor没有实现blur方法"); + } + } finally { + this.editor.setValue(""); + } }, - resetHeight: function (h) { - var tbHeight = 30 * (this.toolbar ? 1 : 0), - tabHeight = 25 * (this.tab ? 1 : 0), - toolHeight = ((this.tool && this.tool.element.outerHeight()) || 25) * ((this.tool && this.tool.isVisible()) ? 1 : 0); - this.view.resetHeight ? this.view.resetHeight(h - tbHeight - tabHeight - toolHeight - 2) : - this.view.element.css({"max-height": (h - tbHeight - tabHeight - toolHeight - 2) + "px"}) + isSearching: function () { + return this._isSearching; }, - setEnable: function (arg) { - BI.PopupView.superclass.setEnable.apply(this, arguments); - this.view && this.view.setEnable(arg); + isViewVisible: function () { + return this.editor.isEnabled() && BI.Maskers.isVisible(this.getName()); }, - setValue: function (selectedValues) { - this.tab && this.tab.setValue(selectedValues); - this.button_group.setValue(selectedValues); + getView: function () { + return this.popupView; }, - getValue: function () { - return this.button_group.getValue(); - } -}); -BI.PopupView.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.popup_view", BI.PopupView);/** - * guy - * @class BI.ScrollView - * @extends BI.Widget - */ -BI.ScrollView = BI.inherit(BI.Widget, { + hasMatched: function () { + this._assertPopupView(); + return this.popupView.hasMatched(); + }, - _const: { - dropDownHeight: 15, - expandIcon: "column-next-page-h-font", - collapseIcon: "column-pre-page-h-font" + adjustHeight: function () { + if (BI.Maskers.has(this.getName()) && BI.Maskers.get(this.getName()).isVisible()) { + BI.Maskers.show(this.getName()); + } }, - _defaultConfig: function() { - return BI.extend(BI.ScrollView.superclass._defaultConfig.apply(this, arguments), { - baseCls:"bi-scroll-view", - scrollHeight: 50, - maxHeight: 300 - }) + adjustView: function () { + this.isViewVisible() && BI.Maskers.show(this.getName()); }, - _init : function() { - BI.ScrollView.superclass._init.apply(this, arguments); + setValue: function (v) { + this._assertPopupView(); + this.popupView && this.popupView.setValue(v); + }, - this.scrollUp = false; - this.scroll = BI.createWidget({ - type: "bi.vertical", - cls: "scroll-container", - scrolly: true - }) - BI.createWidget({ - type: "bi.vertical", - element: this, - scrolly: false, - items: [this.scroll] - }) + getKeyword: function () { + return this.editor.getValue(); + }, - this.dropdown = BI.createWidget({ - type: "bi.icon_button", - height: this._const.dropDownHeight, - cls: "scroll-drop-down-icon " + this._const.expandIcon, - handler: BI.bind(this._dropDownOrUp, this) - }) - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.dropdown, - left: 0, - right: 0, - bottom: -1 * this._const.dropDownHeight - }] - }) - this.populate(this.options.items); + getKeywords: function () { + return this.editor.getKeywords(); }, - _dropDownOrUp: function(){ - if(!this.scrollUp){ - var height = this.element.height(); - height += this.options.scrollHeight; - height = Math.min(height, this.scroll.element[0].scrollHeight, this.options.maxHeight); - this.element.height(height); - this._checkDropDownState(); - } else { - var height = this.element.height(); - height -= this.options.scrollHeight; - height = Math.max(height, this.options.height); - this.element.height(height); - this._checkDropDownState(); + getValue: function () { + var o = this.options; + if (o.isAutoSync) { + return o.adapter.getValue(); } - }, - - _checkDropDownState: function(){ - var height = this.element.height(); - if(!this._checkScroll() || height >= this.options.maxHeight){ - this.scrollUp = true; - this.dropdown.element.removeClass(this._const.expandIcon).addClass(this._const.collapseIcon); - } else if(height <= this.options.height){ - this.scrollUp = false; - this.dropdown.element.addClass(this._const.expandIcon); + if (this.isSearching()) { + return this.popupView.getValue(); } else { - this.dropdown.element.addClass(this.scrollUp ? this._const.collapseIcon : this._const.expandIcon); + return o.adapter.getValue(); } }, - _checkScroll: function(){ - this.scroll.element.height(this.element.height()); - return this.scroll.element[0].scrollHeight > this.scroll.element[0].clientHeight; - }, - - _checkDropDown: function(){ - if(this._checkScroll()){ - this.dropdown.visible(); - //this.scrollUp = false; - this._checkDropDownState(); - } else { - this.dropdown.invisible(); + populate: function (result, searchResult, keyword) { + var o = this.options; + this._assertPopupView(); + this.popupView.populate.apply(this.popupView, arguments); + if (o.isAutoSync) { + this.popupView.setValue(o.adapter.getValue()); } }, - populate: function(){ - this.scroll.populate.apply(this.scroll, arguments); - this.resize(); - }, - - resize: function(){ - this.element.height(this.options.height); - BI.nextTick(BI.bind(this._checkDropDown, this)); + empty: function () { + this.popupView && this.popupView.empty(); }, - addItem: function(){ - this.scroll.addItem.apply(this.scroll, arguments); - BI.nextTick(BI.bind(this._checkDropDown, this)); + destroy: function () { + BI.Maskers.remove(this.getName()); + BI.Searcher.superclass.destroy.apply(this, arguments); } }); +BI.Searcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Searcher.EVENT_START = "EVENT_START"; +BI.Searcher.EVENT_STOP = "EVENT_STOP"; +BI.Searcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.Searcher.EVENT_SEARCHING = "EVENT_SEARCHING"; +BI.Searcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; -$.shortcut("bi.scroll_view", BI.ScrollView);/** - * 搜索面板 +$.shortcut("bi.searcher", BI.Searcher);/** * - * Created by GUY on 2015/9/28. - * @class BI.SearcherView - * @extends BI.Pane + * 切换显示或隐藏面板 + * + * Created by GUY on 2015/11/2. + * @class BI.Switcher + * @extends BI.Widget */ - -BI.SearcherView = BI.inherit(BI.Pane, { +BI.Switcher = BI.inherit(BI.Widget, { _defaultConfig: function () { - var conf = BI.SearcherView.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-searcher-view", - tipText: BI.i18nText("BI-No_Select"), - chooseType: BI.Selection.Single, - - matcher: {//完全匹配的构造器 - type: "bi.button_group", - behaviors: { - redmark: function () { - return true; - } - }, - items: [], - layouts: [{ - type: "bi.vertical" - }] - }, - searcher: { - type: "bi.button_group", - behaviors: { - redmark: function () { - return true; - } - }, - items: [], - layouts: [{ - type: "bi.vertical" - }] - } + return BI.extend(BI.Switcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-switcher", + direction: BI.Direction.Top, + trigger: "click", + toggle: true, + el: {}, + popup: {}, + adapter: null, + masker: {}, + switcherClass: "bi-switcher-popup", + hoverClass: "bi-switcher-hover" }) }, _init: function () { - BI.SearcherView.superclass._init.apply(this, arguments); + BI.Switcher.superclass._init.apply(this, arguments); var self = this, o = this.options; - - this.matcher = BI.createWidget(o.matcher, { - type: "bi.button_group", - chooseType: o.chooseType, - behaviors: { - redmark: function () { - return true; + this._initSwitcher(); + this._initPullDownAction(); + this.switcher.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (self.isEnabled() && this.isEnabled()) { + if (type === BI.Events.EXPAND) { + self._popupView(); } - }, - layouts: [{ - type: "bi.vertical" - }] - }); - this.matcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); - } - }); - this.spliter = BI.createWidget({ - type: "bi.vertical", - height: 1, - hgap: 10, - items: [{ - type: "bi.layout", - height: 1, - cls: "searcher-view-spliter" - }] - }); - this.searcher = BI.createWidget(o.searcher, { - type: "bi.button_group", - chooseType: o.chooseType, - behaviors: { - redmark: function () { - return true; + if (type === BI.Events.COLLAPSE) { + self._hideView(); + } + if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + if (type === BI.Events.CLICK) { + self.fireEvent(BI.Switcher.EVENT_TRIGGER_CHANGE, value, obj); } - }, - layouts: [{ - type: "bi.vertical" - }] - }); - this.searcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); } }); + this.element.hover(function () { + if (self.isEnabled() && self.switcher.isEnabled()) { + self.element.addClass(o.hoverClass); + } + }, function () { + if (self.isEnabled() && self.switcher.isEnabled()) { + self.element.removeClass(o.hoverClass); + } + }); BI.createWidget({ type: "bi.vertical", + scrolly: false, element: this, - items: [this.matcher, this.spliter, this.searcher] + items: [ + {el: this.switcher} + ] }); + o.isDefaultInit && (this._assertPopupView()); }, - startSearch: function () { - - }, - - stopSearch: function () { - - }, - - setValue: function (v) { - this.matcher.setValue(v); - this.searcher.setValue(v); - }, - - getValue: function () { - return this.matcher.getValue().concat(this.searcher.getValue()); - }, - - populate: function (searchResult, matchResult, keyword) { - searchResult || (searchResult = []); - matchResult || (matchResult = []); - this.setTipVisible(searchResult.length + matchResult.length === 0); - this.spliter.setVisible(BI.isNotEmptyArray(matchResult) && BI.isNotEmptyArray(searchResult)); - this.matcher.populate(matchResult, keyword); - this.searcher.populate(searchResult, keyword); - }, - - empty: function () { - this.searcher.empty(); - this.matcher.empty(); + _toggle: function () { + this._assertPopupView(); + if (this.isExpanded()) { + this._hideView(); + } else { + if (this.isEnabled()) { + this._popupView(); + } + } }, - hasMatched: function () { - return this.matcher.getAllButtons().length > 0; - } -}); -BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; + _initPullDownAction: function () { + var self = this, o = this.options; + var evs = this.options.trigger.split(","); + BI.each(evs, function (i, e) { + switch (e) { + case "hover": + self.element[e](function (e) { + if (self.isEnabled() && self.switcher.isEnabled()) { + self._popupView(); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.switcher); + self.fireEvent(BI.Switcher.EVENT_EXPAND); + } + }, function () { + if (self.isEnabled() && self.switcher.isEnabled() && o.toggle) { + self._hideView(); + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.switcher); + self.fireEvent(BI.Switcher.EVENT_COLLAPSE); + } + }); + break; + default : + if (e) { + self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { + if (self.switcher.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.switcher.isEnabled()) { + o.toggle ? self._toggle() : self._popupView(); + if (self.isExpanded()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, '', self.switcher); + self.fireEvent(BI.Switcher.EVENT_EXPAND); + } else { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, '', self.switcher); + self.fireEvent(BI.Switcher.EVENT_COLLAPSE); + } + } + } + }, BI.EVENT_RESPONSE_TIME, true)); + } + break; + } + }) + }, -$.shortcut("bi.searcher_view", BI.SearcherView);/** - * 分页控件 - * - * Created by GUY on 2015/8/31. - * @class BI.Pager - * @extends BI.Widget - */ -BI.Pager = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Pager.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-pager", - behaviors: {}, - layouts: [{ - type: "bi.horizontal", - hgap: 10, - vgap: 0 - }], + _initSwitcher: function () { + this.switcher = BI.createWidget(this.options.el); + }, - dynamicShow: true, //是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 - //dynamicShow为false时以下两个有用 - dynamicShowFirstLast: false,//是否动态显示首页、尾页 - dynamicShowPrevNext: false,//是否动态显示上一页、下一页 - pages: false, //总页数 - curr: function () { - return 1; - }, //初始化当前页 - groups: 0, //连续显示分页数 - jump: BI.emptyFn, //分页的回调函数 + _assertPopupView: function () { + var self = this, o = this.options; + if (!this._created) { + this.popupView = BI.createWidget(o.popup, { + type: "bi.button_group", + element: o.adapter && BI.Maskers.create(this.getName(), o.adapter, BI.extend({container: this}, o.masker)), + cls: "switcher-popup", + layouts: [{ + type: "bi.vertical", + hgap: 0, + vgap: 0 + }] + }); + this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.Switcher.EVENT_CHANGE, value, obj); + } + }); + if (o.direction !== BI.Direction.Custom && !o.adapter) { + BI.createWidget({ + type: "bi.vertical", + scrolly: false, + element: this, + items: [ + {el: this.popupView} + ] + }); + } + this._created = true; + BI.nextTick(function () { + self.fireEvent(BI.Switcher.EVENT_AFTER_INIT); + }); + } + }, - first: false, //是否显示首页 - last: false, //是否显示尾页 - prev: "上一页", - next: "下一页", + _hideView: function () { + this.fireEvent(BI.Switcher.EVENT_BEFORE_HIDEVIEW); + var self = this, o = this.options; + o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); + BI.nextTick(function () { + o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); + self.element.removeClass(o.switcherClass); + self.fireEvent(BI.Switcher.EVENT_AFTER_HIDEVIEW); + }); + }, - firstPage: 1, - lastPage: function () { //在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 - return 1; - }, - hasPrev: BI.emptyFn, //pages不可用时有效 - hasNext: BI.emptyFn //pages不可用时有效 - }) + _popupView: function () { + var self = this, o = this.options; + this._assertPopupView(); + this.fireEvent(BI.Switcher.EVENT_BEFORE_POPUPVIEW); + o.adapter ? BI.Maskers.show(this.getName()) : self.popupView.setVisible(true); + BI.nextTick(function (name) { + o.adapter ? BI.Maskers.show(name) : self.popupView.setVisible(true); + self.element.addClass(o.switcherClass); + self.fireEvent(BI.Switcher.EVENT_AFTER_POPUPVIEW); + }, this.getName()); }, - _init: function () { - BI.Pager.superclass._init.apply(this, arguments); - var self = this; - this.currPage = BI.result(this.options, "curr"); - //翻页太灵敏 - this._lock = false; - this._debouce = BI.debounce(function () { - self._lock = false; - }, 300); - this._populate(); + + populate: function (items) { + this._assertPopupView(); + this.popupView.populate.apply(this.popupView, arguments); + this.switcher.populate.apply(this.switcher, arguments); }, - populate: function () { - this.currPage = BI.result(this.options, "curr"); - this._populate(); + setEnable: function (arg) { + BI.Switcher.superclass.setEnable.apply(this, arguments); + this.switcher && this.switcher.setEnable(arg); + this.popupView && this.popupView.setEnable(arg); + !arg && this._hideView(); }, - - refresh: function () { - this._populate(); + + setValue: function (v) { + this._assertPopupView(); + this.switcher.setValue(v); + this.popupView && this.popupView.setValue(v); }, - _populate: function () { - var self = this, o = this.options, view = [], dict = {}; - this.empty(); - var pages = BI.result(o, "pages"); - var curr = BI.result(this, "currPage"); - var groups = BI.result(o, "groups"); - var first = BI.result(o, "first"); - var last = BI.result(o, "last"); - var prev = BI.result(o, "prev"); - var next = BI.result(o, "next"); + getValue: function () { + this._assertPopupView(); + return this.popupView ? this.popupView.getValue() : []; + }, - if (pages === false) { - groups = 0; - first = false; - last = false; - } else { - groups > pages && (groups = pages); - } + isViewVisible: function () { + return this.isEnabled() && this.switcher.isEnabled() && + (this.options.adapter ? BI.Maskers.isVisible(this.getName()) : (this.popupView && this.popupView.isVisible())); + }, - //计算当前组 - dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); + isExpanded: function () { + return this.isViewVisible(); + }, - //当前页非首页,则输出上一页 - if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { - if (BI.isKey(prev)) { - view.push({ - text: prev, - value: "prev", - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) - }) - } else { - view.push(BI.extend({ - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) - }, prev)); - } + showView: function () { + if (this.isEnabled() && this.switcher.isEnabled()) { + this._popupView(); } + }, - //当前组非首组,则输出首页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { - view.push({ - text: first, - value: "first", - disabled: !(dict.index > 1 && groups !== 0) - }); - if (dict.index > 1 && groups !== 0) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026" - }); - } + hideView: function () { + this._hideView(); + }, + + getView: function () { + return this.popupView; + }, + + adjustView: function () { + this.isViewVisible() && BI.Maskers.show(this.getName()); + }, + + doBehavior: function () { + this._assertPopupView(); + this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); + }, + + getAllLeaves: function () { + return this.popupView && this.popupView.getAllLeaves(); + }, + + getNodeById: function (id) { + if (this.switcher.attr("id") === id) { + return this.switcher; } + return this.popupView && this.popupView.getNodeById(id); + }, - //输出当前页组 - dict.poor = Math.floor((groups - 1) / 2); - dict.start = dict.index > 1 ? curr - dict.poor : 1; - dict.end = dict.index > 1 ? (function () { - var max = curr + (groups - dict.poor - 1); - return max > pages ? pages : max; - }()) : groups; - if (dict.end - dict.start < groups - 1) { //最后一组状态 - dict.start = dict.end - groups + 1; - } - var s = dict.start, e = dict.end; - if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { - s++; - e--; - } - for (; s <= e; s++) { - if (s === curr) { - view.push({ - text: s, - value: s, - selected: true - }) - } else { - view.push({ - text: s, - value: s - }) - } + getNodeByValue: function (value) { + if (this.switcher.getValue() === value) { + return this.switcher; } + return this.popupView && this.popupView.getNodeByValue(value); + }, - //总页数大于连续分页数,且当前组最大页小于总页,输出尾页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { - if (pages > groups && dict.end < pages && groups !== 0) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026" - }); + empty: function () { + this.popupView && this.popupView.empty(); + }, + + destroy: function () { + BI.Switcher.superclass.destroy.apply(this, arguments); + } +}); +BI.Switcher.EVENT_EXPAND = "EVENT_EXPAND"; +BI.Switcher.EVENT_COLLAPSE = "EVENT_COLLAPSE"; +BI.Switcher.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; +BI.Switcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Switcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + +BI.Switcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.Switcher.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; +BI.Switcher.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; +BI.Switcher.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + +$.shortcut("bi.switcher", BI.Switcher);/** + * Created by GUY on 2015/6/26. + */ + +BI.Tab = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.Tab.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tab", + direction: "top",//top, bottom, left, right, custom + logic: { + dynamic: false + }, + defaultShowIndex: 0, + tab: false, + cardCreator: function (v) { + return BI.createWidget(); } - view.push({ - text: last, - value: "last", - disabled: !(pages > groups && dict.end < pages && groups !== 0) + }) + }, + + _init: function () { + BI.Tab.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isObject(o.tab)) { + this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); + this.tab.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }) } + this.cardMap = {}; + this.layout = BI.createWidget({ + type: "bi.card" + }); - //当前页不为尾页时,输出下一页 - dict.flow = !prev && groups === 0; - if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { - view.push((function () { - if (BI.isKey(next)) { - if (pages === false) { - return {text: next, value: "next", disabled: o.hasNext(curr) === false} - } - return (dict.flow && curr === pages) - ? - {text: next, value: "next", disabled: true} - : - {text: next, value: "next", disabled: !(curr !== pages && next || dict.flow)}; - } else { - return BI.extend({ - disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow) - }, next); - } - }())); - } + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) + })))); - this.button_group = BI.createWidget({ - type: "bi.button_group", - element: this, - items: BI.createItems(view, { - cls: "page-item", - height: 23, - hgap: 10 - }), - behaviors: o.behaviors, - layouts: o.layouts - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self._lock === true) { - return; - } - self._lock = true; - self._debouce(); - if (type === BI.Events.CLICK) { - var v = self.button_group.getValue()[0]; - switch (v) { - case "first": - self.currPage = 1; - break; - case "last": - self.currPage = pages; - break; - case "prev": - self.currPage--; - break; - case "next": - self.currPage++; - break; - default: - self.currPage = v; - break; - } - o.jump.apply(self, [{ - pages: pages, - curr: self.currPage - }]); - self._populate(); - self.fireEvent(BI.Pager.EVENT_CHANGE, obj); + var listener = new BI.ShowListener({ + eventObj: this.tab, + cardLayout: this.layout, + cardCreator: function (v) { + var card = o.cardCreator.apply(self, arguments); + self.cardMap[v] = card; + return card; + }, + afterCardShow: function (v) { + self.curr = v; } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); - this.fireEvent(BI.Pager.EVENT_AFTER_POPULATE); + listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { + self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); + }); + if (o.defaultShowIndex !== false) { + this.setSelect(o.defaultShowIndex); + } }, - getCurrentPage: function () { - return this.currPage; + _assertCard: function (v) { + if (!this.layout.isCardExisted(v)) { + var card = this.options.cardCreator(v); + this.cardMap[v] = card; + this.layout.addCardByName(v, card); + } }, - setAllPages: function (pages) { - this.options.pages = pages; + setSelect: function (v) { + this.tab && this.tab.setValue(v); + this._assertCard(v); + this.layout.showCardByName(v); + if (this.curr !== v) { + this.curr = v; + } }, - hasPrev: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - return pages === false ? o.hasPrev(v) : v > 1; + getSelect: function () { + return this.curr; }, - hasNext: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - return pages === false ? o.hasNext(v) : v < pages; + getSelectedTab: function () { + return this.layout.getShowingCard(); + }, + + getTab: function (v) { + this._assertCard(v); + return this.layout.getCardByName(v); }, setValue: function (v) { - var o = this.options; - v = v | 0; - v = v < 1 ? 1 : v; - if (o.pages === false) { - var lastPage = BI.result(o, "lastPage"), firstPage = 1; - this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); - } else { - v = v > o.pages ? o.pages : v; - this.currPage = v; + var card = this.layout.getShowingCard(); + if (card) { + card.setValue(v); } - this._populate(); }, getValue: function () { - var val = this.button_group.getValue()[0]; - switch (val) { - case "prev": - return -1; - case "next": - return 1; - case "first": - return BI.MIN; - case "last": - return BI.MAX; - default : - return val; + var card = this.layout.getShowingCard(); + if (card) { + return card.getValue(); } - } -}); -BI.Pager.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Pager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; -$.shortcut("bi.pager", BI.Pager);/** - * 超链接 - * - * Created by GUY on 2015/9/9. - * @class BI.A - * @extends BI.Text - * @abstract - */ -BI.A = BI.inherit(BI.Text, { - _defaultConfig: function () { - var conf = BI.A.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-a display-block", - href: "", - target: "_blank", - el: null - }) - }, - _init: function () { - var o = this.options; - this.options.element = $(""); - BI.A.superclass._init.apply(this, arguments); - if (o.el) { - BI.createWidget(o.el, { - element: this - }); - } - } -}); - -$.shortcut("bi.a", BI.A);/** - * guy - * 加载条 - * @type {*|void|Object} - */ -BI.LoadingBar = BI.inherit(BI.Single, { - consts: { - loadedText: '加载更多', - endText: '无更多数据' - }, - _defaultConfig: function() { - var conf = BI.LoadingBar.superclass._defaultConfig.apply(this, arguments); - return BI.extend( conf, { - baseCls : (conf.baseCls ||"")+' bi-loading-bar', - height: 30, - handler: BI.emptyFn - }) - }, - _init : function() { - BI.LoadingBar.superclass._init.apply(this, arguments); - var self = this; - this.loaded = BI.createWidget({ - type: "bi.text_button", - cls: "loading-text", - text: this.consts.loadedText, - width: 120, - handler: this.options.handler - }) - this.loaded.on(BI.Controller.EVENT_CHANGE, function(type){ - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }) - - this.loading = BI.createWidget({ - type: "bi.layout", - height:this.options.height, - cls: "loading-background cursor-default" - }) - var loaded = BI.createWidget({ - type: "bi.center_adapt", - items: [this.loaded] - }) - var loading = BI.createWidget({ - type: "bi.center_adapt", - items: [this.loading] - }) - this.cardLayout = BI.createWidget({ - type: "bi.card", - element: this, - items: [{ - el: loaded, - cardName: "loaded" - }, { - el: loading, - cardName: "loading" - }] - }) - this.invisible(); - }, - - _reset: function(){ - this.visible(); - this.loaded.setText(this.consts.loadedText); - this.loaded.enable(); }, - setLoaded: function(){ - this._reset(); - this.cardLayout.showCardByName("loaded"); + populate: function () { + var card = this.layout.getShowingCard(); + if (card) { + return card.populate && card.populate.apply(card, arguments); + } }, - setEnd: function(){ - this.setLoaded(); - this.loaded.setText(this.consts.endText); - this.loaded.disable(); + empty: function () { + this.layout.deleteAllCard(); + this.cardMap = {}; }, - setLoading: function(){ - this._reset(); - this.cardLayout.showCardByName("loading"); + destroy: function () { + this.cardMap = {}; + BI.Tab.superclass.destroy.apply(this, arguments); } }); +BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.loading_bar", BI.LoadingBar);/** - * @class BI.IconButton - * @extends BI.BasicButton - * 图标的button +$.shortcut("bi.tab", BI.Tab);/** + * 表示当前对象 + * + * Created by GUY on 2015/9/7. + * @class BI.EL + * @extends BI.Widget */ -BI.IconButton = BI.inherit(BI.BasicButton, { +BI.EL = BI.inherit(BI.Widget, { _defaultConfig: function () { - var conf = BI.IconButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-icon-button horizon-center display-block", - iconWidth: null, - iconHeight: null - }) + return BI.extend(BI.EL.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-el", + el: {}, + layout: {} + }); }, - _init: function () { - BI.IconButton.superclass._init.apply(this, arguments); - var o = this.options; - this.element.css({ - textAlign: 'center' - }); - this.icon = BI.createWidget({ - type: 'bi.icon', - width: o.iconWidth, - height: o.iconHeight + BI.EL.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.ele = BI.createWidget(o.el); + BI.createWidget(o.layout, { + type: "bi.adaptive", + element: this, + items: [this.ele] }); - if (BI.isNumber(o.height) && o.height > 0 && BI.isNull(o.iconWidth) && BI.isNull(o.iconHeight)) { - this.element.css("lineHeight", o.height + "px"); - BI.createWidget({ - type: "bi.default", - element: this, - items: [this.icon] - }) - } else { - BI.createWidget({ - element: this, - type: 'bi.center_adapt', - items: [this.icon] - }); - } + this.ele.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }) }, - doClick: function () { - BI.IconButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconButton.EVENT_CHANGE, this); - } + setValue: function (v) { + this.ele.setValue(v); + }, + + getValue: function () { + return this.ele.getValue(); + }, + + populate: function () { + this.ele.populate.apply(this, arguments); } }); -BI.IconButton.EVENT_CHANGE = "IconButton.EVENT_CHANGE"; -$.shortcut("bi.icon_button", BI.IconButton);/** - * 图片的button +$.shortcut('bi.el', BI.EL);/** + * 选色控件 * - * Created by GUY on 2016/1/27. - * @class BI.ImageButton - * @extends BI.BasicButton + * Created by GUY on 2015/11/16. + * @class BI.Farbtastic + * @extends BI.Widget */ -BI.ImageButton = BI.inherit(BI.BasicButton, { +BI.Farbtastic = BI.inherit(BI.Widget, { + _defaultConfig: function () { - var conf = BI.ImageButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-image-button display-block", - src: "", - iconWidth: "100%", - iconHeight: "100%" + return BI.extend(BI.Farbtastic.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-farbtastic", + width: 195, + height: 195 }) }, _init: function () { - BI.ImageButton.superclass._init.apply(this, arguments); - var o = this.options; - this.image = BI.createWidget({ - type: "bi.img", - width: o.iconWidth, - height: o.iconHeight, - src: o.src - }); - if (BI.isNumber(o.iconWidth) || BI.isNumber(o.iconHeight)) { - BI.createWidget({ - type: "bi.center_adapt", - element: this, - items: [this.image] - }) - } else { - BI.createWidget({ - type: "bi.adaptive", - element: this, - items: [this.image], - scrollable: false - }) - } - }, - - setWidth: function (w) { - BI.ImageButton.superclass.setWidth.apply(this, arguments); - this.options.width = w; - }, - - setHeight: function (h) { - BI.ImageButton.superclass.setHeight.apply(this, arguments); - this.options.height = h; - }, + BI.Farbtastic.superclass._init.apply(this, arguments); + var self = this; + FR.$defaultImport('/com/fr/bi/web/js/third/farbtastic.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/css/base/third/farbtastic/farbtastic.css', 'css'); - setImageWidth: function (w) { - this.image.setWidth(w); + this.farbtastic = $.farbtastic(this.element, function (v) { + self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); + }); }, - setImageHeight: function (h) { - this.image.setHeight(h); + setValue: function (color) { + this.farbtastic.setColor(color); }, - getImageWidth: function () { - return this.image.element.width(); - }, + getValue: function () { + return this.farbtastic.color; + } +}); +BI.Farbtastic.EVENT_CHANGE = "Farbtastic.EVENT_CHANGE"; +$.shortcut("bi.farbtastic", BI.Farbtastic);(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + var Pos = CodeMirror.Pos; - getImageHeight: function () { - return this.image.element.height(); - }, + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } - setSrc: function (src) { - this.options.src = src; - this.image.setSrc(src); - }, + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } - getSrc: function () { - return this.image.getSrc(); - }, + function scriptHint(editor, keywords, getToken, options) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur); + if (/\b(?:string)\b/.test(token.type)) { + return; + } + token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; - doClick: function () { - BI.ImageButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.ImageButton.EVENT_CHANGE, this); + if (!/^[\w$_]*$/.test(token.string)) { + token = { + start: cur.ch, end: cur.ch, string: "", state: token.state, + type: token.string == "." ? "property" : null + }; + } else if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + var tprop = token; + // If it is a property, find out what it is a property of. + while (tprop.type == "property") { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string != ".") return; + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (!context) var context = []; + context.push(tprop); } + return { + list: getCompletions(token, context, keywords, options), + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end) + }; } -}); -BI.ImageButton.EVENT_CHANGE = "ImageButton.EVENT_CHANGE"; -$.shortcut("bi.image_button", BI.ImageButton);(function ($) { - /** - * 文字类型的按钮 - * @class BI.Button - * @extends BI.BasicButton - * - * @cfg {JSON} options 配置属性 - * @cfg {'common'/'success'/'warning'/'ignore'} [options.level='common'] 按钮类型,用不同颜色强调不同的场景 - */ - BI.Button = BI.inherit(BI.BasicButton, { - _const: { - minWidth: 90 - }, + function getFormulaKeywords() { + return FormulaCollections; + } - _defaultConfig: function () { - var conf = BI.Button.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + ' bi-button', - shadow: true, - isShadowShowingOnSelected: true, - readonly: true, - iconClass: "", - level: 'common', - textAlign: "center", - whiteSpace: "nowrap", - forceCenter: false, - textWidth: null, - textHeight: null, - hgap: 10, - vgap: 0, - tgap: 0, - bgap: 0, - lgap: 0, - rgap: 0 - }) - }, + function formulaHint(editor, options) { + return scriptHint(editor, getFormulaKeywords(), + function (e, cur) { + return e.getTokenAt(cur); + }, + options); + }; + CodeMirror.registerHelper("hint", "formula", formulaHint); - _init: function () { - BI.Button.superclass._init.apply(this, arguments); - var o = this.options, self = this; - if (BI.isNumber(o.height)) { - this.element.css({height: o.height - 2, lineHeight: (o.height - 2) + 'px'}); - } - if (BI.isKey(o.iconClass)) { - this.icon = BI.createWidget({ - type: "bi.icon", - width: 18 - }); - this.text = BI.createWidget({ - type: "bi.label", - text: o.text, - value: o.value - }); - BI.createWidget({ - type: "bi.horizontal_auto", - cls: "button-" + o.level + " " + o.iconClass, - element: this, - hgap: o.hgap, - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - lgap: o.lgap, - rgap: o.rgap, - items: [{ - type: "bi.horizontal", - items: [this.icon, this.text] - }] - }) - } else { - this.text = BI.createWidget({ - type: "bi.label", - cls: "button-" + o.level, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - forceCenter: o.forceCenter, - textWidth: o.textWidth, - textHeight: o.textHeight, - hgap: o.hgap, - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - lgap: o.lgap, - rgap: o.rgap, - element: this, - text: o.text, - value: o.value - }); + function getCompletions(token, context, keywords, options) { + var found = [], start = token.string; + if (!start) { + return found; + } + function maybeAdd(str) { + if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) { + found.push(str); } - this.element.css({"min-width": this._const.minWidth - 2 + "px"}); - }, + } - doClick: function () { - BI.Button.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.Button.EVENT_CHANGE, this); - } - }, + if (context && context.length) { + context.pop(); + } else { + forEach(keywords, maybeAdd); + } + return found; + } +});(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + "use strict"; - setText: function (text) { - BI.Button.superclass.setText.apply(this, arguments); - this.text.setText(text); - }, + CodeMirror.defineMode('formula', function () { + function wordObj(words) { + var o = {}; + for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; + return o; + } - setValue: function (text) { - BI.Button.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.text.setValue(text); + var atoms = wordObj(['false', 'true']); + var keywords = wordObj(FormulaCollections); + + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return null; } - }, + var ch = stream.next(); - setEnable: function (b) { - BI.Button.superclass.setEnable.apply(this, arguments); - this.text.setEnable(b); - this.icon && this.icon.setEnable(b); - }, + if (ch === '"' || ch === '\'') { + nextUntilUnescaped(stream, ch); + return "string"; + } + if (/[\[\],\(\)]/.test(ch)) { + return 'bracket'; + } - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + // richie:暂时不需要解析操作符号 + //if (/[+\-*\/=<>!&|]/.test(ch)) { + // return 'operator'; + //} + //if (/\d|\d./.test(ch)) { + // stream.eatWhile(/\d|\./); + // if (stream.eol() || !/\w/.test(stream.peek())) { + // return 'number'; + // } + //} - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, + stream.eatWhile(/[\w-]/); + var word = stream.current(); + if (atoms.hasOwnProperty(word)) { + return "atom"; + } + if (keywords.hasOwnProperty(word)) { + return "keyword"; + } + return null; + } - destroy: function () { - BI.Button.superclass.destroy.apply(this, arguments); + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next === end && !escaped) { + return false; + } + escaped = !escaped && next === "\\"; + } + return escaped; } - }); - $.shortcut('bi.button', BI.Button); - BI.Button.EVENT_CHANGE = "EVENT_CHANGE"; -})(jQuery);/** - * guy - * 可以点击的一行文字 - * @class BI.TextButton - * @extends BI.BasicButton - * 文字button - */ -BI.TextButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function() { - var conf = BI.TextButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend( conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-text-button display-block", - textAlign: "center", - whiteSpace: "nowrap", - forceCenter: false, - textWidth: null, - textHeight: null, - hgap: 0, - lgap: 0, - rgap: 0, - text:"", - py: "" - }) - }, - - _init:function() { - BI.TextButton.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textWidth: o.textWidth, - textHeight: o.textHeight, - forceCenter: o.forceCenter, - width: o.width, - height: o.height, - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - text: o.text, - value: o.value, - py: o.py - }); - }, - doClick: function(){ - BI.TextButton.superclass.doClick.apply(this, arguments); - if(this.isValid()) { - this.fireEvent(BI.TextButton.EVENT_CHANGE, this.getValue(), this); + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase)(stream, state); } - }, - - doRedMark: function(){ - this.text.doRedMark.apply(this.text, arguments); - }, - unRedMark: function(){ - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + return { + startState: function () { + return {tokens: []}; + }, + token: function (stream, state) { + return tokenize(stream, state); + }, + fold: "brace" + }; + }); + CodeMirror.defineMIME("text/fx-formula", "formula"); +});// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, +(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + "use strict"; - setText: function(text){ - BI.TextButton.superclass.setText.apply(this, arguments); - text = BI.isArray(text) ? text.join(",") : text; - this.text.setText(text); - }, + var HINT_ELEMENT_CLASS = "CodeMirror-hint"; + var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; - setValue: function(text){ - BI.TextButton.superclass.setValue.apply(this, arguments); - if(!this.isReadOnly()) { - text = BI.isArray(text) ? text.join(",") : text; - this.text.setValue(text); - } - } -}); -BI.TextButton.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.text_button", BI.TextButton);/** - * guy - * 一个占位符和两个icon和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/15. - * @class BI.BlankIconTextIconItem - * @extends BI.BasicButton - */ -BI.BlankIconTextIconItem = BI.inherit(BI.BasicButton, { - _const: { - commonWidth: 25 - }, + // This is the old interface, kept around for now to stay + // backwards-compatible. + CodeMirror.showHint = function (cm, getHints, options) { + if (!getHints) return cm.showHint(options); + if (options && options.async) getHints.async = true; + var newOpts = {hint: getHints}; + if (options) for (var prop in options) newOpts[prop] = options[prop]; + return cm.showHint(newOpts); + }; - _defaultConfig: function () { - var conf = BI.BlankIconTextIconItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-blank-icon-text-icon-item", - logic: { - dynamic: false - }, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - blankWidth: 0, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.BlankIconTextIconItem.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) + CodeMirror.defineExtension("showHint", function (options) { + // We want a single cursor position. + if (this.listSelections().length > 1 || this.somethingSelected()) return; - var icon1 = BI.createWidget({ - type: "bi.center_adapt", - cls: o.iconCls1, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }) - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.center_adapt", - cls: o.iconCls2, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }, - top: 0, - bottom: 0, - right: 0 - }] - }) + if (this.state.completionActive) this.state.completionActive.close(); + var completion = this.state.completionActive = new Completion(this, options); + if (!completion.options.hint) return; - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", { - type: "bi.layout", - width: o.blankWidth - }, icon1, this.text, { - type: "bi.layout", - width: c.commonWidth - }) - })))); - }, + CodeMirror.signal(this, "startCompletion", this); + completion.update(true); + }); - doClick: function () { - BI.BlankIconTextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.BlankIconTextIconItem.EVENT_CHANGE, this.getValue(), this); - } - }, + function Completion(cm, options) { + this.cm = cm; + this.options = this.buildOptions(options); + this.widget = null; + this.debounce = 0; + this.tick = 0; + this.startPos = this.cm.getCursor(); + this.startLen = this.cm.getLine(this.startPos.line).length; - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + var self = this; + cm.on("cursorActivity", this.activityFunc = function () { + self.cursorActivity(); + }); + } - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + var requestAnimationFrame = window.requestAnimationFrame || function (fn) { + return setTimeout(fn, 1000 / 60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + Completion.prototype = { + close: function () { + if (!this.active()) return; + this.cm.state.completionActive = null; + this.tick = null; + this.cm.off("cursorActivity", this.activityFunc); - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, + if (this.widget && this.data) CodeMirror.signal(this.data, "close"); + if (this.widget) this.widget.close(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + active: function () { + return this.cm.state.completionActive == this; + }, - getValue: function () { - return this.text.getValue(); - }, + pick: function (data, i) { + var completion = data.list[i]; + if (completion.hint) completion.hint(this.cm, data, completion); + else { + this.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + var to = this.cm.getCursor(); + this.cm.markText(completion.from || data.from, to, {className: "#function", atomic: true}); + this.cm.replaceSelection("() "); + to = this.cm.getCursor(); + to.ch = to.ch - 2; + this.cm.setCursor(to); + this.cm.focus(); + } + CodeMirror.signal(data, "pick", completion); + this.close(); + }, - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + cursorActivity: function () { + if (this.debounce) { + cancelAnimationFrame(this.debounce); + this.debounce = 0; + } - getText: function () { - return this.text.getText(); - } -}); -BI.BlankIconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.blank_icon_text_icon_item", BI.BlankIconTextIconItem);/** - * 带有一个占位 - * - * Created by GUY on 2015/9/11. - * @class BI.BlankIconTextItem - * @extends BI.BasicButton - */ -BI.BlankIconTextItem = BI.inherit(BI.BasicButton, { - _const: { - commonWidth: 25 - }, + var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); + if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || + pos.ch < this.startPos.ch || this.cm.somethingSelected() || + (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { + this.close(); + } else { + var self = this; + this.debounce = requestAnimationFrame(function () { + self.update(); + }); + if (this.widget) this.widget.disable(); + } + }, - _defaultConfig: function () { - var conf = BI.BlankIconTextItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", - logic: { - dynamic: false - }, - cls: "close-ha-font", - blankWidth: 0, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.BlankIconTextItem.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - var blank = BI.createWidget({ - type: "bi.layout", - width: o.blankWidth - }) - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }); + update: function (first) { + if (this.tick == null) return; + if (this.data) CodeMirror.signal(this.data, "update"); + if (!this.options.hint.async) { + this.finishUpdate(this.options.hint(this.cm, this.options), first); + } else { + var myTick = ++this.tick, self = this; + this.options.hint(this.cm, function (data) { + if (self.tick == myTick) self.finishUpdate(data, first); + }, this.options); + } + }, - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon, this.text) - })))); - }, + finishUpdate: function (data, first) { + this.data = data; - doClick: function () { - BI.BlankIconTextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.BlankIconTextItem.EVENT_CHANGE, this.getValue(), this); - } - }, + var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); + if (this.widget) this.widget.close(); + if (data && data.list.length) { + if (picked && data.list.length == 1) { + this.pick(data, 0); + } else { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + } + } + }, - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); + buildOptions: function (options) { + var editor = this.cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + return out; } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + }; - getText: function () { - return this.text.getText(); - }, + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + function buildKeyMap(completion, handle) { + var baseMap = { + Up: function () { + handle.moveFocus(-1); + }, + Down: function () { + handle.moveFocus(1); + }, + PageUp: function () { + handle.moveFocus(-handle.menuSize() + 1, true); + }, + PageDown: function () { + handle.moveFocus(handle.menuSize() - 1, true); + }, + Home: function () { + handle.setFocus(0); + }, + End: function () { + handle.setFocus(handle.length - 1); + }, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + var custom = completion.options.customKeys; + var ourMap = custom ? {} : baseMap; - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function (cm) { + return val(cm, handle); + }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + if (custom) + for (var key in custom) if (custom.hasOwnProperty(key)) + addBinding(key, custom[key]); + var extra = completion.options.extraKeys; + if (extra) + for (var key in extra) if (extra.hasOwnProperty(key)) + addBinding(key, extra[key]); + return ourMap; + } - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); + function getHintElement(hintsElement, el) { + while (el && el != hintsElement) { + if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; + el = el.parentNode; + } } -}); -BI.BlankIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.blank_icon_text_item", BI.BlankIconTextItem);/** - * guy - * 两个icon和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/9. - * @class BI.IconTextIconItem - * @extends BI.BasicButton - */ -BI.IconTextIconItem = BI.inherit(BI.BasicButton, { - _const: { - commonWidth: 25 - }, - _defaultConfig: function () { - var conf = BI.IconTextIconItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-icon-item", - logic: { - dynamic: false - }, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.IconTextIconItem.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) + function Widget(completion, data) { + this.completion = completion; + this.data = data; + this.picked = false; + var widget = this, cm = completion.cm; - var icon1 = BI.createWidget({ - type: "bi.center_adapt", - cls: o.iconCls1, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight + var hints = this.hints = document.createElement("ul"); + hints.className = "CodeMirror-hints"; + this.selectedHint = data.selectedHint || 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + } + + var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + hints.style.left = left + "px"; + hints.style.top = top + "px"; + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. + var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); + var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); + (completion.options.container || document.body).appendChild(hints); + var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + hints.style.top = (top = pos.top - height) + "px"; + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) + "px"; + hints.style.top = (top = pos.bottom - box.top) + "px"; + var cursor = cm.getCursor(); + if (data.from.ch != cursor.ch) { + pos = cm.cursorCoords(cursor); + hints.style.left = (left = pos.left) + "px"; + box = hints.getBoundingClientRect(); } - }] - }) - var blank = BI.createWidget({ - type: "bi.layout", - width: c.commonWidth - }) - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.center_adapt", - cls: o.iconCls2, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }, - top: 0, - bottom: 0, - right: 0 - }] - }) + } + } + var overlapX = box.right - winW; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX) + "px"; + } - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) - })))); - }, + cm.addKeyMap(this.keyMap = buildKeyMap(completion, { + moveFocus: function (n, avoidWrap) { + widget.changeActive(widget.selectedHint + n, avoidWrap); + }, + setFocus: function (n) { + widget.changeActive(n); + }, + menuSize: function () { + return widget.screenAmount(); + }, + length: completions.length, + close: function () { + completion.close(); + }, + pick: function () { + widget.pick(); + }, + data: data + })); - doClick: function () { - BI.IconTextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextIconItem.EVENT_CHANGE, this.getValue(), this); + if (completion.options.closeOnUnfocus) { + var closingOnBlur; + cm.on("blur", this.onBlur = function () { + closingOnBlur = setTimeout(function () { + completion.close(); + }, 100); + }); + cm.on("focus", this.onFocus = function () { + clearTimeout(closingOnBlur); + }); } - }, - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + var startScroll = cm.getScrollInfo(); + cm.on("scroll", this.onScroll = function () { + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) + "px"; + }); - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + CodeMirror.on(hints, "dblclick", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + widget.pick(); + } + }); - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + CodeMirror.on(hints, "click", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + if (completion.options.completeOnSingleClick) widget.pick(); + } + }); - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, + CodeMirror.on(hints, "mousedown", function () { + setTimeout(function () { + cm.focus(); + }, 20); + }); - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + CodeMirror.signal(data, "select", completions[0], hints.firstChild); + return true; + } - getValue: function () { - return this.text.getValue(); - }, + Widget.prototype = { + close: function () { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, - getText: function () { - return this.text.getText(); - } -}); -BI.IconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.icon_text_icon_item", BI.IconTextIconItem);/** - * guy - * - * Created by GUY on 2015/9/9. - * @class BI.IconTextItem - * @extends BI.BasicButton - */ -BI.IconTextItem = BI.inherit(BI.BasicButton, { - _const: { - commonWidth: 25 - }, + disable: function () { + this.completion.cm.removeKeyMap(this.keyMap); + var widget = this; + this.keyMap = { + Enter: function () { + widget.picked = true; + } + }; + this.completion.cm.addKeyMap(this.keyMap); + }, - _defaultConfig: function () { - var conf = BI.IconTextItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-item", - direction: BI.Direction.Left, - logic: { - dynamic: false - }, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.IconTextItem.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }); - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }); + pick: function () { + this.completion.pick(this.data, this.selectedHint); + }, - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.icon, this.text) - })))); - }, + changeActive: function (i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; + if (node.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node.offsetTop - 3; + else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); + screenAmount: function () { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; } - }, + }; - getValue: function () { - return this.text.getValue(); - }, + CodeMirror.registerHelper("hint", "auto", function (cm, options) { + var helpers = cm.getHelpers(cm.getCursor(), "hint"), words; + if (helpers.length) { + for (var i = 0; i < helpers.length; i++) { + var cur = helpers[i](cm, options); + if (cur && cur.list.length) return cur; + } + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + if (words) return CodeMirror.hint.fromList(cm, {words: words}); + } else if (CodeMirror.hint.anyword) { + return CodeMirror.hint.anyword(cm, options); + } + }); - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + CodeMirror.registerHelper("hint", "fromList", function (cm, options) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var found = []; + for (var i = 0; i < options.words.length; i++) { + var word = options.words[i]; + if (word.slice(0, token.string.length) == token.string) + found.push(word); + } - getText: function () { - return this.text.getText(); - }, + if (found.length) return { + list: found, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + }); - doClick: function () { - BI.IconTextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextItem.EVENT_CHANGE, this.getValue(), this); - } - }, + CodeMirror.commands.autocomplete = CodeMirror.showHint; - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + var defaultOptions = { + hint: CodeMirror.hint.auto, + completeSingle: true, + alignWithWord: true, + closeCharacters: /[\s()\[\]{};:>,]/, + closeOnUnfocus: true, + completeOnSingleClick: true, + container: null, + customKeys: null, + extraKeys: null + }; - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + CodeMirror.defineOption("hintOptions", null); +});// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - } -}); -BI.IconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.icon_text_item", BI.IconTextItem);/** - * - * 图标的button - * - * Created by GUY on 2015/9/9. - * @class BI.TextIconItem - * @extends BI.BasicButton - */ -BI.TextIconItem = BI.inherit(BI.BasicButton, { - _const: { - commonWidth: 25 - }, +(function(mod) { + this.CodeMirror = mod(); +})(function() { + "use strict"; - _defaultConfig: function () { - var conf = BI.TextIconItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-icon-item", - logic: { - dynamic: false - }, - cls: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.TextIconItem.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }); - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }); + // BROWSER SNIFFING - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) - })))); - }, + // Kludges for bugs and behavior differences that can't be feature + // detected are enabled based on userAgent etc sniffing. - doClick: function () { - BI.TextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextIconItem.EVENT_CHANGE, this.getValue(), this); - } - }, + var gecko = /gecko\/\d/i.test(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + var ie = ie_upto10 || ie_11up; + var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); + var webkit = /WebKit\//.test(navigator.userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); + var chrome = /Chrome\//.test(navigator.userAgent); + var presto = /Opera\//.test(navigator.userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); + var phantom = /PhantomJS/.test(navigator.userAgent); - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); + var mac = ios || /Mac/.test(navigator.platform); + var windows = /win/i.test(navigator.platform); - getValue: function () { - return this.text.getValue(); - }, + var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); + if (presto_version) presto_version = Number(presto_version[1]); + if (presto_version && presto_version >= 15) { presto = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); + var captureRightClick = gecko || (ie && ie_version >= 9); - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + // Optimize some code when these features are not used. + var sawReadOnlySpans = false, sawCollapsedSpans = false; - getText: function () { - return this.text.getText(); - }, + // EDITOR CONSTRUCTOR - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + this.options = options = options ? copyObj(options) : {}; + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false); + setGuttersForLineNumbers(options); - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - } -}); -BI.TextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.text_icon_item", BI.TextIconItem);/** - * guy - * 一个button和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/9. - * @class BI.TextItem - * @extends BI.BasicButton - */ -BI.TextItem = BI.inherit(BI.BasicButton, { + var doc = options.value; + if (typeof doc == "string") doc = new Doc(doc, options.mode); + this.doc = doc; - _defaultConfig: function () { - var conf = BI.TextItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-item", - textAlign: "left", - whiteSpace: "nowrap", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.TextItem.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, - height: o.height, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - }, + var input = new CodeMirror.inputStyles[options.inputStyle](this); + var display = this.display = new Display(place, doc, input); + display.wrapper.CodeMirror = this; + updateGutters(this); + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + if (options.autofocus && !mobile) display.input.focus(); + initScrollbars(this); - doClick: function () { - BI.TextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextItem.EVENT_CHANGE, this.getValue(), this); - } - }, + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + }; - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + var cm = this; - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + registerEventHandlers(this); + ensureGlobalHandlers(); - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, + startOperation(this); + this.curOp.forceUpdate = true; + attachDoc(this, doc); - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + if ((options.autofocus && !mobile) || cm.hasFocus()) + setTimeout(bind(onFocus, this), 20); + else + onBlur(this); - getValue: function () { - return this.text.getValue(); - }, + for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](this, options[opt], Init); + maybeUpdateLineNumberWidth(this); + if (options.finishInit) options.finishInit(this); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); + endOperation(this); + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + display.lineDiv.style.textRendering = "auto"; + } - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + // DISPLAY CONSTRUCTOR - getText: function () { - return this.text.getText(); + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc, input) { + var d = this; + this.input = input; + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.scrollbarFiller.setAttribute("cm-not-content", "true"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + d.gutterFiller.setAttribute("cm-not-content", "true"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = elt("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + d.sizerWidth = null; + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; + + if (place) { + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); } -}); -BI.TextItem.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.text_item", BI.TextItem);/** - * guy - * Created by GUY on 2015/9/9. - * @class BI.IconTextIconNode - * @extends BI.NodeButton - */ -BI.IconTextIconNode = BI.inherit(BI.NodeButton, { - _const: { - commonWidth: 25 - }, - _defaultConfig: function () { - var conf = BI.IconTextIconNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-icon-node", - logic: { - dynamic: false - }, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.IconTextIconNode.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + d.reportedViewFrom = d.reportedViewTo = doc.first; + // Information about the rendered lines. + d.view = []; + d.renderedView = null; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastWrapHeight = d.lastWrapWidth = 0; + d.updateLineNumbers = null; - var icon1 = BI.createWidget({ - type: "bi.center_adapt", - cls: o.iconCls1, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }) - var blank = BI.createWidget({ - type: "bi.layout", - width: c.commonWidth - }) - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.center_adapt", - cls: o.iconCls2, - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }, - top: 0, - bottom: 0, - right: 0 - }] - }) + d.nativeBarWidth = d.barHeight = d.barWidth = 0; + d.scrollbarsClipped = false; - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) - })))); - }, + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; - doClick: function () { - BI.IconTextIconNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextIconNode.EVENT_CHANGE, this.getValue(), this); - } - }, + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + // True when shift is held down. + d.shift = false; - getValue: function () { - return this.text.getValue(); - }, + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null; - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + d.activeTouch = null; - getText: function () { - return this.text.getText(); - } -}); -BI.IconTextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.icon_text_icon_node", BI.IconTextIconNode);/** - * guy - * Created by GUY on 2015/9/9. - * @class BI.IconTextNode - * @extends BI.NodeButton - */ -BI.IconTextNode = BI.inherit(BI.NodeButton, { - _const: { - commonWidth: 25 - }, + input.init(d); + } - _defaultConfig: function () { - var conf = BI.IconTextNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-node", - logic: { - dynamic: false - }, - cls: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.IconTextNode.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }) + // STATE UPDATES - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", this.icon, this.text) - })))); - }, + // Used to get the editor into a consistent state again when options change. - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } - getValue: function () { - return this.text.getValue(); - }, + function resetModeState(cm) { + cm.doc.iter(function(line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap"); + cm.display.sizer.style.minWidth = ""; + cm.display.sizerWidth = null; + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap"); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function(){updateScrollbars(cm);}, 100); + } - getText: function () { - return this.text.getText(); - }, + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function(line) { + if (lineIsHidden(cm.doc, line)) return 0; - doClick: function () { - BI.IconTextNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextNode.EVENT_CHANGE, this.getValue(), this); - } - }, + var widgetsHeight = 0; + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; + } - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; + else + return widgetsHeight + th; + }; + } - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - } -}); -BI.IconTextNode.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.icon_text_node", BI.IconTextNode);/** - * Created by GUY on 2015/9/9. - * @class BI.TextIconNode - * @extends BI.NodeButton - */ -BI.TextIconNode = BI.inherit(BI.NodeButton, { - _const: { - commonWidth: 25 - }, + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function(line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } - _defaultConfig: function () { - var conf = BI.TextIconNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-icon-node", - logic: { - dynamic: false - }, - cls: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.TextIconNode.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }) - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: c.commonWidth, - items: [{ - el: { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - } - }] - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) - })))); - }, - - doClick: function () { - BI.TextIconNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextIconNode.EVENT_CHANGE, this.getValue(), this); - } - }, + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function(){alignHorizontally(cm);}, 20); + } - getValue: function () { - return this.text.getValue(); - }, + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + updateGutterSpace(cm); + } - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + function updateGutterSpace(cm) { + var width = cm.display.gutters.offsetWidth; + cm.display.sizer.style.marginLeft = width + "px"; + } - getText: function () { - return this.text.getText(); - }, + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(0, true); + len -= cur.text.length - found.from.ch; + cur = found.to.line; + len += cur.text.length - found.to.ch; + } + return len; + } - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function(line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(found, 1); } -}); -BI.TextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.text_icon_node", BI.TextIconNode);/** - * guy - * - * Created by GUY on 2015/9/9. - * @class BI.TextNode - * @extends BI.NodeButton - */ -BI.TextNode = BI.inherit(BI.NodeButton, { + } - _defaultConfig: function () { - var conf = BI.TextNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-node", - textAlign: "left", - whiteSpace: "nowrap", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }) - }, - _init: function () { - BI.TextNode.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, - height: o.height, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - }, + // SCROLLBARS - doClick: function () { - BI.TextNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextNode.EVENT_CHANGE, this.getValue(), this); - } - }, + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth; + var docH = Math.round(cm.doc.height + paddingVert(cm.display)); + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + }; + } - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, + function NativeScrollbars(place, scroll, cm) { + this.cm = cm; + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + place(vert); place(horiz); - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, + on(vert, "scroll", function() { + if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); + }); + on(horiz, "scroll", function() { + if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); + }); - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, + this.checkedOverlay = false; + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; + } - getValue: function () { - return this.text.getValue(); - }, + NativeScrollbars.prototype = copyObj({ + update: function(measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + var sWidth = measure.nativeBarWidth; - setText: function () { - this.text.setText.apply(this.text, arguments); - }, + if (needsV) { + this.vert.style.display = "block"; + this.vert.style.bottom = needsH ? sWidth + "px" : "0"; + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; + } else { + this.vert.style.display = ""; + this.vert.firstChild.style.height = "0"; + } - getText: function () { - return this.text.getText(); - } -}); -BI.TextNode.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.text_node", BI.TextNode);/** - * - * Created by GUY on 2016/1/15. - * @class BI.CodeEditor - * @extends BI.Single - */ -BI.CodeEditor = BI.inherit(BI.Single, { - _defaultConfig: function () { - return $.extend(BI.CodeEditor.superclass._defaultConfig.apply(), { - baseCls: 'bi-code-editor', - value: '', - watermark: "" - }); - }, - _init: function () { - BI.CodeEditor.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.editor = CodeMirror(this.element[0], { - textWrapping: true, - lineWrapping: true, - lineNumbers: false - }); - this.editor.on("change", function (cm, change) { - BI.nextTick(function () { - self.fireEvent(BI.CodeEditor.EVENT_CHANGE) - }); - }); + if (needsH) { + this.horiz.style.display = "block"; + this.horiz.style.right = needsV ? sWidth + "px" : "0"; + this.horiz.style.left = measure.barLeft + "px"; + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); + this.horiz.firstChild.style.width = + (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; + } else { + this.horiz.style.display = ""; + this.horiz.firstChild.style.width = "0"; + } - this.editor.on("focus", function () { - watermark.setVisible(false); - self.fireEvent(BI.CodeEditor.EVENT_FOCUS); - }); + if (!this.checkedOverlay && measure.clientHeight > 0) { + if (sWidth == 0) this.overlayHack(); + this.checkedOverlay = true; + } - this.editor.on("blur", function () { - watermark.setVisible(BI.isEmptyString(self.getValue())); - self.fireEvent(BI.CodeEditor.EVENT_BLUR); - }); + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}; + }, + setScrollLeft: function(pos) { + if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; + }, + setScrollTop: function(pos) { + if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; + }, + overlayHack: function() { + var w = mac && !mac_geMountainLion ? "12px" : "18px"; + this.horiz.style.minHeight = this.vert.style.minWidth = w; + var self = this; + var barMouseDown = function(e) { + if (e_target(e) != self.vert && e_target(e) != self.horiz) + operation(self.cm, onMouseDown)(e); + }; + on(this.vert, "mousedown", barMouseDown); + on(this.horiz, "mousedown", barMouseDown); + }, + clear: function() { + var parent = this.horiz.parentNode; + parent.removeChild(this.horiz); + parent.removeChild(this.vert); + } + }, NativeScrollbars.prototype); - // this.editor.on("blur", function () { - // self.editor.execCommand("goLineEnd"); - // }); + function NullScrollbars() {} - //水印 - var watermark = BI.createWidget({ - type: "bi.label", - text: o.watermark, - cls: "bi-water-mark", - whiteSpace: "nowrap", - textAlign: "left" - }); - watermark.element.bind( - "mousedown", function (e) { - self.insertString(""); - self.editor.focus(); - e.stopEvent(); - } - ); - watermark.element.bind("click", function (e) { - self.editor.focus(); - e.stopEvent(); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: watermark, - top: 0, - left: 5 - }] - }); + NullScrollbars.prototype = copyObj({ + update: function() { return {bottom: 0, right: 0}; }, + setScrollLeft: function() {}, + setScrollTop: function() {}, + clear: function() {} + }, NullScrollbars.prototype); - if (BI.isKey(o.value)) { - BI.nextTick(function () { - self.setValue(o.value); - }); - } - }, + CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; - setEnable: function (b) { - BI.CodeEditor.superclass.setEnable.apply(this, arguments); - this.editor.setOption("readOnly", b === true ? false : "nocursor") - }, + function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear(); + if (cm.display.scrollbars.addClass) + rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } - insertParam: function(param){ - var from = this.editor.getCursor(); - this.editor.replaceSelection(param); - var to = this.editor.getCursor(); - this.editor.markText(from, to, {className: 'param', atomic: true}); - this.editor.replaceSelection(" "); - this.editor.focus(); - }, + cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function() { + if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0); + }); + node.setAttribute("cm-not-content", "true"); + }, function(pos, axis) { + if (axis == "horizontal") setScrollLeft(cm, pos); + else setScrollTop(cm, pos); + }, cm); + if (cm.display.scrollbars.addClass) + addClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } - insertString: function(str){ - this.editor.replaceSelection(str); - this.editor.focus(); - }, + function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm); + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; + updateScrollbarsInner(cm, measure); + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + updateHeightsInViewport(cm); + updateScrollbarsInner(cm, measureForScrollbars(cm)); + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; + } + } - getValue: function () { - return this.editor.getValue("\n", function (line) { - var rawText = line.text, value = line.text, num = 0; - value.text = rawText; - _.forEach(line.markedSpans, function (i, ms) { - switch (i.marker.className) { - case "param": - var fieldNameLength = i.to - i.from; - value = value.substr(0, i.from + num) + "$\{" + value.substr(i.from + num, fieldNameLength) + "\}" + value.substr(i.to + num, value.length); - num += fieldNameLength + 3; - break; - } - }); - return value; - }); - }, + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbarsInner(cm, measure) { + var d = cm.display; + var sizes = d.scrollbars.update(measure); - _analyzeContent: function (v) { - var regx = /\$[\{][^\}]*[\}]|\w*\w|\$\{[^\$\(\)\+\-\*\/)\$,]*\w\}|\$\{[^\$\(\)\+\-\*\/]*\w\}|\$\{[^\$\(\)\+\-\*\/]*[\u4e00-\u9fa5]\}|\w|(.)|\n/g; - return v.match(regx); - }, + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; - setValue: function (v) { - var self = this, result; - this.refresh(); - self.editor.setValue(""); - result = this._analyzeContent(v || ""); - BI.each(result, function (i, item) { - var fieldRegx = /\$[\{][^\}]*[\}]/; - var str = item.match(fieldRegx); - if (BI.isNotEmptyArray(str)) { - self.insertParam(str[0].substring(2, item.length - 1)); - } else { - self.insertString(item); - } - }) - }, + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = sizes.bottom + "px"; + d.scrollbarFiller.style.width = sizes.right + "px"; + } else d.scrollbarFiller.style.display = ""; + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = sizes.bottom + "px"; + d.gutterFiller.style.width = measure.gutterWidth + "px"; + } else d.gutterFiller.style.display = ""; + } - refresh: function(){ - var self = this; - BI.nextTick(function () { - self.editor.refresh(); - }); + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewport may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; + if (ensureFrom < from) { + from = ensureFrom; + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); + to = ensureTo; + } } -}); -BI.CodeEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.CodeEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.CodeEditor.EVENT_FOCUS = "EVENT_FOCUS"; -$.shortcut("bi.code_editor", BI.CodeEditor);/** - * Created by GUY on 2015/4/15. - * @class BI.Editor - * @extends BI.Single - */ -BI.Editor = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Editor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - tipType: "warning", - inputType: "text", - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - mouseOut: false, - allowBlank: false, - watermark: "", - errorText: "" - }) - }, - - _init: function () { - BI.Editor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = this.addWidget(BI.createWidget({ - type: "bi.input", - element: "", - watermark: o.watermark, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - mouseOut: o.mouseOut, - allowBlank: o.allowBlank - })); - this.editor.element.css({ - "width": "100%", - "height": "100%", - "border": "none", - "outline": "none", - "padding": "0", - "margin": "0" - }); - if (BI.isKey(this.options.watermark)) { - this.watermark = BI.createWidget({ - type: "bi.label", - cls: "bi-water-mark", - text: this.options.watermark, - forceCenter: true, - whiteSpace: "nowrap", - textAlign: "left" - }); - this.watermark.element.bind({ - mousedown: function (e) { - if (self.isEnabled()) { - self.editor.isEditing() || self.editor.focus(); - } else { - self.editor.isEditing() && self.editor.blur(); - } - e.stopEvent(); - } - }); - this.watermark.element.bind("click", function (e) { - if (self.isEnabled()) { - self.editor.isEditing() || self.editor.focus(); - } else { - self.editor.isEditing() && self.editor.blur(); - } - e.stopEvent(); - }); - this.watermark.element.css({ - position: "absolute", - left: "3px", - right: "3px", - top: "0px", - bottom: "0px" - }); - } - var items = [{ - el: { - type: "bi.default", - items: this.watermark ? [this.editor, this.watermark] : [this.editor] - }, - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - }]; + return {from: from, to: Math.max(to, from + 1)}; + } - BI.createWidget({ - type: "bi.absolute", - element: this, - items: items - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Input.EVENT_FOCUS, function () { - self._checkError(); - self.element.addClass("bi-editor-focus"); - self.fireEvent(BI.Editor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Input.EVENT_BLUR, function () { - self.setErrorVisible(false); - self.element.removeClass("bi-editor-focus"); - self.fireEvent(BI.Editor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Input.EVENT_CLICK, function () { - self.fireEvent(BI.Editor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Input.EVENT_CHANGE, function () { - self.fireEvent(BI.Editor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Input.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.Editor.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.Input.EVENT_QUICK_DOWN, function (v) { - self.watermark && self.watermark.invisible(); - }); + // LINE NUMBERS - this.editor.on(BI.Input.EVENT_VALID, function () { - self._checkWaterMark(); - self.setErrorVisible(false); - self.fireEvent(BI.Editor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Input.EVENT_ERROR, function () { - self._checkWaterMark(); - self.fireEvent(BI.Editor.EVENT_ERROR, arguments); - self.setErrorVisible(self.isEditing()); - }); - this.editor.on(BI.Input.EVENT_RESTRICT, function () { - self._checkWaterMark(); - var tip = self.setErrorVisible(true); - tip && tip.element.fadeOut(100, function () { - tip.element.fadeIn(100); - }); - self.fireEvent(BI.Editor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Input.EVENT_EMPTY, function () { - self._checkWaterMark(); - self.fireEvent(BI.Editor.EVENT_EMPTY, arguments); - }); - this.editor.on(BI.Input.EVENT_ENTER, function () { - self.fireEvent(BI.Editor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Input.EVENT_SPACE, function () { - self.fireEvent(BI.Editor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Input.EVENT_BACKSPACE, function () { - self.fireEvent(BI.Editor.EVENT_BACKSPACE, arguments); - }); - this.editor.on(BI.Input.EVENT_REMOVE, function () { - self.fireEvent(BI.Editor.EVENT_REMOVE, arguments); - }); - this.editor.on(BI.Input.EVENT_START, function () { - self.fireEvent(BI.Editor.EVENT_START, arguments); - }); - this.editor.on(BI.Input.EVENT_PAUSE, function () { - self.fireEvent(BI.Editor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Input.EVENT_STOP, function () { - self.fireEvent(BI.Editor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Input.EVENT_CONFIRM, function () { - self.fireEvent(BI.Editor.EVENT_CONFIRM, arguments); - }); - this.element.click(function (e) { - e.stopPropagation(); - return false; - }); - if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { - this.setValue(this.options.value); - } else { - this._checkWaterMark(); - } - }, + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter && view[i].gutter) + view[i].gutter.style.left = left; + var align = view[i].alignable; + if (align) for (var j = 0; j < align.length; j++) + align[j].style.left = left; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } - _checkToolTip: function () { - var o = this.options; - var errorText = o.errorText; - if (BI.isFunction(errorText)) { - errorText = errorText(this.editor.getValue()); - } - if (BI.isKey(errorText)) { - if (!this.isEnabled() || this.isValid() || (BI.Bubbles.has(this.getName()) && BI.Bubbles.get(this.getName()).isVisible())) { - this.setTitle(""); - } else { - this.setTitle(errorText); - } - } - }, + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + updateGutterSpace(cm); + return true; + } + return false; + } - _checkError: function () { - this.setErrorVisible(this.isEnabled() && !this.isValid()); - this._checkToolTip(); - }, + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } - _checkWaterMark: function () { - var o = this.options; - if (!this.disabledWarterMark && this.editor.getValue() === "" && BI.isKey(o.watermark)) { - this.watermark && this.watermark.visible(); - } else { - this.watermark && this.watermark.invisible(); - } - }, + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; + } - setErrorText: function (text) { - this.options.errorText = text; - }, + // DISPLAY DRAWING - getErrorText: function () { - return this.options.errorText; - }, + function DisplayUpdate(cm, viewport, force) { + var display = cm.display; - setErrorVisible: function (b) { - var o = this.options; - var errorText = o.errorText; - if (BI.isFunction(errorText)) { - errorText = errorText(this.editor.getValue()); - } - if (!this.disabledError && BI.isKey(errorText)) { - BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this); - this._checkToolTip(); - return BI.Bubbles.get(this.getName()); - } - }, + this.viewport = viewport; + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport); + this.editorIsHidden = !display.wrapper.offsetWidth; + this.wrapperHeight = display.wrapper.clientHeight; + this.wrapperWidth = display.wrapper.clientWidth; + this.oldDisplayWidth = displayWidth(cm); + this.force = force; + this.dims = getDimensions(cm); + this.events = []; + } - disableError: function () { - this.disabledError = true; - this._checkError(); - }, + DisplayUpdate.prototype.signal = function(emitter, type) { + if (hasHandler(emitter, type)) + this.events.push(arguments); + }; + DisplayUpdate.prototype.finish = function() { + for (var i = 0; i < this.events.length; i++) + signal.apply(null, this.events[i]); + }; - enableError: function () { - this.disabledError = false; - this._checkError(); - }, + function maybeClipScrollbars(cm) { + var display = cm.display; + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; + display.heightForcer.style.height = scrollGap(cm) + "px"; + display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; + display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; + display.scrollbarsClipped = true; + } + } - disableWarterMark: function () { - this.disabledWarterMark = true; - this._checkWaterMark(); - }, + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc; - enableWarterMark: function () { - this.disabledWarterMark = false; - this._checkWaterMark(); - }, + if (update.editorIsHidden) { + resetView(cm); + return false; + } - focus: function () { - this.element.addClass("text-editor-focus"); - this.editor.focus(); - }, + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + return false; - blur: function () { - this.element.removeClass("text-editor-focus"); - this.editor.blur(); - }, + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm); + update.dims = getDimensions(cm); + } - selectAll: function () { - this.editor.selectAll(); - }, + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, update.visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } - onKeyDown: function (k) { - this.editor.onKeyDown(k); - }, + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; + adjustView(cm, from, to); - setValue: function (v) { - BI.Editor.superclass.setValue.apply(this, arguments); - this.editor.setValue(v); - this._checkError(); - this._checkWaterMark(); - }, + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; - getLastValidValue: function () { - return BI.trim(this.editor.getLastValidValue()); - }, + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + return false; - resetLastValidValue: function () { - this.editor.resetLastValidValue(); - }, + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var focused = activeElt(); + if (toUpdate > 4) display.lineDiv.style.display = "none"; + patchDisplay(cm, display.updateLineNumbers, update.dims); + if (toUpdate > 4) display.lineDiv.style.display = ""; + display.renderedView = display.view; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); - getValue: function () { - if (!this.isValid()) { - return BI.trim(this.editor.getLastValidValue()); - } - return BI.trim(this.editor.getValue()); - }, + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + display.gutters.style.height = 0; - setValid: function (b) { - BI.Editor.superclass.setValid.apply(this, arguments); - this.editor.setValid(b); - }, + if (different) { + display.lastWrapHeight = update.wrapperHeight; + display.lastWrapWidth = update.wrapperWidth; + startWorker(cm, 400); + } - isEditing: function () { - return this.editor.isEditing(); - }, + display.updateLineNumbers = null; - isValid: function () { - return this.editor.isValid(); - }, + return true; + } - setEnable: function (b) { - BI.Editor.superclass.setEnable.apply(this, arguments); - this.editor && this.editor.setEnable(b); - this.watermark && this.watermark.setEnable(b); + function postUpdateDisplay(cm, update) { + var viewport = update.viewport; + for (var first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport); + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + break; + } + if (!updateDisplayIfNeeded(cm, update)) break; + updateHeightsInViewport(cm); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + setDocumentHeight(cm, barMeasure); + updateScrollbars(cm, barMeasure); } -}); -BI.Editor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Editor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.Editor.EVENT_BLUR = "EVENT_BLUR"; -BI.Editor.EVENT_CLICK = "EVENT_CLICK"; -BI.Editor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.Editor.EVENT_SPACE = "EVENT_SPACE"; -BI.Editor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; -BI.Editor.EVENT_START = "EVENT_START"; -BI.Editor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Editor.EVENT_STOP = "EVENT_STOP"; -BI.Editor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.Editor.EVENT_VALID = "EVENT_VALID"; -BI.Editor.EVENT_ERROR = "EVENT_ERROR"; -BI.Editor.EVENT_ENTER = "EVENT_ENTER"; -BI.Editor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.Editor.EVENT_REMOVE = "EVENT_REMOVE"; -BI.Editor.EVENT_EMPTY = "EVENT_EMPTY"; + update.signal(cm, "update", cm); + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; + } + } -$.shortcut("bi.editor", BI.Editor);/** - * 多文件 - * - * Created by GUY on 2016/4/13. - * @class BI.MultifileEditor - * @extends BI.Single - * @abstract - */ -BI.MultifileEditor = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.MultifileEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-multifile-editor", - multiple: false, - maxSize: 1024 * 1024, - accept: "", - url: "" - }) - }, + function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport); + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm); + postUpdateDisplay(cm, update); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + setDocumentHeight(cm, barMeasure); + updateScrollbars(cm, barMeasure); + update.finish(); + } + } - _init: function () { - var self = this, o = this.options; - BI.MultifileEditor.superclass._init.apply(this, arguments); - this.file = BI.createWidget({ - type: "bi.file", - cls: "multifile-editor", - width: "100%", - height: "100%", - name: o.name, - url: o.url, - multiple: o.multiple, - accept: o.accept, - maxSize: o.maxSize - }); - this.file.on(BI.File.EVENT_CHANGE, function () { - self.fireEvent(BI.MultifileEditor.EVENT_CHANGE, arguments); - }); - this.file.on(BI.File.EVENT_UPLOADSTART, function () { - self.fireEvent(BI.MultifileEditor.EVENT_UPLOADSTART, arguments); - }); - this.file.on(BI.File.EVENT_ERROR, function () { - self.fireEvent(BI.MultifileEditor.EVENT_ERROR, arguments); - }); - this.file.on(BI.File.EVENT_PROGRESS, function () { - self.fireEvent(BI.MultifileEditor.EVENT_PROGRESS, arguments); - }); - this.file.on(BI.File.EVENT_UPLOADED, function () { - self.fireEvent(BI.MultifileEditor.EVENT_UPLOADED, arguments); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.adaptive", - scrollable: false, - items: [this.file] - }, - top: 0, - right: 0, - left: 0, - bottom: 0 - }] - }); - }, + function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px"; + var total = measure.docHeight + cm.display.barHeight; + cm.display.heightForcer.style.top = total + "px"; + cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px"; + } - select: function () { - this.file.select(); - }, + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height; + if (cur.hidden) continue; + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + } + var diff = cur.line.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) for (var j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]); + } + } + } - getValue: function () { - return this.file.getValue(); - }, + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) + line.widgets[i].height = line.widgets[i].node.offsetHeight; + } - upload: function () { - this.file.upload(); - }, + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + var gutterLeft = d.gutters.clientLeft; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; + width[cm.options.gutters[i]] = n.clientWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth}; + } - reset: function () { - this.file.reset(); - }, + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; - setEnable: function (enable) { - BI.MultiFile.superclass.setEnable.apply(this, arguments); - this.file.setEnable(enable); + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none"; + else + node.parentNode.removeChild(node); + return next; } -}); -BI.MultifileEditor.EVENT_CHANGE = "MultifileEditor.EVENT_CHANGE"; -BI.MultifileEditor.EVENT_UPLOADSTART = "MultifileEditor.EVENT_UPLOADSTART"; -BI.MultifileEditor.EVENT_ERROR = "MultifileEditor.EVENT_ERROR"; -BI.MultifileEditor.EVENT_PROGRESS = "MultifileEditor.EVENT_PROGRESS"; -BI.MultifileEditor.EVENT_UPLOADED = "MultifileEditor.EVENT_UPLOADED"; -$.shortcut("bi.multifile_editor", BI.MultifileEditor);/** - * - * Created by GUY on 2016/1/18. - * @class BI.TextAreaEditor - * @extends BI.Single - */ -BI.TextAreaEditor = BI.inherit(BI.Single, { - _defaultConfig: function () { - return $.extend(BI.TextAreaEditor.superclass._defaultConfig.apply(), { - baseCls: 'bi-textarea-editor', - value: '' - }); - }, - _init: function () { - BI.TextAreaEditor.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.content = BI.createWidget({ - type: "bi.layout", - tagName: "textarea", - width: "100%", - height: "100%", - cls: "textarea-editor-content display-block" - }); - this.content.element.css({"resize": "none"}); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.adaptive", - items: [this.content] - }, - left: 0, - right: 3, - top: 0, - bottom: 5 - }] - }); - this.content.element.focus(function () { - self.content.element.addClass("textarea-editor-focus"); - self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); - }); - this.content.element.blur(function () { - self.content.element.removeClass("textarea-editor-focus"); - self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); - }); - if (BI.isKey(o.value)) { - self.setValue(o.value); + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur); + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; + updateLineForChanges(cm, lineView, lineN, dims); } - }, - - focus: function () { - this.content.element.addClass("textarea-editor-focus"); - this.content.element.focus(); - }, + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) cur = rm(cur); + } - blur: function () { - this.content.element.removeClass("textarea-editor-focus"); - this.content.element.blur(); - }, + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") updateLineText(cm, lineView); + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); + else if (type == "class") updateLineClasses(lineView); + else if (type == "widget") updateLineWidgets(cm, lineView, dims); + } + lineView.changes = null; + } - getValue: function () { - return this.content.element.val(); - }, + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text); + lineView.node.appendChild(lineView.text); + if (ie && ie_version < 8) lineView.node.style.zIndex = 2; + } + return lineView.node; + } - setValue: function (value) { - this.content.element.val(value); - }, + function updateLineBackground(lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) cls += " CodeMirror-linebackground"; + if (lineView.background) { + if (cls) lineView.background.className = cls; + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + } + } - setStyle: function (style) { - this.style = style; - this.element.css(style); - this.content.element.css(style) - }, + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built; + } + return buildLineContent(cm, lineView); + } - getStyle: function () { - return this.style; - }, + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) lineView.node = built.pre; + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(lineView); + } else if (cls) { + lineView.text.className = cls; + } + } - setValid: function (b) { - BI.TextAreaEditor.superclass.setValid.apply(this, arguments); - this.content.setValid(b); - }, + function updateLineClasses(lineView) { + updateLineBackground(lineView); + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass; + else if (lineView.node != lineView.text) + lineView.node.className = ""; + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } - setEnable: function (b) { - BI.TextAreaEditor.superclass.setEnable.apply(this, arguments); - this.content.setEnable(b); + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; } -}); -BI.TextAreaEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.TextAreaEditor.EVENT_FOCUS = "EVENT_FOCUS"; -$.shortcut("bi.textarea_editor", BI.TextAreaEditor);/** - * guy 图标 - * @class BI.Icon - * @extends BI.Single - */ -BI.Icon = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Icon.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - tagName: "i", - baseCls: (conf.baseCls || "") + " x-icon b-font horizon-center display-block" - }) - }, - _init: function () { - BI.Icon.superclass._init.apply(this, arguments); + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + + "px; width: " + dims.gutterTotalWidth + "px"); + cm.display.input.setUneditable(gutterWrap); + wrap.insertBefore(gutterWrap, lineView.text); + if (lineView.line.gutterClass) + gutterWrap.className += " " + lineView.line.gutterClass; + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + cm.display.lineNumInnerWidth + "px")); + if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); + } } -}); -$.shortcut("bi.icon", BI.Icon);/** - * @class BI.Iframe - * @extends BI.Single - * @abstract - * Created by GameJian on 2016/3/2. - */ -BI.Iframe = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Iframe.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-iframe", - src: "", - width: "100%", - height: "100%" - }) - }, + } - _init: function () { - var o = this.options; - this.options.element = $("')); - } catch (e) { - var form = document.createElement('form'), - iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); - form.setAttribute("enctype", "multipart/form-data"); - iframe.setAttribute("name", iframe.id = target); - iframe.setAttribute("src", url); - } - ; - iframe.style.position = "absolute"; - iframe.style.left = iframe.style.top = "-10000px"; - iframe.onload = onload; - iframe.onerror = function (event) { - if (isFunction(handler.onerror)) - handler.onerror(rpe, event || window.event); - }; - iframe.onreadystatechange = function () { - if (/loaded|complete/i.test(iframe.readyState)) { - onload(); + function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) return; + var sel = cm.doc.sel; - //wei : todo,将附件信息放到handler.attach - } - else if (isFunction(handler.onloadprogress)) { - if (rpe.loaded < rpe.total) - ++rpe.loaded; - handler.onloadprogress(rpe, { - readyState: { - loading: 2, - interactive: 3, - loaded: 4, - complete: 4 - }[iframe.readyState] || 1 - }); - } - }; - form.setAttribute("action", handler.url + '&width=' + width + '&height=' + height); - form.setAttribute("target", iframe.id); - form.setAttribute("method", "post"); - form.appendChild(handler.file); - form.style.display = "none"; - if (isFunction(handler.onloadstart)) - handler.onloadstart(rpe, {}); - with (document.body || document.documentElement) { - appendChild(iframe); - appendChild(form); - form.submit(); - } - ; - return handler; - }; - xhr = null; - return sendFile; - })(Object.prototype.toString); + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; + var mode = cm.getModeAt(range.head); + var indented = false; + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart"); + break; + } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + indented = indentLine(cm, range.head.line, "smart"); + } + if (indented) signalLater(cm, "electricInput", cm, range.head.line); + } + } - var sendFiles = function (handler, maxSize, width, height) { + function copyableRanges(cm) { + var text = [], ranges = []; + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line; + var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; + ranges.push(lineRange); + text.push(cm.getRange(lineRange.anchor, lineRange.head)); + } + return {text: text, ranges: ranges}; + } - var length = handler.files.length, - i = 0, - onload = handler.onload, - onloadstart = handler.onloadstart; - handler.current = 0; - handler.total = 0; - handler.sent = 0; - while (handler.current < length) { - handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); - handler.current++; - } - handler.current = 0; - if (length && handler.files[0].fileSize !== -1) { - handler.file = handler.files[handler.current]; + function disableBrowserMagic(field) { + field.setAttribute("autocorrect", "off"); + field.setAttribute("autocapitalize", "off"); + field.setAttribute("spellcheck", "false"); + } - sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { - handler.onloadstart = null; - handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); - if (++handler.current < length) { - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = arguments.callee; - } else if (onload) { - handler.onloadstart = onloadstart; - handler.onload = onload; - handler.onload(rpe, xhr); - } - }; - } else if (length) { - handler.total = length * 100; - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { - var callee = arguments.callee; - handler.onloadstart = null; - handler.sent += 100; - if (++handler.current < length) { - if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { - handler.iframe.parentNode.removeChild(handler.iframe); - handler.iframe = null; - } - ; - setTimeout(function () { - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = callee; - }, 15); - } else if (onload) { - setTimeout(function () { - handler.iframe.parentNode.removeChild(handler.iframe); - handler.iframe = null; - handler.onloadstart = onloadstart; - handler.onload = onload; - handler.onload(rpe, xhr); - }, 15); - } - }; - } - return handler; - }; + // TEXTAREA INPUT STYLE - BI.File = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.File.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-file display-block", - element: "", - name: "", - url: "", - multiple: true, - accept: "", /**'*.jpg; *.zip'**/ - maxSize: 1024 * 1024 - }) - }, + function TextareaInput(cm) { + this.cm = cm; + // See input.poll and input.reset + this.prevInput = ""; - _init: function () { - var self = this, o = this.options; - BI.File.superclass._init.apply(this, arguments); - if (o.multiple === true) { - this.element.attr("multiple", "multiple"); - } - this.element.attr("name", o.name || this.getName()); + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false; + // Self-resetting timeout for the poller + this.polling = new Delayed(); + // Tracks when input.reset has punted to just putting a short + // string into the textarea instead of the full selection. + this.inaccurateSelection = false; + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false; + this.composing = null; + }; - BI.nextTick(function () { - // create the noswfupload.wrap Object - // wrap.maxSize 文件大小限制 - // wrap.maxlength 文件个数限制 - var _wrap = self.wrap = self._wrap(self.element[0], o.maxSize); - // fileType could contain whatever text but filter checks *.{extension} - // if present + function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) te.style.width = "1000px"; + else te.setAttribute("wrap", "off"); + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) te.style.border = "1px solid black"; + disableBrowserMagic(te); + return div; + } - // handlers + TextareaInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = this.cm; - _wrap.onloadstart = function (rpe, xhr) { - //BI.Msg.toast("loadstart"); - self.fireEvent(BI.File.EVENT_UPLOADSTART); - }; + // Wraps and hides input textarea + var div = this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var te = this.textarea = div.firstChild; + display.wrapper.insertBefore(div, display.wrapper.firstChild); - _wrap.onprogress = function (rpe, xhr) { - //BI.Msg.toast("onprogress"); - // percent for each bar + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) te.style.width = "0px"; - // fileSize is -1 only if browser does not support file info access - // this if splits recent browsers from others - if (this.file.fileSize !== -1) { - // simulation property indicates when the progress event is fake - if (rpe.simulation) { + on(te, "input", function() { + if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; + input.poll(); + }); - } else { + on(te, "paste", function(e) { + if (handlePaste(e, cm)) return true; - } - } else { - // if fileSIze is -1 browser is using an iframe because it does - // not support - // files sent via Ajax (XMLHttpRequest) - // We can still show some information - } - self.fireEvent(BI.File.EVENT_PROGRESS, { - file: this.file, - total: rpe.total, - loaded: rpe.loaded, - simulation: rpe.simulation - }); - }; + cm.state.pasteIncoming = true; + input.fastPoll(); + }); - // generated if there is something wrong during upload - _wrap.onerror = function () { - // just inform the user something was wrong - self.fireEvent(BI.File.EVENT_ERROR); - }; + function prepareCopyCut(e) { + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (input.inaccurateSelection) { + input.prevInput = ""; + input.inaccurateSelection = false; + te.value = lastCopied.join("\n"); + selectInput(te); + } + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll); + } else { + input.prevInput = ""; + te.value = ranges.text.join("\n"); + selectInput(te); + } + } + if (e.type == "cut") cm.state.cutIncoming = true; + } + on(te, "cut", prepareCopyCut); + on(te, "copy", prepareCopyCut); - // generated when every file has been sent (one or more, it does not - // matter) - _wrap.onload = function (rpe, xhr) { - var self_ = this; - // just show everything is fine ... - // ... and after a second reset the component - setTimeout(function () { - self_.clean(); // remove files from list - self_.hide(); // hide progress bars and enable input file + on(display.scroller, "paste", function(e) { + if (eventInWidget(display, e)) return; + cm.state.pasteIncoming = true; + input.focus(); + }); - //BI.Msg.toast("onload"); - self.fireEvent(BI.File.EVENT_UPLOADED); - // enable again the submit button/element - }, 1000); - }; - _wrap.url = o.url ? o.url : BI.servletURL - + '?op=fr_attach&cmd=ah_upload'; - _wrap.fileType = o.accept; //文件类型限制 - _wrap.attach_array = []; - _wrap.attach_names = []; - _wrap.attachNum = 0; - }); - }, + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function(e) { + if (!eventInWidget(display, e)) e_preventDefault(e); + }); - _events: function (wrap) { - var self = this; - event.add(wrap.dom.input, "change", function () { - event.del(wrap.dom.input, "change", arguments.callee); - for (var input = wrap.dom.input.cloneNode(true), i = 0, files = F(wrap.dom.input); i < files.length; i++) { - var item = files.item(i); - var tempFile = item.value || item.name; - var value = item.fileName || (item.fileName = tempFile.split("\\").pop()), - ext = -1 !== value.indexOf(".") ? value.split(".").pop().toLowerCase() : "unknown", - size = item.fileSize || item.size; - if (wrap.fileType && -1 === wrap.fileType.indexOf("*." + ext)) { - //文件类型不支持 - BI.Msg.toast("文件类型不支持"); - self.fireEvent(BI.File.EVENT_ERROR, { - errorType: 0, - file: item - }); - } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { - //文件大小不支持 - BI.Msg.toast("文件大小不支持"); - self.fireEvent(BI.File.EVENT_ERROR, { - errorType: 1, - file: item - }); - } else { - wrap.files.unshift(item); - //BI.Msg.toast(value); - self.fireEvent(BI.File.EVENT_CHANGE, { - file: item - }); - } - } - input.value = ""; - wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); - wrap.dom.input = input; - event.add(wrap.dom.input, "change", arguments.callee); - }); - return wrap; - }, + on(te, "compositionstart", function() { + var start = cm.getCursor("from"); + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + }; + }); + on(te, "compositionend", function() { + if (input.composing) { + input.poll(); + input.composing.range.clear(); + input.composing = null; + } + }); + }, - _wrap: function () { - var self = this, o = this.options; - // be sure input accept multiple files - var input = this.element[0]; - this.element.attr("multiple", "multiple"); - input.value = ""; + prepareSelection: function() { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc; + var result = prepareSelection(cm); - // wrap Object - return this._events({ + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + } - // DOM namespace - dom: { - input: input, // input file - disabled: false // internal use, checks input file state - }, - name: input.name, // name to send for each file ($_FILES[{name}] in the server) - // maxSize is the maximum amount of bytes for each file - maxSize: o.maxSize ? o.maxSize >> 0 : -1, - files: [], // file list + return result; + }, - // remove every file from the noswfupload component - clean: function () { - this.files = []; - }, + showSelection: function(drawn) { + var cm = this.cm, display = cm.display; + removeChildrenAndAdd(display.cursorDiv, drawn.cursors); + removeChildrenAndAdd(display.selectionDiv, drawn.selection); + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px"; + this.wrapper.style.left = drawn.teLeft + "px"; + } + }, - // upload one file a time (which make progress possible rather than all files in one shot) - // the handler is an object injected into the wrap one, could be the wrap itself or - // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} - upload: function (handler) { - if (handler) { - for (var key in handler) - this[key] = handler[key]; - } - sendFiles(this, this.maxSize); - return this; - }, + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + reset: function(typing) { + if (this.contextMenuPending) return; + var minimal, selected, cm = this.cm, doc = cm.doc; + if (cm.somethingSelected()) { + this.prevInput = ""; + var range = doc.sel.primary(); + minimal = hasCopyEvent && + (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + this.textarea.value = content; + if (cm.state.focused) selectInput(this.textarea); + if (ie && ie_version >= 9) this.hasSelection = content; + } else if (!typing) { + this.prevInput = this.textarea.value = ""; + if (ie && ie_version >= 9) this.hasSelection = null; + } + this.inaccurateSelection = minimal; + }, - // hide progress bar (total + current) and enable files selection - hide: function () { - if (this.dom.disabled) { - this.dom.disabled = false; - this.dom.input.removeAttribute("disabled"); - } - }, + getField: function() { return this.textarea; }, - // show progress bar and disable file selection (used during upload) - // total and current are pixels used to style bars - // totalProp and currentProp are properties to change, "height" by default - show: function (total, current, totalProp, currentProp) { - if (!this.dom.disabled) { - this.dom.disabled = true; - this.dom.input.setAttribute("disabled", "disabled"); - } - } - }); - }, + supportsTouch: function() { return false; }, - select: function () { - $(this.wrap.dom.input).click(); - }, + focus: function() { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus(); } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } + }, - upload: function (handler) { - this.wrap.upload(handler); - }, + blur: function() { this.textarea.blur(); }, - getValue: function () { - return this.wrap.attach_array; - }, + resetPosition: function() { + this.wrapper.style.top = this.wrapper.style.left = 0; + }, - reset: function () { - this.wrap.attach_array = []; - this.wrap.attach_names = []; - this.wrap.attachNum = 0; - }, + receivedFocus: function() { this.slowPoll(); }, - setEnable: function (enable) { - BI.MultiFile.superclass.setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("disabled", "disabled"); - } else { - this.element.removeAttr("disabled"); - } - } - }); - BI.File.EVENT_CHANGE = "BI.File.EVENT_CHANGE"; - BI.File.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; - BI.File.EVENT_ERROR = "EVENT_ERROR"; - BI.File.EVENT_PROGRESS = "EVENT_PROGRESS"; - BI.File.EVENT_UPLOADED = "EVENT_UPLOADED"; - $.shortcut("bi.file", BI.File); -})();/** - * guy - * @class BI.Input 一个button和一行数 组成的一行listitem - * @extends BI.Single - * @type {*|void|Object} - */ -BI.Input = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-input display-block", - element: "", - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn,//按确定键能否退出编辑 - mouseOut: false, - allowBlank: false - }) - }, - - _init: function () { - BI.Input.superclass._init.apply(this, arguments); - var self = this; - var _keydown = BI.debounce(function (keyCode) { - self.onKeyDown(keyCode); - self._keydown_ = false; - }, 300); - var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, true); - this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, true); - this.element - .keydown(function (e) { - self.fireEvent(BI.Input.EVENT_QUICK_DOWN); - }) - .keyup(function (e) { - self._keydown_ = true; - _keydown(e.keyCode); - }) - .on("input propertychange", function (e) { - self._keydown_ = true; - _keydown(e.keyCode); - }) - .click(function (e) { - e.stopPropagation(); - _clk(); - }) - .mousedown(function (e) { - self.element.val(self.element.val()); - }) - .focusout(function (e) { - self._blurDebounce(); - }); + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + slowPoll: function() { + var input = this; + if (input.pollingFast) return; + input.polling.set(this.cm.options.pollInterval, function() { + input.poll(); + if (input.cm.state.focused) input.slowPoll(); + }); }, - _focus: function () { - this.element.addClass("bi-input-focus"); - this._checkValidationOnValueChange(); - this._isEditing = true; - if (this.getValue() == "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this.fireEvent(BI.Input.EVENT_FOCUS); + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + fastPoll: function() { + var missed = false, input = this; + input.pollingFast = true; + function p() { + var changed = input.poll(); + if (!changed && !missed) {missed = true; input.polling.set(60, p);} + else {input.pollingFast = false; input.slowPoll();} + } + input.polling.set(20, p); }, - _blur: function () { - var self = this; - if (self._keydown_ === true) { - BI.delay(blur, 300); - } else { - blur(); - } - function blur() { - if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { - self.element.val(self._lastValidValue ? self._lastValidValue : ""); - self._checkValidationOnValueChange(); - self._defaultState(); - } - self.element.removeClass("bi-input-focus"); - self._isEditing = false; - self._start = false; - if (self.isValid()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); - self.fireEvent(BI.Input.EVENT_CONFIRM); - } - self.fireEvent(BI.Input.EVENT_BLUR); - } - }, + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + poll: function() { + var cm = this.cm, input = this.textarea, prevInput = this.prevInput; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput) || + isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq) + return false; - _click: function () { - if (this._isEditing !== true) { - this._focus(); - this.selectAll(); - this.fireEvent(BI.Input.EVENT_CLICK); - } - }, + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false; + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset(); + return false; + } - onClick: function () { - this._click(); - }, + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0); + if (first == 0x200b && !prevInput) prevInput = "\u200b"; + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - onKeyDown: function (keyCode) { - if (!this.isValid() || BI.trim(this._lastValidValue) !== BI.trim(this.getValue())) { - this._checkValidationOnValueChange(); - } - if (keyCode == BI.keyCode.ENTER) { - if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { - this.blur(); - this.fireEvent(BI.Input.EVENT_ENTER); - } else { - this.fireEvent(BI.Input.EVENT_RESTRICT); - } - } - if (keyCode == BI.keyCode.SPACE) { - this.fireEvent(BI.Input.EVENT_SPACE); - } - if (keyCode == BI.keyCode.BACKSPACE && this._lastValue == "") { - this.fireEvent(BI.Input.EVENT_REMOVE); - } - if (keyCode == BI.keyCode.BACKSPACE || keyCode == BI.keyCode.DELETE) { - this.fireEvent(BI.Input.EVENT_BACKSPACE); - } - this.fireEvent(BI.Input.EVENT_KEY_DOWN); + var self = this; + runInOp(cm, function() { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, self.composing ? "*compose" : null); - if (this.isValid() && BI.trim(this.getValue()) !== "") { - if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") - || (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { - this._start = true; - this._pause = false; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_START); - } - } + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; + else self.prevInput = text; - if (/(\s|\u00A0)$/.test(this.getValue())) { - this._pause = true; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); - this.fireEvent(BI.Input.EVENT_PAUSE); - this._defaultState(); - } else if ((keyCode === BI.keyCode.BACKSPACE || keyCode === BI.keyCode.DELETE) && - BI.trim(this.getValue()) === "" && (this._lastValue !== null && BI.trim(this._lastValue) !== "")) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_STOP); - this._valueChange(); - } else { - this._valueChange(); + if (self.composing) { + self.composing.range.clear(); + self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}); } + }); + return true; }, - //初始状态 - _defaultState: function () { - if (this.getValue() == "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this._lastValue = this.getValue(); - this._lastSubmitValue = null; + ensurePolled: function() { + if (this.pollingFast && this.poll()) this.pollingFast = false; }, - _valueChange: function () { - if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_CHANGE); - this._lastSubmitValue = BI.trim(this.getValue()); - } - if (this.getValue() == "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this._lastValue = this.getValue(); + onKeyPress: function() { + if (ie && ie_version >= 9) this.hasSelection = null; + this.fastPoll(); }, - _checkValidationOnValueChange: function () { - var o = this.options; - var v = this.getValue(); - this.setValid( - (o.allowBlank === true && BI.trim(v) == "") || - (BI.isNotEmptyString(BI.trim(v)) - && (v === this._lastValidValue || - o.validationChecker.apply(this, [BI.trim(v)]) !== false)) - ); - }, + onContextMenu: function(e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea; + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) return; // Opera is difficult. - focus: function () { - if (!this.element.is(":visible")) { - throw new Error("input输入框在不可见下不能focus"); - } - if (!this._isEditing === true) { - this.element.focus(); - this._focus(); - this.selectAll(); - } - }, + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); - blur: function () { - if (!this.element.is(":visible")) { - throw new Error("input输入框在不可见下不能blur"); - } - if (this._isEditing === true) { - this.element.blur(); - this._blurDebounce(); + var oldCSS = te.style.cssText; + input.wrapper.style.position = "absolute"; + te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + + "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + + "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) + display.input.focus(); + if (webkit) window.scrollTo(null, oldScrollY); + display.input.reset(); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) te.value = input.prevInput = " "; + input.contextMenuPending = true; + display.selForContextMenu = cm.doc.sel; + clearTimeout(display.detectingSelectAll); + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected(); + var extval = "\u200b" + (selected ? te.value : ""); + te.value = "\u21da"; // Used to catch context-menu undo + te.value = extval; + input.prevInput = selected ? "" : "\u200b"; + te.selectionStart = 1; te.selectionEnd = extval.length; + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel; } - }, + } + function rehide() { + input.contextMenuPending = false; + input.wrapper.style.position = "relative"; + te.style.cssText = oldCSS; + if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); - selectAll: function () { - if (!this.element.is(":visible")) { - throw new Error("input输入框在不可见下不能select"); + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); + var i = 0, poll = function() { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); + else display.input.reset(); + }; + display.detectingSelectAll = setTimeout(poll, 200); } - this.element.select(); - this._isEditing = true; - }, + } - setValue: function (textValue) { - this.element.val(textValue); - BI.nextTick(BI.bind(function () { - this._checkValidationOnValueChange(); - this._defaultState(); - if (this.isValid()) { - this._lastSubmitValue = this.getValue(); - } - }, this)); + if (ie && ie_version >= 9) prepareSelectAllHack(); + if (captureRightClick) { + e_stop(e); + var mouseup = function() { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } }, - getValue: function () { - return this.element.val() || ""; - }, + setUneditable: nothing, - isEditing: function () { - return this._isEditing; - }, + needsContentAttribute: false + }, TextareaInput.prototype); - getLastValidValue: function () { - return this._lastValidValue; - }, + // CONTENTEDITABLE INPUT STYLE - setValid: function () { - BI.Input.superclass.setValid.apply(this, arguments); - if (this.isValid()) { - this._lastValidValue = this.getValue(); - this.element.removeClass("bi-input-error"); - this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); - } else { - if (this._lastValidValue === this.getValue()) { - this._lastValidValue = null; - } - this.element.addClass("bi-input-error"); - this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); - } - }, + function ContentEditableInput(cm) { + this.cm = cm; + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; + this.polling = new Delayed(); + this.gracePeriod = false; + } - setEnable: function (b) { - BI.Input.superclass.setEnable.apply(this, [b]); - this.element[0].disabled = !b; - } -}); -BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; + ContentEditableInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = input.cm; + var div = input.div = display.lineDiv; + div.contentEditable = "true"; + disableBrowserMagic(div); -BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; -BI.Input.EVENT_CLICK = "EVENT_CLICK"; -BI.Input.EVENT_BLUR = "EVENT_BLUR"; -BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; -BI.Input.EVENT_SPACE = "EVENT_SPACE"; -BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; + on(div, "paste", function(e) { handlePaste(e, cm); }) -BI.Input.EVENT_START = "EVENT_START"; -BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Input.EVENT_STOP = "EVENT_STOP"; -BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; -BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; -BI.Input.EVENT_VALID = "EVENT_VALID"; -BI.Input.EVENT_ERROR = "EVENT_ERROR"; -BI.Input.EVENT_ENTER = "EVENT_ENTER"; -BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; -$.shortcut("bi.input", BI.Input);/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.Radio = BI.inherit(BI.IconButton, { - _defaultConfig: function() { - var conf = BI.Radio.superclass._defaultConfig.apply(this,arguments); - return BI.extend(conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-radio radio-icon", - selected: false, - handler: BI.emptyFn, - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16 - }) - }, + on(div, "compositionstart", function(e) { + var data = e.data; + input.composing = {sel: cm.doc.sel, data: data, startData: data}; + if (!data) return; + var prim = cm.doc.sel.primary(); + var line = cm.getLine(prim.head.line); + var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); + if (found > -1 && found <= prim.head.ch) + input.composing.sel = simpleSelection(Pos(prim.head.line, found), + Pos(prim.head.line, found + data.length)); + }); + on(div, "compositionupdate", function(e) { + input.composing.data = e.data; + }); + on(div, "compositionend", function(e) { + var ours = input.composing; + if (!ours) return; + if (e.data != ours.startData && !/\u200b/.test(e.data)) + ours.data = e.data; + // Need a small delay to prevent other code (input event, + // selection polling) from doing damage when fired right after + // compositionend. + setTimeout(function() { + if (!ours.handled) + input.applyComposition(ours); + if (input.composing == ours) + input.composing = null; + }, 50); + }); - _init : function() { - BI.Radio.superclass._init.apply(this, arguments); - }, + on(div, "touchstart", function() { + input.forceCompositionEnd(); + }); - doClick: function(){ - BI.Radio.superclass.doClick.apply(this, arguments); - if(this.isValid()){ - this.fireEvent(BI.Radio.EVENT_CHANGE); + on(div, "input", function() { + if (input.composing) return; + if (!input.pollContent()) + runInOp(input.cm, function() {regChange(cm);}); + }); + + function onCopyCut(e) { + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (e.type == "cut") cm.replaceSelection("", null, "cut"); + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.operation(function() { + cm.setSelections(ranges.ranges, 0, sel_dontScroll); + cm.replaceSelection("", null, "cut"); + }); + } } - } -}); -BI.Radio.EVENT_CHANGE = "Radio.EVENT_CHANGE"; + // iOS exposes the clipboard API, but seems to discard content inserted into it + if (e.clipboardData && !ios) { + e.preventDefault(); + e.clipboardData.clearData(); + e.clipboardData.setData("text/plain", lastCopied.join("\n")); + } else { + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild; + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); + te.value = lastCopied.join("\n"); + var hadFocus = document.activeElement; + selectInput(te); + setTimeout(function() { + cm.display.lineSpace.removeChild(kludge); + hadFocus.focus(); + }, 50); + } + } + on(div, "copy", onCopyCut); + on(div, "cut", onCopyCut); + }, -$.shortcut("bi.radio", BI.Radio);/** - * Created by GUY on 2015/6/26. - */ + prepareSelection: function() { + var result = prepareSelection(this.cm, false); + result.focus = this.cm.state.focused; + return result; + }, -BI.Label = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Label.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-label", - textAlign: "center", - whiteSpace: "nowrap", //normal or nowrap - forceCenter: false, //是否无论如何都要居中, 不考虑超出边界的情况, 在未知宽度和高度时有效 - textWidth: null, - textHeight: null, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - text: "", - py: "", - keyword: "" - }) + showSelection: function(info) { + if (!info || !this.cm.display.view.length) return; + if (info.focus) this.showPrimarySelection(); + this.showMultipleSelections(info); }, - _createJson: function () { - var o = this.options; - return { - type: "bi.text", - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - lineHeight: o.textHeight, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }; + showPrimarySelection: function() { + var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); + var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); + var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && + cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) + return; + + var start = posToDOM(this.cm, prim.from()); + var end = posToDOM(this.cm, prim.to()); + if (!start && !end) return; + + var view = this.cm.display.view; + var old = sel.rangeCount && sel.getRangeAt(0); + if (!start) { + start = {node: view[0].measure.map[2], offset: 0}; + } else if (!end) { // FIXME dangerously hacky + var measure = view[view.length - 1].measure; + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; + } + + try { var rng = range(start.node, start.offset, end.offset, end.node); } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + sel.removeAllRanges(); + sel.addRange(rng); + if (old && sel.anchorNode == null) sel.addRange(old); + else if (gecko) this.startGracePeriod(); + } + this.rememberSelection(); }, - _init: function () { - BI.Label.superclass._init.apply(this, arguments); + startGracePeriod: function() { + var input = this; + clearTimeout(this.gracePeriod); + this.gracePeriod = setTimeout(function() { + input.gracePeriod = false; + if (input.selectionChanged()) + input.cm.operation(function() { input.cm.curOp.selectionChanged = true; }); + }, 20); + }, - if (this.options.textAlign === "center") { - this._createCenterEl(); - } else { - this._createNotCenterEl(); - } + showMultipleSelections: function(info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); }, - _createCenterEl: function () { - var o = this.options; - var json = this._createJson(); - if (BI.isNumber(o.width) && o.width > 0) { - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - if (BI.isNumber(o.height) && o.height > 0) { - var gap = (o.width - o.textWidth) / 2; - BI.createWidget({ - type: "bi.adaptive", - height: o.height, - scrollable: true, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - left: gap + o.hgap + o.lgap, - right: gap + o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - } - ] - }); - this.element.css({"line-height": o.height + "px"}); - return; - } - json.width = o.textWidth; - BI.createWidget({ - type: "bi.center_adapt", - scrollable: true, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)) - } - ] - }); - return; - } - if (o.whiteSpace == "normal") { - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.center_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [this.text] - }); - return; - } - if (BI.isNumber(o.height) && o.height > 0) { - this.element.css({ - "line-height": o.height + "px" - }); - BI.createWidget({ - type: "bi.absolute", - scrollable: true, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)), - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - }] - }); - return; - } - json.width = o.width - 2 * o.hgap; - BI.createWidget({ - type: "bi.center_adapt", - scrollable: true, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)) - }] - }); - return; - } - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - json.width = o.textWidth; - BI.createWidget({ - type: "bi.center_adapt", - scrollable: true, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)) - } - ] - }); - return; - } - if (o.whiteSpace == "normal") { - this.text = BI.createWidget(json); - this.text = BI.createWidget({ - type: "bi.center_adapt", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - scrollable: true, - element: this, - items: [this.text] - }); - return; - } - if (BI.isNumber(o.height) && o.height > 0) { - if (BI.isNumber(o.textHeight) && o.textHeight > 0) { - this.element.css({ - "line-height": o.height + "px" - }); - BI.createWidget({ - type: "bi.adaptive", - height: o.height, - scrollable: true, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)), - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - }] - }); - return; - } - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap - }); - this.element.css({ - "line-height": o.height + "px" - }); - this.text = BI.createWidget(BI.extend(json, { - element: this - })); - BI.createWidget({ - type: "bi.layout", - element: this.text, - scrollable: true - }); - return; - } - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap - }); - if (o.forceCenter) { - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.center_adapt", - element: this, - items: [this.text] - }); - return; - } - this.text = BI.createWidget(BI.extend(json, { - element: this - })); - BI.createWidget({ - type: "bi.layout", - element: this.text, - scrollable: true - }) + rememberSelection: function() { + var sel = window.getSelection(); + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; }, - _createNotCenterEl: function () { - var o = this.options; - var json = this._createJson(); - if (BI.isNumber(o.width) && o.width > 0) { - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - if (BI.isNumber(o.height) && o.height > 0) { - BI.createWidget({ - type: "bi.adaptive", - height: o.height, - scrollable: true, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - } - ] - }); - this.element.css({"line-height": o.height + "px"}); - return; - } - json.width = o.textWidth; - BI.createWidget({ - type: "bi.vertical_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)) - } - ] - }); - return; - } - if (o.whiteSpace == "normal") { - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.vertical_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [this.text] - }); - return; - } - if (BI.isNumber(o.height) && o.height > 0) { - this.element.css({ - "line-height": o.height + "px" - }); - BI.createWidget({ - type: "bi.absolute", - scrollable: true, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)), - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - }] - }); - return; - } - json.width = o.width - 2 * o.hgap - o.lgap - o.rgap; - BI.createWidget({ - type: "bi.vertical_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)) - }] - }); - return; - } - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - json.width = o.textWidth; - BI.createWidget({ - type: "bi.vertical_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)) - } - ] - }); - return; - } - if (o.whiteSpace == "normal") { - this.text = BI.createWidget(json) - this.text = BI.createWidget({ - type: "bi.vertical_adapt", - scrollable: true, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [this.text] - }); - return; - } - if (BI.isNumber(o.height) && o.height > 0) { - if (BI.isNumber(o.textHeight) && o.textHeight > 0) { - this.element.css({ - "line-height": o.height + "px" - }); - BI.createWidget({ - type: "bi.adaptive", - height: o.height, - scrollable: true, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)), - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap - }] - }); - return; - } - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap - }); - this.element.css({ - "line-height": o.height + "px" - }); - this.text = BI.createWidget(BI.extend(json, { - element: this - })); - BI.createWidget({ - type: "bi.layout", - element: this.text, - scrollable: true - }); - return; - } - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap - }); - if (o.forceCenter) { - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.vertical_adapt", - element: this, - items: [this.text] - }); - return; - } - this.text = BI.createWidget(BI.extend(json, { - element: this - })); - BI.createWidget({ - type: "bi.layout", - element: this.text, - scrollable: true - }) - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); + selectionInEditor: function() { + var sel = window.getSelection(); + if (!sel.rangeCount) return false; + var node = sel.getRangeAt(0).commonAncestorContainer; + return contains(this.div, node); }, - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); + focus: function() { + if (this.cm.options.readOnly != "nocursor") this.div.focus(); }, + blur: function() { this.div.blur(); }, + getField: function() { return this.div; }, - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, + supportsTouch: function() { return true; }, - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, + receivedFocus: function() { + var input = this; + if (this.selectionInEditor()) + this.pollSelection(); + else + runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; }); - setText: function (v) { - this.options.text = v; - this.text.setText(v); + function poll() { + if (input.cm.state.focused) { + input.pollSelection(); + input.polling.set(input.cm.options.pollInterval, poll); + } + } + this.polling.set(this.cm.options.pollInterval, poll); }, - getText: function () { - return this.options.text; + selectionChanged: function() { + var sel = window.getSelection(); + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; }, - setValue: function (v) { - BI.Label.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.text.setValue(v); - } + pollSelection: function() { + if (!this.composing && !this.gracePeriod && this.selectionChanged()) { + var sel = window.getSelection(), cm = this.cm; + this.rememberSelection(); + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var head = domToPos(cm, sel.focusNode, sel.focusOffset); + if (anchor && head) runInOp(cm, function() { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); + if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; + }); + } }, - populate: function () { - BI.Label.superclass.populate.apply(this, arguments); - } -}); + pollContent: function() { + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); + var from = sel.from(), to = sel.to(); + if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; -$.shortcut("bi.label", BI.Label);/** - * guy a元素 - * @class BI.Link - * @extends BI.Text - */ -BI.Link = BI.inherit(BI.Label, { - _defaultConfig: function() { - var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-link", - href: "", - target: "_blank" - }) - }, - - _createJson: function(){ - var o = this.options; - return { - type:"bi.a", - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - lineHeight: o.textHeight, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py, - href: o.href, - target: o.target - }; - }, - - _init : function() { - BI.Link.superclass._init.apply(this, arguments); - } -}); - -$.shortcut("bi.link", BI.Link);/** - * guy - * tip提示 - * zIndex在10亿级别 - * @class BI.Tip - * @extends BI.Single - * @abstract - */ -BI.Tip = BI.inherit(BI.Single, { - _defaultConfig: function() { - var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-tip", - zIndex: BI.zIndex_tip - }) - }, - - _init : function() { - BI.Tip.superclass._init.apply(this, arguments); - this.element.css({"zIndex": this.options.zIndex}); - } -});/** - * 下拉 - * @class BI.Trigger - * @extends BI.Single - * @abstract - */ -BI.Trigger = BI.inherit(BI.Single, { - _defaultConfig: function() { - var conf = BI.Trigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-trigger cursor-pointer", - height: 30 - }) - }, - - _init : function() { - BI.Trigger.superclass._init.apply(this, arguments); - }, - - setKey: function(){ - - }, - - getKey: function(){ - - } -});/** - * svg绘图 - * - * Created by GUY on 2015/12/3. - * @class BI.Svg - * @extends BI.Widget - */ -BI.Svg = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.Svg.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-svg" - }) - }, + var fromIndex; + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + var fromLine = lineNo(display.view[0].line); + var fromNode = display.view[0].node; + } else { + var fromLine = lineNo(display.view[fromIndex].line); + var fromNode = display.view[fromIndex - 1].node.nextSibling; + } + var toIndex = findViewIndex(cm, to.line); + if (toIndex == display.view.length - 1) { + var toLine = display.viewTo - 1; + var toNode = display.lineDiv.lastChild; + } else { + var toLine = lineNo(display.view[toIndex + 1].line) - 1; + var toNode = display.view[toIndex + 1].node.previousSibling; + } - _init: function () { - BI.Svg.superclass._init.apply(this, arguments); - this.paper = Raphael(this.element[0]); + var newText = splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } + else break; + } - $(this.paper.canvas).width("100%").height("100%").css({"left": "0", "top": "0"}).appendTo(this.element); + var cutFront = 0, cutEnd = 0; + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + ++cutFront; + var newBot = lst(newText), oldBot = lst(oldText); + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)); + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + ++cutEnd; - this.top = this.paper.top; - this.bottom = this.paper.bottom; - this.customAttributes = this.paper.customAttributes; - this.ca = this.paper.ca; - this.raphael = this.paper.raphael; - }, + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); + newText[0] = newText[0].slice(cutFront); - add: function () { - return this.paper.add.apply(this.paper, arguments); + var chFrom = Pos(fromLine, cutFront); + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input"); + return true; + } }, - path: function () { - return this.paper.path.apply(this.paper, arguments); + ensurePolled: function() { + this.forceCompositionEnd(); }, - - image: function () { - return this.paper.image.apply(this.paper, arguments); + reset: function() { + this.forceCompositionEnd(); }, - - rect: function () { - return this.paper.rect.apply(this.paper, arguments); + forceCompositionEnd: function() { + if (!this.composing || this.composing.handled) return; + this.applyComposition(this.composing); + this.composing.handled = true; + this.div.blur(); + this.div.focus(); }, - - circle: function () { - return this.paper.circle.apply(this.paper, arguments); + applyComposition: function(composing) { + if (composing.data && composing.data != composing.startData) + operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); }, - ellipse: function () { - return this.paper.ellipse.apply(this.paper, arguments); + setUneditable: function(node) { + node.setAttribute("contenteditable", "false"); }, - text: function () { - return this.paper.text.apply(this.paper, arguments); + onKeyPress: function(e) { + e.preventDefault(); + operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); }, - print: function () { - return this.paper.print.apply(this.paper, arguments); - }, + onContextMenu: nothing, + resetPosition: nothing, + needsContentAttribute: true + }, ContentEditableInput.prototype); - setStart: function () { - return this.paper.setStart.apply(this.paper, arguments); - }, + function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line); + if (!view || view.hidden) return null; + var line = getLine(cm.doc, pos.line); + var info = mapFromLineView(view, line, pos.line); - setFinish: function () { - return this.paper.setFinish.apply(this.paper, arguments); - }, + var order = getOrder(line), side = "left"; + if (order) { + var partPos = getBidiPartAt(order, pos.ch); + side = partPos % 2 ? "right" : "left"; + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); + result.offset = result.collapse == "right" ? result.end : result.start; + return result; + } - setSize: function () { - return this.paper.setSize.apply(this.paper, arguments); - }, + function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } - setViewBox: function () { - return this.paper.setViewBox.apply(this.paper, arguments); - }, + function domToPos(cm, node, offset) { + var lineNode; + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset]; + if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); + node = null; offset = 0; + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) return null; + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i]; + if (lineView.node == lineNode) + return locateNodeInLineView(lineView, node, offset); + } + } + function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false; + if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); + if (node == wrapper) { + bad = true; + node = wrapper.childNodes[offset]; + offset = 0; + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line; + return badPos(Pos(lineNo(line), line.text.length), bad); + } + } - getById: function () { - return this.paper.getById.apply(this.paper, arguments); - }, + var textNode = node.nodeType == 3 ? node : null, topNode = node; + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild; + if (offset) offset = textNode.nodeValue.length; + } + while (topNode.parentNode != wrapper) topNode = topNode.parentNode; + var measure = lineView.measure, maps = measure.maps; - getElementByPoint: function () { - return this.paper.getElementByPoint.apply(this.paper, arguments); - }, + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i]; + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2]; + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); + var ch = map[j] + offset; + if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; + return Pos(line, ch); + } + } + } + } + var found = find(textNode, topNode, offset); + if (found) return badPos(found, bad); - getElementsByPoint: function () { - return this.paper.getElementsByPoint.apply(this.paper, arguments); - }, + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0); + if (found) + return badPos(Pos(found.line, found.ch - dist), bad); + else + dist += after.textContent.length; + } + for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1); + if (found) + return badPos(Pos(found.line, found.ch + dist), bad); + else + dist += after.textContent.length; + } + } - getFont: function () { - return this.paper.getFont.apply(this.paper, arguments); - }, + function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false; + function recognizeMarker(id) { return function(marker) { return marker.id == id; }; } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text"); + if (cmText != null) { + if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); + text += cmText; + return; + } + var markerID = node.getAttribute("cm-marker"), range; + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); + if (found.length && (range = found[0].find())) + text += getBetween(cm.doc, range.from, range.to).join("\n"); + return; + } + if (node.getAttribute("contenteditable") == "false") return; + for (var i = 0; i < node.childNodes.length; i++) + walk(node.childNodes[i]); + if (/^(pre|div|p)$/i.test(node.nodeName)) + closing = true; + } else if (node.nodeType == 3) { + var val = node.nodeValue; + if (!val) return; + if (closing) { + text += "\n"; + closing = false; + } + text += val; + } + } + for (;;) { + walk(from); + if (from == to) break; + from = from.nextSibling; + } + return text; + } + CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; - set: function () { - return this.paper.set.apply(this.paper, arguments); + // SELECTION / CURSOR + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + function Selection(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + } + + Selection.prototype = { + primary: function() { return this.ranges[this.primIndex]; }, + equals: function(other) { + if (other == this) return true; + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; + } + return true; }, - remove: function () { - return this.paper.remove.apply(this.paper, arguments); + deepCopy: function() { + for (var out = [], i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); + return new Selection(out, this.primIndex); }, - clear: function () { - return this.paper.clear.apply(this.paper, arguments); - } -}); -$.shortcut("bi.svg", BI.Svg);/** - * - * 表格 - * - * Created by GUY on 2015/9/22. - * @class BI.TableCell - * @extends BI.Single - */ -BI.TableCell = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.TableCell.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-table-cell", - textAlign: "left", - text: "" - }) + somethingSelected: function() { + for (var i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true; + return false; }, - - _init: function () { - BI.TableCell.superclass._init.apply(this, arguments); - BI.createWidget({ - type: "bi.label", - element: this, - whiteSpace: "nowrap", - textAlign: this.options.textAlign, - height: this.options.height, - text: this.options.text, - value: this.options.value, - lgap: 5 - }) + contains: function(pos, end) { + if (!end) end = pos; + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i; + } + return -1; } -}); - -$.shortcut("bi.table_cell", BI.TableCell);/** - * - * 表格单元格 - * - * Created by GUY on 2016/1/12. - * @class BI.CollectionTableCell - * @extends BI.Widget - */ -BI.CollectionTableCell = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.CollectionTableCell.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-collection-table-cell", - width: 0, - height: 0, - _left: 0, - _top: 0, - cell: {} - }) - }, + }; - _init: function () { - BI.CollectionTableCell.superclass._init.apply(this, arguments); - var o = this.options; - this.cell = BI.createWidget(BI.extend({ - type: "bi.label" - }, o.cell, { - cls: (o.cell.cls || "") + "collection-table-cell-wrapper", - width: o.width - (o._left === 0 ? 1 : 0) - 1, - height: o.height - (o._top === 0 ? 1 : 0) - 1 - })); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.cell, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - }, + function Range(anchor, head) { + this.anchor = anchor; this.head = head; + } - setWidth: function (width) { - BI.CollectionTableCell.superclass.setWidth.apply(this, arguments); - var o = this.options; - this.cell.setWidth(o.width - (o._left === 0 ? 1 : 0) - 1); - }, + Range.prototype = { + from: function() { return minPos(this.anchor, this.head); }, + to: function() { return maxPos(this.anchor, this.head); }, + empty: function() { + return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; + } + }; - setHeight: function (height) { - BI.CollectionTableCell.superclass.setHeight.apply(this, arguments); - var o = this.options; - this.cell.setHeight(o.height - (o._top === 0 ? 1 : 0) - 1); + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex]; + ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) --primIndex; + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } } -}); + return new Selection(ranges, primIndex); + } -$.shortcut("bi.collection_table_cell", BI.CollectionTableCell);/** - * CollectionTable - * - * Created by GUY on 2016/1/12. - * @class BI.CollectionTable - * @extends BI.Widget - */ -BI.CollectionTable = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.CollectionTable.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-collection-table", - headerRowSize: 25, - rowSize: 25, - columnSize: [], - isNeedFreeze: false, - freezeCols: [], - isNeedMerge: false, - mergeCols: [], - mergeRule: BI.emptyFn, - header: [], - items: [], - regionColumnSize: [] - }); - }, + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0); + } - _init: function () { - BI.CollectionTable.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this._width = 0; - this._height = 0; - this._scrollBarSize = BI.DOM.getScrollWidth(); - this.topLeftCollection = BI.createWidget({ - type: "bi.collection_view", - cellSizeAndPositionGetter: function (index) { - return self.topLeftItems[index]; - } - }); - this.topLeftCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { - self.bottomLeftCollection.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.topRightCollection = BI.createWidget({ - type: "bi.collection_view", - cellSizeAndPositionGetter: function (index) { - return self.topRightItems[index]; - } - }); - this.topRightCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { - self.bottomRightCollection.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.bottomLeftCollection = BI.createWidget({ - type: "bi.collection_view", - cellSizeAndPositionGetter: function (index) { - return self.bottomLeftItems[index]; - } - }); - this.bottomLeftCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { - self.bottomRightCollection.setScrollTop(scroll.scrollTop); - self.topLeftCollection.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.bottomRightCollection = BI.createWidget({ - type: "bi.collection_view", - cellSizeAndPositionGetter: function (index) { - return self.bottomRightItems[index]; - } - }); - this.bottomRightCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { - self.bottomLeftCollection.setScrollTop(scroll.scrollTop); - self.topRightCollection.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.topLeft = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.topLeftCollection] - }); - this.topRight = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.topRightCollection] - }); - this.bottomLeft = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.bottomLeftCollection] - }); - this.bottomRight = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.bottomRightCollection] - }); - this.contextLayout = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.topLeft, - top: 0, - left: 0 - }, { - el: this.topRight, - top: 0 - }, { - el: this.bottomLeft, - left: 0 - }, { - el: this.bottomRight - }] - }); + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} + function clipPosArray(doc, array) { + for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); + return out; + } - this.topScrollbar = BI.createWidget({ - type: "bi.grid_table_scrollbar", - width: BI.GridTableScrollbar.SIZE - }); - this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { - self.bottomLeftCollection.setScrollTop(scrollTop); - self.bottomRightCollection.setScrollTop(scrollTop); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.leftScrollbar = BI.createWidget({ - type: "bi.grid_table_horizontal_scrollbar", - height: BI.GridTableScrollbar.SIZE - }); - this.leftScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { - self.topLeftCollection.setScrollLeft(scrollLeft); - self.bottomLeftCollection.setScrollLeft(scrollLeft); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.rightScrollbar = BI.createWidget({ - type: "bi.grid_table_horizontal_scrollbar", - height: BI.GridTableScrollbar.SIZE - }); - this.rightScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { - self.topRightCollection.setScrollLeft(scrollLeft); - self.bottomRightCollection.setScrollLeft(scrollLeft); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.scrollBarLayout = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.topScrollbar, - right: 0, - top: 0 - }, { - el: this.leftScrollbar, - left: 0 - }, { - el: this.rightScrollbar, - }] - }); - this._width = o.width - BI.GridTableScrollbar.SIZE; - this._height = o.height - BI.GridTableScrollbar.SIZE; - if (o.items.length > 0 || o.header.length < 0) { - this._digest(); - this._populate(); - } - }, + // SELECTION UPDATES - _getFreezeColLength: function () { - return this.options.isNeedFreeze ? this.options.freezeCols.length : 0; - }, + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. - _populateScrollbar: function () { - var o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); - this.topScrollbar.setContentSize(o.items.length * o.rowSize); - this.topScrollbar.setSize(this._height - o.header.length * o.headerRowSize); - this.topScrollbar.setPosition(this.bottomRightCollection.getScrollTop()); - this.topScrollbar.populate(); + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(doc, range, head, other) { + if (doc.cm && doc.cm.display.shift || doc.extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head); + } else { + return new Range(other || head, head); + } + } - this.leftScrollbar.setContentSize(totalLeftColumnSize); - this.leftScrollbar.setSize(regionSize); - this.leftScrollbar.setPosition(this.bottomLeftCollection.getScrollLeft()); - this.leftScrollbar.populate(); + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options) { + setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); + } - this.rightScrollbar.setContentSize(totalRightColumnSize); - this.rightScrollbar.setSize(this._width - regionSize); - this.rightScrollbar.setPosition(this.bottomRightCollection.getScrollLeft()); - this.rightScrollbar.populate(); + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + for (var out = [], i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); + var newSel = normalizeSelection(out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } - var items = this.scrollBarLayout.attr("items"); - items[0].top = o.header.length * o.headerRowSize; - items[1].top = this._height; - items[2].top = this._height; - items[2].left = regionSize; - this.scrollBarLayout.attr("items", items); - this.scrollBarLayout.resize(); - }, + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); + } - _populateTable: function () { - var self = this, o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } - var tlw = regionSize; - var tlh = regionSize >= summaryColumnSizeArray[freezeColLength - 1] ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); - var trw = this._width - regionSize; - var trh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); - var blw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? regionSize : (regionSize + this._scrollBarSize); - var blh = (regionSize >= (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); - var brw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? (this._width - regionSize) : (this._width - regionSize + this._scrollBarSize); - var brh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); + } + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); + else return sel; + } - var otlw = regionSize; - var otlh = o.header.length * o.headerRowSize; - var otrw = this._width - regionSize; - var otrh = o.header.length * o.headerRowSize; - var oblw = regionSize; - var oblh = this._height - o.header.length * o.headerRowSize; - var obrw = this._width - regionSize; - var obrh = this._height - o.header.length * o.headerRowSize; + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } - var digest = function (w, h, tw, th, el) { - if (w >= tw && h >= th) { - el.element.css({ - overflow: "hidden", - overflowX: "hidden", - overflowY: "hidden" - }) - } else if (w >= tw) { - el.element.css({ - overflow: "hidden", - overflowX: "hidden", - overflowY: "auto" - }) - } else if (h >= th) { - el.element.css({ - overflow: "hidden", - overflowX: "auto", - overflowY: "hidden" - }) - } else { - el.element.css({ - overflow: "auto", - overflowX: "auto", - overflowY: "auto" - }) - } - }; + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } - this.topLeft.setWidth(otlw); - this.topLeft.setHeight(otlh); - this.topRight.setWidth(otrw); - this.topRight.setHeight(otrh); - this.bottomLeft.setWidth(oblw); - this.bottomLeft.setHeight(oblh); - this.bottomRight.setWidth(obrw); - this.bottomRight.setHeight(obrh); + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel); - this.topLeftCollection.setWidth(tlw); - this.topLeftCollection.setHeight(tlh); - this.topRightCollection.setWidth(trw); - this.topRightCollection.setHeight(trh); - this.bottomLeftCollection.setWidth(blw); - this.bottomLeftCollection.setHeight(blh); - this.bottomRightCollection.setWidth(brw); - this.bottomRightCollection.setHeight(brh); + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); - digest(tlw, tlh, totalLeftColumnSize, o.header.length * o.headerRowSize, this.topLeftCollection); - digest(trw, trh, totalRightColumnSize, o.header.length * o.headerRowSize, this.topRightCollection); - digest(blw, blh, totalLeftColumnSize, o.items.length * o.rowSize, this.bottomLeftCollection); - digest(brw, brh, totalRightColumnSize, o.items.length * o.rowSize, this.bottomRightCollection); + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm); + } - var items = this.contextLayout.attr("items"); - items[1].left = regionSize; - items[2].top = o.header.length * o.headerRowSize; - items[3].left = regionSize; - items[3].top = o.header.length * o.headerRowSize; - this.contextLayout.attr("items", items); - this.contextLayout.resize(); + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return; - var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; - var run = function (positions, items, rendered) { - BI.each(positions, function (i, item) { - var cell = { - type: "bi.collection_table_cell", - cell: items[item.row][item.col] - }; - rendered.push(cell); - }); - }; - run(this.topLeftItems, o.header, leftHeader); - run(this.topRightItems, o.header, rightHeader); - run(this.bottomLeftItems, o.items, leftItems); - run(this.bottomRightItems, o.items, rightItems); + doc.sel = sel; - this.topLeftCollection.populate(leftHeader); - this.topRightCollection.populate(rightHeader); - this.bottomLeftCollection.populate(leftItems); - this.bottomRightCollection.populate(rightItems); - }, + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; + signalCursorActivity(doc.cm); + } + signalLater(doc, "cursorActivity", doc); + } - _digest: function () { - var o = this.options; - var freezeColLength = this._getFreezeColLength(); - this.topLeftItems = this._serialize(o.header, 0, freezeColLength, o.headerRowSize, o.columnSize, o.mergeCols); - this.topRightItems = this._serialize(o.header, freezeColLength, o.columnSize.length, o.headerRowSize, o.columnSize, true); - this.bottomLeftItems = this._serialize(o.items, 0, freezeColLength, o.rowSize, o.columnSize, o.mergeCols); - this.bottomRightItems = this._serialize(o.items, freezeColLength, o.columnSize.length, o.rowSize, o.columnSize, o.mergeCols); - }, + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); + } - _serialize: function (items, startCol, endCol, rowHeight, columnSize, mergeCols) { - var self = this, o = this.options; - var result = [], cache = {}, preCol = {}, preRow = {}, map = {}; - var summaryColumnSize = []; - for (var i = startCol; i < endCol; i++) { - if (i === startCol) { - summaryColumnSize[i] = columnSize[i]; - } else { - summaryColumnSize[i] = summaryColumnSize[i - 1] + columnSize[i]; + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i); + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel; + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, bias, mayClear) { + var flipped = false, curPos = pos; + var dir = bias || 1; + doc.cantEdit = false; + search: for (;;) { + var line = getLine(doc, curPos.line); + if (line.markedSpans) { + for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else {--i; continue;} + } + } + if (!m.atomic) continue; + var newPos = m.find(dir < 0 ? -1 : 1); + if (cmp(newPos, curPos) == 0) { + newPos.ch += dir; + if (newPos.ch < 0) { + if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); + else newPos = null; + } else if (newPos.ch > line.text.length) { + if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); + else newPos = null; + } + if (!newPos) { + if (flipped) { + // Driven in a corner -- no valid cursor position found at all + // -- try again *with* clearing, if we didn't already + if (!mayClear) return skipAtomic(doc, pos, bias, true); + // Otherwise, turn off editing until further notice, and return the start of the doc + doc.cantEdit = true; + return Pos(doc.first, 0); + } + flipped = true; newPos = pos; dir = -dir; + } } + curPos = newPos; + continue search; + } } - var mergeRow = function (i, j) { - preCol[j]._height += rowHeight; - preCol[j].__mergeRows.push(i); - }; + } + return curPos; + } + } - var mergeCol = function (i, j) { - preRow[i]._width += columnSize[j]; - preRow[i].__mergeCols.push(j); - }; + // SELECTION DRAWING - var createOneEl = function (r, c) { - var width = columnSize[c]; - var height = rowHeight; - map[r][c]._row = r; - map[r][c]._col = c; - map[r][c]._width = width; - map[r][c]._height = height; - preCol[c] = map[r][c]; - preCol[c].__mergeRows = [r]; - preRow[r] = map[r][c]; - preRow[r].__mergeCols = [c]; + function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()); + } - result.push({ - x: summaryColumnSize[c] - columnSize[c], - y: +r * rowHeight, - item: map[r][c] - }); - }; + function prepareSelection(cm, primary) { + var doc = cm.doc, result = {}; + var curFragment = result.cursors = document.createDocumentFragment(); + var selFragment = result.selection = document.createDocumentFragment(); - BI.each(items, function (i, cols) { - for (var j = startCol; j < endCol; j++) { - if (!cache[i]) { - cache[i] = {}; - } - if (!map[i]) { - map[i] = {}; - } - cache[i][j] = cols[j]; - map[i][j] = {}; - if (mergeCols === true || mergeCols.indexOf(j) > -1) { - if (i === 0 && j === startCol) { - createOneEl(0, startCol); - } else if (j === startCol && i > 0) { - var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); - if (isNeedMergeRow === true) { - mergeRow(i, j); - preRow[i] = preCol[j]; - } else { - createOneEl(i, j); - } - } else if (i === 0 && j > startCol) { - var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); - if (isNeedMergeCol === true) { - mergeCol(i, j); - preCol[j] = preRow[i]; - } else { - createOneEl(i, j); - } - } else { - var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); - var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); - if (isNeedMergeCol && isNeedMergeRow) { - continue; - //mergeRow(i, j);//优先合并列 - } - if (isNeedMergeCol) { - mergeCol(i, j); - } - if (isNeedMergeRow) { - mergeRow(i, j); - } - if (!isNeedMergeCol && !isNeedMergeRow) { - createOneEl(i, j); - } - } - } else { - createOneEl(i, j); - } - } - }); - return BI.map(result, function (i, item) { - return { - x: item.x, - y: item.y, - row: item.item._row, - col: item.item._col, - width: item.item._width, - height: item.item._height - } - }); - }, + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (primary === false && i == doc.sel.primIndex) continue; + var range = doc.sel.ranges[i]; + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + drawSelectionCursor(cm, range, curFragment); + if (!collapsed) + drawSelectionRange(cm, range, selFragment); + } + return result; + } - _populate: function () { - if (this._width <= 0 || this._height <= 0) { - return; - } - if (this._isNeedDigest === true) { - this._digest(); - } - this._populateTable(); - this._populateScrollbar(); - }, + // Draws a cursor for the given range + function drawSelectionCursor(cm, range, output) { + var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine); - getRegionSize: function () { - var o = this.options; - var regionSize = o.regionColumnSize[0] || 0; - if (o.isNeedFreeze === false || o.freezeCols.length === 0) { - return 0; - } - if (!regionSize) { - BI.each(o.freezeCols, function (i, col) { - regionSize += o.columnSize[col]; - }); - } - return regionSize; - }, + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + cursor.style.left = pos.left + "px"; + cursor.style.top = pos.top + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - setVerticalScroll: function (scrollTop) { - this.bottomLeftCollection.setScrollTop(scrollTop); - this.bottomRightCollection.setScrollTop(scrollTop); - }, + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left + "px"; + otherCursor.style.top = pos.other.top + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } + } - setLeftHorizontalScroll: function (scrollLeft) { - this.topLeftCollection.setScrollLeft(scrollLeft); - this.bottomLeftCollection.setScrollLeft(scrollLeft); - }, + // Draws the given range as a highlighted selection + function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left; + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; - setRightHorizontalScroll: function (scrollLeft) { - this.topRightCollection.setScrollLeft(scrollLeft); - this.bottomRightCollection.setScrollLeft(scrollLeft); - }, + function add(left, top, width, bottom) { + if (top < 0) top = 0; + top = Math.round(top); + bottom = Math.round(bottom); + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + + "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + + "px; height: " + (bottom - top) + "px")); + } - getVerticalScroll: function () { - return this.bottomRightCollection.getScrollTop(); - }, + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } - getLeftHorizontalScroll: function () { - return this.bottomLeftCollection.getScrollLeft(); - }, + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = leftSide; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = rightSide; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < leftSide + 1) left = leftSide; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return {start: start, end: end}; + } - getRightHorizontalScroll: function () { - return this.bottomRightCollection.getScrollLeft(); - }, + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top); + } - setWidth: function (width) { - BI.CollectionTable.superclass.setWidth.apply(this, arguments); - this._width = this.options.width - BI.GridTableScrollbar.SIZE; - }, + output.appendChild(fragment); + } - setHeight: function (height) { - BI.CollectionTable.superclass.setHeight.apply(this, arguments); - this._height = this.options.height - BI.GridTableScrollbar.SIZE; - }, + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function() { + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + else if (cm.options.cursorBlinkRate < 0) + display.cursorDiv.style.visibility = "hidden"; + } - setColumnSize: function (columnSize) { - this._isNeedDigest = true; - this.options.columnSize = columnSize; - }, + // HIGHLIGHT WORKER - setRegionColumnSize: function (regionColumnSize) { - this._isNeedDigest = true; - this.options.regionColumnSize = regionColumnSize; - }, + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } - getColumnSize: function () { - return this.options.columnSize; - }, + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.viewTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + var changedLines = []; - getRegionColumnSize: function () { - return this.options.regionColumnSize; - }, + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { + if (doc.frontier >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles; + var highlighted = highlightLine(cm, line, state, true); + line.styles = highlighted.styles; + var oldCls = line.styleClasses, newCls = highlighted.classes; + if (newCls) line.styleClasses = newCls; + else if (oldCls) line.styleClasses = null; + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) changedLines.push(doc.frontier); + line.stateAfter = copyState(doc.mode, state); + } else { + processLine(cm, line.text, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + if (changedLines.length) runInOp(cm, function() { + for (var i = 0; i < changedLines.length; i++) + regLineChange(cm, changedLines[i], "text"); + }); + } - populate: function (items, header) { - if (items && items !== this.options.items) { - this._isNeedDigest = true; - this.options.items = items; - this._restore(); - } - if (header && header !== this.options.header) { - this._isNeedDigest = true; - this.options.header = header; - this._restore(); - } - this._populate(); - }, + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } - _restore: function () { - this.topLeftCollection.restore(); - this.topRightCollection.restore(); - this.bottomLeftCollection.restore(); - this.bottomRightCollection.restore(); - }, + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function(line) { + processLine(cm, line.text, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + if (precise) doc.frontier = pos; + return state; + } - restore: function () { - this._restore(); - } -}); -$.shortcut('bi.collection_table', BI.CollectionTable);/** - * QuickCollectionTable - * - * Created by GUY on 2016/1/12. - * @class BI.QuickCollectionTable - * @extends BI.CollectionTable - */ -BI.QuickCollectionTable = BI.inherit(BI.CollectionTable, { - _defaultConfig: function () { - return BI.extend(BI.QuickCollectionTable.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-quick-collection-table" - }); - }, + // POSITION MEASUREMENT - _init: function () { - BI.QuickCollectionTable.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.topLeftCollection.setOverflowX(false); - this.topLeftCollection.setOverflowY(false); - this.topRightCollection.setOverflowX(false); - this.topRightCollection.setOverflowY(false); - this.bottomLeftCollection.setOverflowX(false); - this.bottomLeftCollection.setOverflowY(false); - this.bottomRightCollection.setOverflowX(false); - this.bottomRightCollection.setOverflowY(false); - this._leftWheelHandler = new BI.WheelHandler( - BI.bind(this._onWheelY, this), - BI.bind(this._shouldHandleX, this), - BI.bind(this._shouldHandleY, this) - ); - this._rightWheelHandler = new BI.WheelHandler( - BI.bind(this._onWheelY, this), - BI.bind(this._shouldHandleX, this), - BI.bind(this._shouldHandleY, this) - ); - this.bottomLeftCollection.element.mousewheel(function (e) { - self._leftWheelHandler.onWheel(e.originalEvent); - }); - this.bottomRightCollection.element.mousewheel(function (e) { - self._rightWheelHandler.onWheel(e.originalEvent); - }); - }, + function paddingTop(display) {return display.lineSpace.offsetTop;} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} + function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH; + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; + if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; + return data; + } - _shouldHandleX: function (delta) { - return false; - }, + function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } + function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; + } + function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; + } - _shouldHandleY: function (delta) { - if (delta > 0) { - return this.bottomRightCollection.getScrollTop() < this.bottomRightCollection.getMaxScrollTop(); - } else { - return this.bottomRightCollection.getScrollTop() > 0; + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && displayWidth(cm); + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top); } - }, + } + heights.push(rect.bottom - rect.top); + } + } - _onWheelY: function (deltaX, deltaY) { - var self = this; - var scrollTop = this.bottomRightCollection.getScrollTop(); - scrollTop += deltaY; - this.bottomLeftCollection.setScrollTop(scrollTop); - this.bottomRightCollection.setScrollTop(scrollTop); - self._populateScrollbar(); - this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }, + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return {map: lineView.measure.map, cache: lineView.measure.cache}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; + } - _populateTable: function () { - var self = this, o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view; + } - var otlw = regionSize; - var otlh = o.header.length * o.headerRowSize; - var otrw = this._width - regionSize; - var otrh = o.header.length * o.headerRowSize; - var oblw = regionSize; - var oblh = this._height - o.header.length * o.headerRowSize; - var obrw = this._width - regionSize; - var obrh = this._height - o.header.length * o.headerRowSize; + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); + } - this.topLeft.setWidth(otlw); - this.topLeft.setHeight(otlh); - this.topRight.setWidth(otrw); - this.topRight.setHeight(otrh); - this.bottomLeft.setWidth(oblw); - this.bottomLeft.setHeight(oblh); - this.bottomRight.setWidth(obrw); - this.bottomRight.setHeight(obrh); - - this.topLeftCollection.setWidth(otlw); - this.topLeftCollection.setHeight(otlh); - this.topRightCollection.setWidth(otrw); - this.topRightCollection.setHeight(otrh); - this.bottomLeftCollection.setWidth(oblw); - this.bottomLeftCollection.setHeight(oblh); - this.bottomRightCollection.setWidth(obrw); - this.bottomRightCollection.setHeight(obrh); + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)]; + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext; + } - var items = this.contextLayout.attr("items"); - items[1].left = regionSize; - items[2].top = o.header.length * o.headerRowSize; - items[3].left = regionSize; - items[3].top = o.header.length * o.headerRowSize; - this.contextLayout.attr("items", items); - this.contextLayout.resize(); + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) + view = null; + else if (view && view.changes) + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + if (!view) + view = updateExternalMeasurement(cm, line); - var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; - var run = function (positions, items, rendered) { - BI.each(positions, function (i, item) { - var cell = { - type: "bi.collection_table_cell", - cell: items[item.row][item.col] - }; - rendered.push(cell); - }); - }; - run(this.topLeftItems, o.header, leftHeader); - run(this.topRightItems, o.header, rightHeader); - run(this.bottomLeftItems, o.items, leftItems); - run(this.bottomRightItems, o.items, rightItems); + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + }; + } - this.topLeftCollection.populate(leftHeader); - this.topRightCollection.populate(rightHeader); - this.bottomLeftCollection.populate(leftItems); - this.bottomRightCollection.populate(rightItems); + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) ch = -1; + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect(); + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) prepared.cache[key] = found; } -}); -$.shortcut('bi.quick_collection_table', BI.QuickCollectionTable);/** - * - * 表格单元格 - * - * Created by GUY on 2016/1/12. - * @class BI.GridTableCell - * @extends BI.Widget - */ -BI.GridTableCell = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.GridTableCell.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-grid-table-cell", - width: 0, - height: 0, - _rowIndex: 0, - _columnIndex: 0, - _left: 0, - _top: 0, - cell: {} - }) - }, + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom}; + } - _init: function () { - BI.GridTableCell.superclass._init.apply(this, arguments); - var o = this.options; - this.cell = BI.createWidget(BI.extend({ - type: "bi.label" - }, o.cell, { - cls: (o.cell.cls || "") + "grid-table-cell-wrapper", - width: o.width - (o._columnIndex === 0 ? 1 : 0) - 1, - height: o.height - (o._rowIndex === 0 ? 1 : 0) - 1 - })); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.cell, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - }, + var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; - setWidth: function (width) { - BI.GridTableCell.superclass.setWidth.apply(this, arguments); - var o = this.options; - this.cell.setWidth(o.width - (o._columnIndex === 0 ? 1 : 0) - 1); - }, + function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + var mStart = map[i], mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) collapse = "right"; + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias; + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } + break; + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; + } - setHeight: function (height) { - BI.GridTableCell.superclass.setHeight.apply(this, arguments); - var o = this.options; - this.cell.setHeight(o.height - (o._rowIndex === 0 ? 1 : 0) - 1); + function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); + var node = place.node, start = place.start, end = place.end, collapse = place.collapse; + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { + rect = node.parentNode.getBoundingClientRect(); + } else if (ie && cm.options.lineWrapping) { + var rects = range(node, start, end).getClientRects(); + if (rects.length) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = nullRect; + } else { + rect = range(node, start, end).getBoundingClientRect() || nullRect; + } + if (rect.left || rect.right || start == 0) break; + end = start; + start = start - 1; + collapse = "right"; + } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right"; + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = node.getBoundingClientRect(); + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; + else + rect = nullRect; } -}); -$.shortcut("bi.grid_table_cell", BI.GridTableCell);/** - * GridTable - * - * Created by GUY on 2016/1/12. - * @class BI.GridTable - * @extends BI.Widget - */ -BI.GridTable = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.GridTable.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-grid-table", - headerRowSize: 25, - rowSize: 25, - columnSize: [], - isNeedFreeze: false, - freezeCols: [], - header: [], - items: [], - regionColumnSize: [] - }); - }, + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; + var mid = (rtop + rbot) / 2; + var heights = prepared.view.measure.heights; + for (var i = 0; i < heights.length - 1; i++) + if (mid < heights[i]) break; + var top = i ? heights[i - 1] : 0, bot = heights[i]; + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot}; + if (!rect.left && !rect.right) result.bogus = true; + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } - _init: function () { - BI.GridTable.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this._width = 0; - this._height = 0; - this._scrollBarSize = BI.DOM.getScrollWidth(); - var rowHeightGetter = function () { - return o.rowSize; - }; - var columnLeftWidthGetter = function (index) { - return o.columnSize[index]; - }; - var columnRightWidthGetter = function (index) { - return o.columnSize[index + self._getFreezeColLength()]; - }; - this.topLeftGrid = BI.createWidget({ - type: "bi.grid_view", - rowHeightGetter: rowHeightGetter, - columnWidthGetter: columnLeftWidthGetter, - }); - this.topLeftGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { - self.bottomLeftGrid.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.topRightGrid = BI.createWidget({ - type: "bi.grid_view", - rowHeightGetter: rowHeightGetter, - columnWidthGetter: columnRightWidthGetter, - }); - this.topRightGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { - self.bottomRightGrid.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.bottomLeftGrid = BI.createWidget({ - type: "bi.grid_view", - rowHeightGetter: rowHeightGetter, - columnWidthGetter: columnLeftWidthGetter, - }); - this.bottomLeftGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { - self.bottomRightGrid.setScrollTop(scroll.scrollTop); - self.topLeftGrid.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.bottomRightGrid = BI.createWidget({ - type: "bi.grid_view", - rowHeightGetter: rowHeightGetter, - columnWidthGetter: columnRightWidthGetter, - }); - this.bottomRightGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { - self.bottomLeftGrid.setScrollTop(scroll.scrollTop); - self.topRightGrid.setScrollLeft(scroll.scrollLeft); - self._populateScrollbar(); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.topLeft = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.topLeftGrid] - }); - this.topRight = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.topRightGrid] - }); - this.bottomLeft = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.bottomLeftGrid] - }); - this.bottomRight = BI.createWidget({ - type: "bi.vertical", - scrollable: false, - scrolly: false, - items: [this.bottomRightGrid] - }); - this.contextLayout = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.topLeft, - top: 0, - left: 0 - }, { - el: this.topRight, - top: 0 - }, { - el: this.bottomLeft, - left: 0 - }, { - el: this.bottomRight - }] - }); + return result; + } - this.topScrollbar = BI.createWidget({ - type: "bi.grid_table_scrollbar", - width: BI.GridTableScrollbar.SIZE - }); - this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { - self.bottomLeftGrid.setScrollTop(scrollTop); - self.bottomRightGrid.setScrollTop(scrollTop); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.leftScrollbar = BI.createWidget({ - type: "bi.grid_table_horizontal_scrollbar", - height: BI.GridTableScrollbar.SIZE - }); - this.leftScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { - self.topLeftGrid.setScrollLeft(scrollLeft); - self.bottomLeftGrid.setScrollLeft(scrollLeft); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.rightScrollbar = BI.createWidget({ - type: "bi.grid_table_horizontal_scrollbar", - height: BI.GridTableScrollbar.SIZE - }); - this.rightScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { - self.topRightGrid.setScrollLeft(scrollLeft); - self.bottomRightGrid.setScrollLeft(scrollLeft); - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }); - this.scrollBarLayout = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.topScrollbar, - right: 0, - top: 0 - }, { - el: this.leftScrollbar, - left: 0 - }, { - el: this.rightScrollbar, - }] - }); - this._width = o.width - BI.GridTableScrollbar.SIZE; - this._height = o.height - BI.GridTableScrollbar.SIZE; - this.header = this._getHeader(); - this.items = this._getItems(); - if (o.items.length > 0) { - this._populate(); - } - }, + // Work around problem with bounding client rects on ranges being + // returned incorrectly when zoomed on IE10 and below. + function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + return rect; + var scaleX = screen.logicalXDPI / screen.deviceXDPI; + var scaleY = screen.logicalYDPI / screen.deviceYDPI; + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY}; + } - _getFreezeColLength: function () { - return this.options.isNeedFreeze ? this.options.freezeCols.length : 0; - }, + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {}; + } + } - _populateScrollbar: function () { - var o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); - this.topScrollbar.setContentSize(o.items.length * o.rowSize); - this.topScrollbar.setSize(this._height - o.header.length * o.headerRowSize); - this.topScrollbar.setPosition(Math.min(this.bottomLeftGrid.getScrollTop(), this.bottomRightGrid.getScrollTop())); - this.topScrollbar.populate(); + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]); + } - this.leftScrollbar.setContentSize(totalLeftColumnSize); - this.leftScrollbar.setSize(regionSize); - this.leftScrollbar.setPosition(this.bottomLeftGrid.getScrollLeft()); - this.leftScrollbar.populate(); + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } - this.rightScrollbar.setContentSize(totalRightColumnSize); - this.rightScrollbar.setSize(this._width - regionSize); - this.rightScrollbar.setPosition(this.bottomRightGrid.getScrollLeft()); - this.rightScrollbar.populate(); + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - var items = this.scrollBarLayout.attr("items"); - items[0].top = o.header.length * o.headerRowSize; - items[1].top = this._height; - items[2].top = this._height; - items[2].left = regionSize; - this.scrollBarLayout.attr("items", items); - this.scrollBarLayout.resize(); - }, + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"/null (editor), "window", + // or "page". + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } - _getHeader: function () { - var o = this.options; - var freezeColLength = this._getFreezeColLength(); - var leftHeader = [], rightHeader = []; - BI.each(o.header, function (i, cols) { - leftHeader[i] = []; - rightHeader[i] = []; - BI.each(cols, function (j, col) { - var cell = { - type: "bi.grid_table_cell", - cell: col - }; - if (j < freezeColLength) { - leftHeader[i].push(cell); - } else { - rightHeader[i].push(cell); - } - }); - }); - return [leftHeader, rightHeader]; - }, + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"/null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } - _getItems: function () { - var o = this.options; - var freezeColLength = this._getFreezeColLength(); - var leftItems = [], rightItems = []; - BI.each(o.items, function (i, cols) { - leftItems[i] = []; - rightItems[i] = []; - BI.each(cols, function (j, col) { - var cell = { - type: "bi.grid_table_cell", - cell: col - }; - if (j < freezeColLength) { - leftItems[i].push(cell); - } else { - rightItems[i].push(cell); - } - }); - }); - return [leftItems, rightItems]; - }, + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; + } - _populateTable: function () { - var self = this, o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); + } - var tlw = regionSize; - var tlh = regionSize >= summaryColumnSizeArray[freezeColLength - 1] ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); - var trw = this._width - regionSize; - var trh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); - var blw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? regionSize : (regionSize + this._scrollBarSize); - var blh = (regionSize >= (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); - var brw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? (this._width - regionSize) : (this._width - regionSize + this._scrollBarSize); - var brh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } - var otlw = regionSize; - var otlh = o.header.length * o.headerRowSize; - var otrw = this._width - regionSize; - var otrh = o.header.length * o.headerRowSize; - var oblw = regionSize; - var oblh = this._height - o.header.length * o.headerRowSize; - var obrw = this._width - regionSize; - var obrh = this._height - o.header.length * o.headerRowSize; + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0, pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return {left: left, right: left, top: top, bottom: top + lineObj.height}; + } - var digest = function (w, h, tw, th, el) { - if (w >= tw && h >= th) { - el.element.css({ - overflow: "hidden", - overflowX: "hidden", - overflowY: "hidden" - }) - } else if (w >= tw) { - el.element.css({ - overflow: "hidden", - overflowX: "hidden", - overflowY: "auto" - }) - } else if (h >= th) { - el.element.css({ - overflow: "hidden", - overflowX: "auto", - overflowY: "hidden" - }) - } else { - el.element.css({ - overflow: "auto", - overflowX: "auto", - overflowY: "auto" - }) - } - }; + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, outside, xRel) { + var pos = Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } - this.topLeft.setWidth(otlw); - this.topLeft.setHeight(otlh); - this.topRight.setWidth(otrw); - this.topRight.setHeight(otrh); - this.bottomLeft.setWidth(oblw); - this.bottomLeft.setHeight(oblh); - this.bottomRight.setWidth(obrw); - this.bottomRight.setHeight(obrh); + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; - this.topLeftGrid.setWidth(tlw); - this.topLeftGrid.setHeight(tlh); - this.topRightGrid.setWidth(trw); - this.topRightGrid.setHeight(trh); - this.bottomLeftGrid.setWidth(blw); - this.bottomLeftGrid.setHeight(blh); - this.bottomRightGrid.setWidth(brw); - this.bottomRightGrid.setHeight(brh); + var lineObj = getLine(doc, lineN); + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(0, true); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line); + else + return found; + } + } - digest(tlw, tlh, totalLeftColumnSize, o.header.length * o.headerRowSize, this.topLeftGrid); - digest(trw, trh, totalRightColumnSize, o.header.length * o.headerRowSize, this.topRightGrid); - digest(blw, blh, totalLeftColumnSize, o.items.length * o.rowSize, this.bottomLeftGrid); - digest(brw, brh, totalRightColumnSize, o.items.length * o.rowSize, this.bottomRightGrid); + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var preparedMeasure = prepareMeasureForLine(cm, lineObj); - this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); - this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); - this.topRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); - this.topRightGrid.setEstimatedRowSize(o.headerRowSize); - this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); - this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); - this.bottomRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); - this.bottomRightGrid.setEstimatedRowSize(o.rowSize); + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } - var items = this.contextLayout.attr("items"); - items[1].left = regionSize; - items[2].top = o.header.length * o.headerRowSize; - items[3].left = regionSize; - items[3].top = o.header.length * o.headerRowSize; - this.contextLayout.attr("items", items); - this.contextLayout.resize(); + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - this.topLeftGrid.populate(this.header[0]); - this.topRightGrid.populate(this.header[1]); - this.bottomLeftGrid.populate(this.items[0]); - this.bottomRightGrid.populate(this.items[1]); - }, + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (;;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var xDiff = x - (ch == from ? fromX : toX); + while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, + xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} + else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} + } + } - _populate: function () { - if (this._width <= 0 || this._height <= 0) { - return; - } - this._populateTable(); - this._populateScrollbar(); - }, + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } - getRegionSize: function () { - var o = this.options; - var regionSize = o.regionColumnSize[0] || 0; - if (o.isNeedFreeze === false || o.freezeCols.length === 0) { - return 0; - } - if (!regionSize) { - BI.each(o.freezeCols, function (i, col) { - regionSize += o.columnSize[col]; - }); - } - return regionSize; - }, + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } - setVerticalScroll: function (scrollTop) { - this.bottomLeftGrid.setScrollTop(scrollTop); - this.bottomRightGrid.setScrollTop(scrollTop); - }, + // OPERATIONS - setLeftHorizontalScroll: function (scrollLeft) { - this.topLeftGrid.setScrollLeft(scrollLeft); - this.bottomLeftGrid.setScrollLeft(scrollLeft); - }, + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. - setRightHorizontalScroll: function (scrollLeft) { - this.topRightGrid.setScrollLeft(scrollLeft); - this.bottomRightGrid.setScrollLeft(scrollLeft); - }, + var operationGroup = null; - getVerticalScroll: function () { - return this.bottomRightGrid.getScrollTop(); - }, + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + }; + if (operationGroup) { + operationGroup.ops.push(cm.curOp); + } else { + cm.curOp.ownsGroup = operationGroup = { + ops: [cm.curOp], + delayedCallbacks: [] + }; + } + } - getLeftHorizontalScroll: function () { - return this.bottomLeftGrid.getScrollLeft(); - }, + function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0; + do { + for (; i < callbacks.length; i++) + callbacks[i](); + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j]; + if (op.cursorActivityHandlers) + while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm); + } + } while (i < callbacks.length); + } - getRightHorizontalScroll: function () { - return this.bottomRightGrid.getScrollLeft(); - }, + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp, group = op.ownsGroup; + if (!group) return; - setWidth: function (width) { - BI.GridTable.superclass.setWidth.apply(this, arguments); - this._width = this.options.width - BI.GridTableScrollbar.SIZE; - }, + try { fireCallbacksForOps(group); } + finally { + operationGroup = null; + for (var i = 0; i < group.ops.length; i++) + group.ops[i].cm.curOp = null; + endOperations(group); + } + } - setHeight: function (height) { - BI.GridTable.superclass.setHeight.apply(this, arguments); - this._height = this.options.height - BI.GridTableScrollbar.SIZE; - }, + // The DOM updates done when an operation finishes are batched so + // that the minimum number of relayouts are required. + function endOperations(group) { + var ops = group.ops; + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R1(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W1(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R2(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W2(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_finish(ops[i]); + } - setColumnSize: function (columnSize) { - this.options.columnSize = columnSize; - }, + function endOperation_R1(op) { + var cm = op.cm, display = cm.display; + maybeClipScrollbars(cm); + if (op.updateMaxLine) findMaxLine(cm); - setRegionColumnSize: function (regionColumnSize) { - this.options.regionColumnSize = regionColumnSize; - }, + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping; + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); + } - getColumnSize: function () { - return this.options.columnSize; - }, + function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); + } - getRegionColumnSize: function () { - return this.options.regionColumnSize; - }, + function endOperation_R2(op) { + var cm = op.cm, display = cm.display; + if (op.updatedDisplay) updateHeightsInViewport(cm); - populate: function (items, header) { - if (items && this.options.items !== items) { - this.options.items = items; - this.items = this._getItems(); - this._restore(); - } - if (header && this.options.header !== header) { - this.options.header = header; - this.header = this._getHeader(); - this._restore(); - } - this._populate(); - }, + op.barMeasure = measureForScrollbars(cm); - _restore: function () { - this.topLeftGrid.restore(); - this.topRightGrid.restore(); - this.bottomLeftGrid.restore(); - this.bottomRightGrid.restore(); - }, + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; + cm.display.sizerWidth = op.adjustWidthTo; + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); + } - restore: function () { - this._restore(); + if (op.updatedDisplay || op.selectionChanged) + op.preparedSelection = display.input.prepareSelection(); + } + + function endOperation_W2(op) { + var cm = op.cm; + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; + if (op.maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); + cm.display.maxLineChanged = false; } -}); -$.shortcut('bi.grid_table', BI.GridTable);/** - * QuickGridTable - * - * Created by GUY on 2016/1/12. - * @class BI.QuickGridTable - * @extends BI.GridTable - */ -BI.QuickGridTable = BI.inherit(BI.GridTable, { - _defaultConfig: function () { - return BI.extend(BI.QuickGridTable.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-quick-grid-table" - }); - }, - _init: function () { - BI.QuickGridTable.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.topLeftGrid.setOverflowX(false); - this.topLeftGrid.setOverflowY(false); - this.topRightGrid.setOverflowX(false); - this.topRightGrid.setOverflowY(false); - this.bottomLeftGrid.setOverflowX(false); - this.bottomLeftGrid.setOverflowY(false); - this.bottomRightGrid.setOverflowX(false); - this.bottomRightGrid.setOverflowY(false); - this._leftWheelHandler = new BI.WheelHandler( - BI.bind(this._onWheelY, this), - BI.bind(this._shouldHandleX, this), - BI.bind(this._shouldHandleY, this) - ); - this._rightWheelHandler = new BI.WheelHandler( - BI.bind(this._onWheelY, this), - BI.bind(this._shouldHandleX, this), - BI.bind(this._shouldHandleY, this) - ); - this.bottomLeftGrid.element.mousewheel(function (e) { - self._leftWheelHandler.onWheel(e.originalEvent); - }); - this.bottomRightGrid.element.mousewheel(function (e) { - self._rightWheelHandler.onWheel(e.originalEvent); - }); - }, + if (op.preparedSelection) + cm.display.input.showSelection(op.preparedSelection); + if (op.updatedDisplay) + setDocumentHeight(cm, op.barMeasure); + if (op.updatedDisplay || op.startHeight != cm.doc.height) + updateScrollbars(cm, op.barMeasure); - _shouldHandleX: function (delta) { - return false; - }, + if (op.selectionChanged) restartBlink(cm); - _shouldHandleY: function (delta) { - if (delta > 0) { - return this.bottomRightGrid.getScrollTop() < this.bottomRightGrid.getMaxScrollTop(); - } else { - return this.bottomRightGrid.getScrollTop() > 0; - } - }, + if (cm.state.focused && op.updateInput) + cm.display.input.reset(op.typing); + if (op.focus && op.focus == activeElt()) ensureFocus(op.cm); + } - _onWheelY: function (deltaX, deltaY) { - var self = this; - var scrollTop = this.bottomRightGrid.getScrollTop(); - scrollTop += deltaY; - this.bottomLeftGrid.setScrollTop(scrollTop); - this.bottomRightGrid.setScrollTop(scrollTop); - self._populateScrollbar(); - this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); - }, + function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc; - _populateTable: function () { - var self = this, o = this.options; - var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; - var freezeColLength = this._getFreezeColLength(); - BI.each(o.columnSize, function (i, size) { - if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { - totalLeftColumnSize += size; - } else { - totalRightColumnSize += size; - } - totalColumnSize += size; - if (i === 0) { - summaryColumnSizeArray[i] = size; - } else { - summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; - } - }); + if (op.updatedDisplay) postUpdateDisplay(cm, op.update); - var otlw = regionSize; - var otlh = o.header.length * o.headerRowSize; - var otrw = this._width - regionSize; - var otrh = o.header.length * o.headerRowSize; - var oblw = regionSize; - var oblh = this._height - o.header.length * o.headerRowSize; - var obrw = this._width - regionSize; - var obrh = this._height - o.header.length * o.headerRowSize; + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + display.wheelStartX = display.wheelStartY = null; - this.topLeft.setWidth(otlw); - this.topLeft.setHeight(otlh); - this.topRight.setWidth(otrw); - this.topRight.setHeight(otrh); - this.bottomLeft.setWidth(oblw); - this.bottomLeft.setHeight(oblh); - this.bottomRight.setWidth(obrw); - this.bottomRight.setHeight(obrh); + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { + doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); + display.scrollbars.setScrollTop(doc.scrollTop); + display.scroller.scrollTop = doc.scrollTop; + } + if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { + doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft)); + display.scrollbars.setScrollLeft(doc.scrollLeft); + display.scroller.scrollLeft = doc.scrollLeft; + alignHorizontally(cm); + } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); + if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); + } - this.topLeftGrid.setWidth(otlw); - this.topLeftGrid.setHeight(otlh); - this.topRightGrid.setWidth(otrw); - this.topRightGrid.setHeight(otrh); - this.bottomLeftGrid.setWidth(oblw); - this.bottomLeftGrid.setHeight(oblh); - this.bottomRightGrid.setWidth(obrw); - this.bottomRightGrid.setHeight(obrh); + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); - this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); - this.topRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); - this.topRightGrid.setEstimatedRowSize(o.headerRowSize); - this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); - this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); - this.bottomRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); - this.bottomRightGrid.setEstimatedRowSize(o.rowSize); + if (display.wrapper.offsetHeight) + doc.scrollTop = cm.display.scroller.scrollTop; - var items = this.contextLayout.attr("items"); - items[1].left = regionSize; - items[2].top = o.header.length * o.headerRowSize; - items[3].left = regionSize; - items[3].top = o.header.length * o.headerRowSize; - this.contextLayout.attr("items", items); - this.contextLayout.resize(); + // Fire change events, and delayed event handlers + if (op.changeObjs) + signal(cm, "changes", cm, op.changeObjs); + if (op.update) + op.update.finish(); + } - var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; - BI.each(o.header, function (i, cols) { - leftHeader[i] = []; - rightHeader[i] = []; - BI.each(cols, function (j, col) { - var cell = { - type: "bi.grid_table_cell", - cell: col - }; - if (j < freezeColLength) { - leftHeader[i].push(cell); - } else { - rightHeader[i].push(cell); - } - }); - }); - BI.each(o.items, function (i, cols) { - leftItems[i] = []; - rightItems[i] = []; - BI.each(cols, function (j, col) { - var cell = { - type: "bi.grid_table_cell", - cell: col - }; - if (j < freezeColLength) { - leftItems[i].push(cell); - } else { - rightItems[i].push(cell); - } - }); - }); - this.topLeftGrid.populate(leftHeader); - this.topRightGrid.populate(rightHeader); - this.bottomLeftGrid.populate(leftItems); - this.bottomRightGrid.populate(rightItems); - } -}); -$.shortcut('bi.quick_grid_table', BI.QuickGridTable);/** - * - * 表格滚动条 - * - * Created by GUY on 2016/1/12. - * @class BI.GridTableScrollbar - * @extends BI.Widget - */ -BI.GridTableScrollbar = BI.inherit(BI.Widget, { - _const: { - FACE_MARGIN: 4, - FACE_MARGIN_2: 4 * 2, - FACE_SIZE_MIN: 30, - KEYBOARD_SCROLL_AMOUNT: 40 - }, - _defaultConfig: function () { - return BI.extend(BI.GridTableScrollbar.superclass._defaultConfig.apply(this, arguments), { - baseCls: "scrollbar-layout-main public-scrollbar-main", - attributes: { - tabIndex: 0 - }, - contentSize: 0, - defaultPosition: 0, - isOpaque: false, - orientation: "vertical", - position: 0, - size: 0 - }) - }, + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) return f(); + startOperation(cm); + try { return f(); } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function() { + if (cm.curOp) return f.apply(cm, arguments); + startOperation(cm); + try { return f.apply(cm, arguments); } + finally { endOperation(cm); } + }; + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function() { + if (this.curOp) return f.apply(this, arguments); + startOperation(this); + try { return f.apply(this, arguments); } + finally { endOperation(this); } + }; + } + function docMethodOp(f) { + return function() { + var cm = this.cm; + if (!cm || cm.curOp) return f.apply(this, arguments); + startOperation(cm); + try { return f.apply(this, arguments); } + finally { endOperation(cm); } + }; + } - _init: function () { - BI.GridTableScrollbar.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.focused = false; - this.isDragging = false; - this.face = BI.createWidget({ - type: "bi.layout", - cls: "scrollbar-layout-face public-scrollbar-face " - + (this._isHorizontal() ? "scrollbar-layout-face-horizontal" : "scrollbar-layout-face-vertical") - }); - this.contextLayout = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.face, - left: 0, - top: 0 - }] - }); - var onWheel = o.orientation === 'horizontal' ? this._onWheelX : this._onWheelY; - this._wheelHandler = new BI.WheelHandler( - BI.bind(onWheel, this), - BI.bind(this._shouldHandleX, this), - BI.bind(this._shouldHandleY, this) - ); - this._mouseMoveTracker = new BI.MouseMoveTracker( - BI.bind(this._onMouseMove, this), - BI.bind(this._onMouseMoveEnd, this), - document - ); - this.element.on("mousedown", BI.bind(this._onMouseDown, this)); - this.element.on("mousewheel", function (e) { - self._wheelHandler.onWheel(e.originalEvent); - }); - this.element.on("keydown", BI.bind(this._onKeyDown, this)); - this.element.on("focus", function () { - self.focused = true; - self._populate(); - }); - this.element.on("blur", function () { - self.focused = false; - self._populate(); - }); - if (this._isHorizontal()) { - this.element.addClass("scrollbar-layout-main-horizontal"); - } else { - this.element.addClass("scrollbar-layout-main-vertical"); - } - this._populate(); - }, - - _isHorizontal: function () { - return this.options.orientation === 'horizontal' - }, - - _getScale: function () { - var o = this.options; - var scale = o.size / o.contentSize; - var faceSize = o.size * scale; + // VIEW TRACKING - if (faceSize < this._const.FACE_SIZE_MIN) { - scale = (o.size - this._const.FACE_SIZE_MIN) / (o.contentSize - o.size); - } - return scale; - }, + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } - _getFaceSize: function () { - var o = this.options; - var scale = o.size / o.contentSize; - var faceSize = o.size * scale; + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array; + } - if (faceSize < this._const.FACE_SIZE_MIN) { - faceSize = this._const.FACE_SIZE_MIN; - } - return faceSize; - }, + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + if (!lendiff) lendiff = 0; - _shouldHandleX: function (delta) { - return this.options.orientation === 'horizontal' ? - this._shouldHandleChange(delta) : - false; - }, + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from; - _shouldHandleY: function (delta) { - return this.options.orientation !== 'horizontal' ? - this._shouldHandleChange(delta) : - false; - }, + cm.curOp.viewChanged = true; - _shouldHandleChange: function (delta) { - return this.options.position + delta !== this.options.position; - }, + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm); + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut = viewCuttingPoint(cm, from, from, -1); + if (cut) { + display.view = display.view.slice(0, cut.index); + display.viewTo = cut.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } - _onWheelY: function (deltaX, deltaY) { - this._onWheel(deltaY); - }, + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff; + else if (from < ext.lineN + ext.size) + display.externalMeasured = null; + } + } - _onWheelX: function (deltaX, deltaY) { - this._onWheel(deltaX); - }, + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null; - _onWheel: function (delta) { - var maxPosition = this.options.contentSize - this.options.size; - this.options.position += delta; - if (this.options.position < 0) { - this.options.position = 0; - } else if (this.options.position > maxPosition) { - this.options.position = maxPosition; - } - this._populate(); - this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); - }, + if (line < display.viewFrom || line >= display.viewTo) return; + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) return; + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) arr.push(type); + } - _onMouseDown: function (e) { - if (e.target !== this.face.element[0]) { - var position = this._isHorizontal() ? e.offsetX : e.offsetY; - position /= this._getScale(); - this.options.position = BI.clamp(position - (this._getFaceSize() * 0.5 / this._getScale()), 0, this.options.contentSize - this.options.size); - this._populate(); - this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); - } else { - this._mouseMoveTracker.captureMouseMoves(e); - } - this.element[0].focus(); - }, + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } - _onMouseMove: function (deltaX, deltaY) { - var delta = this._isHorizontal() ? deltaX : deltaY; - delta /= this._getScale(); - this.options.position = BI.clamp(this.options.position + delta, 0, this.options.contentSize - this.options.size); - this.isDragging = this._mouseMoveTracker.isDragging(); - this._populate(); - this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); - }, + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null; + n -= cm.display.viewFrom; + if (n < 0) return null; + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) return i; + } + } - _onMouseMoveEnd: function (event) { - this._mouseMoveTracker.releaseMouseMoves(); - if (this.isDragging === true) { - this.isDragging = false; - this._populate(); - } - }, + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + return {index: index, lineN: newN}; + for (var i = 0, n = cm.display.viewFrom; i < index; i++) + n += view[i].size; + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null; + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null; + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return {index: index, lineN: newN}; + } - _onKeyDown: function (event) { - var Keys = { - BACKSPACE: 8, - TAB: 9, - RETURN: 13, - ALT: 18, - ESC: 27, - SPACE: 32, - PAGE_UP: 33, - PAGE_DOWN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - DELETE: 46, - COMMA: 188, - PERIOD: 190, - A: 65, - Z: 90, - ZERO: 48, - NUMPAD_0: 96, - NUMPAD_9: 105 - }; - var keyCode = event.keyCode; - - if (keyCode === Keys.TAB) { - return; - } - - var distance = 40; - var direction = 0; + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)); + display.viewFrom = from; + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)); + } + display.viewTo = to; + } - if (this._isHorizontal()) { - switch (keyCode) { - case Keys.HOME: - direction = -1; - distance = this.options.contentSize; - break; + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; + } + return dirty; + } - case Keys.LEFT: - direction = -1; - break; + // EVENT HANDLERS - case Keys.RIGHT: - direction = 1; - break; + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + on(d.scroller, "dblclick", operation(cm, function(e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = cm.findWordAt(pos); + extendSelection(cm.doc, word.anchor, word.head); + })); + else + on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); - default: - return; - } + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = {end: 0}; + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); + prevTouch = d.activeTouch; + prevTouch.end = +new Date; + } + }; + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) return false; + var touch = e.touches[0]; + return touch.radiusX <= 1 && touch.radiusY <= 1; + } + function farAway(touch, other) { + if (other.left == null) return true; + var dx = other.left - touch.left, dy = other.top - touch.top; + return dx * dx + dy * dy > 20 * 20; + } + on(d.scroller, "touchstart", function(e) { + if (!isMouseLikeTouchEvent(e)) { + clearTimeout(touchFinished); + var now = +new Date; + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null}; + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX; + d.activeTouch.top = e.touches[0].pageY; } + } + }); + on(d.scroller, "touchmove", function() { + if (d.activeTouch) d.activeTouch.moved = true; + }); + on(d.scroller, "touchend", function(e) { + var touch = d.activeTouch; + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range; + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + range = new Range(pos, pos); + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + range = cm.findWordAt(pos); + else // Triple tap + range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); + cm.setSelection(range.anchor, range.head); + cm.focus(); + e_preventDefault(e); + } + finishTouch(); + }); + on(d.scroller, "touchcancel", finishTouch); - if (!this._isHorizontal()) { - switch (keyCode) { - case Keys.SPACE: - if (event.shiftKey) { - direction = -1; - } else { - direction = 1; - } - break; - - case Keys.HOME: - direction = -1; - distance = this.options.contentSize; - break; + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function() { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); - case Keys.UP: - direction = -1; - break; + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); + on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); - case Keys.DOWN: - direction = 1; - break; + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - case Keys.PAGE_UP: - direction = -1; - distance = this.options.size; - break; + d.dragFunctions = { + simple: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);}, + start: function(e){onDragStart(cm, e);}, + drop: operation(cm, onDrop) + }; - case Keys.PAGE_DOWN: - direction = 1; - distance = this.options.size; - break; + var inp = d.input.getField(); + on(inp, "keyup", function(e) { onKeyUp.call(cm, e); }); + on(inp, "keydown", operation(cm, onKeyDown)); + on(inp, "keypress", operation(cm, onKeyPress)); + on(inp, "focus", bind(onFocus, cm)); + on(inp, "blur", bind(onBlur, cm)); + } - default: - return; - } - } + function dragDropChanged(cm, value, old) { + var wasOn = old && old != CodeMirror.Init; + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions; + var toggle = value ? on : off; + toggle(cm.display.scroller, "dragstart", funcs.start); + toggle(cm.display.scroller, "dragenter", funcs.simple); + toggle(cm.display.scroller, "dragover", funcs.simple); + toggle(cm.display.scroller, "drop", funcs.drop); + } + } - this.options.position = BI.clamp(this.options.position + (distance * direction), 0, this.options.contentSize - this.options.size); - event.preventDefault(); - this._populate(); - this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); - }, + // Called when the window resizes + function onResize(cm) { + var d = cm.display; + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + return; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + d.scrollbarsClipped = false; + cm.setSize(); + } - _populate: function () { - var self = this, o = this.options; - if (o.size < 1 || o.contentSize <= o.size) { - this.setVisible(false); - return; - } - this.setVisible(true); + // MOUSE EVENTS - var size = o.size; - var isHorizontal = this._isHorizontal(); - var isActive = this.focused || this.isDragging; + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + return true; + } + } - var faceSize = this._getFaceSize(); - var isOpaque = o.isOpaque; - this.element[isOpaque === true ? "addClass" : "removeClass"]("public-scrollbar-main-opaque"); - this.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-main-active"); - - this.face.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-face-active"); - - var position = o.position * this._getScale() + this._const.FACE_MARGIN; - - var items = this.contextLayout.attr("items"); - if (isHorizontal) { - this.setWidth(size); - this.face.setWidth(faceSize - this._const.FACE_MARGIN_2); - items[0].left = position; - items[0].top = 0; - } else { - this.setHeight(size); - this.face.setHeight(faceSize - this._const.FACE_MARGIN_2); - items[0].left = 0; - items[0].top = position; - } - this.contextLayout.attr("items", items); - this.contextLayout.resize(); - }, - - setContentSize: function (contentSize) { - this.options.contentSize = contentSize; - }, + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; - setPosition: function (position) { - this.options.position = position; - }, + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e) { return null; } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); + } + return coords; + } - setSize: function (size) { - this.options.size = size; - }, + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + var cm = this, display = cm.display; + if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return; + display.shift = e.shiftKey; - populate: function () { - this._populate(); + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function(){display.scroller.draggable = true;}, 100); + } + return; } -}); -BI.GridTableScrollbar.SIZE = 10; -BI.GridTableScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; -$.shortcut("bi.grid_table_scrollbar", BI.GridTableScrollbar); + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + window.focus(); + switch (e_button(e)) { + case 1: + if (start) + leftButtonDown(cm, e, start); + else if (e_target(e) == display.scroller) + e_preventDefault(e); + break; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(function() {display.input.focus();}, 20); + e_preventDefault(e); + break; + case 3: + if (captureRightClick) onContextMenu(cm, e); + else delayBlurEvent(cm); + break; + } + } -BI.GridTableHorizontalScrollbar = BI.inherit(BI.Widget, { - _const: { - FACE_MARGIN: 4, - FACE_MARGIN_2: 4 * 2, - FACE_SIZE_MIN: 30, - KEYBOARD_SCROLL_AMOUNT: 40 - }, - _defaultConfig: function () { - return BI.extend(BI.GridTableHorizontalScrollbar.superclass._defaultConfig.apply(this, arguments), { - attributes: { - tabIndex: 0 - }, - contentSize: 0, - position: 0, - size: 0 - }) - }, + var lastClick, lastDoubleClick; + function leftButtonDown(cm, e, start) { + if (ie) setTimeout(bind(ensureFocus, cm), 0); + else cm.curOp.focus = activeElt(); - _init: function () { - BI.GridTableHorizontalScrollbar.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.scrollbar = BI.createWidget({ - type: "bi.grid_table_scrollbar", - orientation: "horizontal", - isOpaque: true, - position: o.position, - contentSize: o.contentSize, - size: o.size - }); - this.scrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function () { - self.fireEvent(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, arguments); - }); - BI.createWidget({ - type: "bi.absolute", - cls: "horizontal-scrollbar", - element: this, - width: o.size, - height: BI.GridTableScrollbar.SIZE, - items: [{ - el: { - type: "bi.absolute", - scrollable: false, - height: BI.GridTableScrollbar.SIZE, - items: [{ - el: this.scrollbar, - left: 0, - top: 0 - }] - }, - top: 0, - left: 0, - right: 0 - }] - }); - }, + var now = +new Date, type; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { + type = "triple"; + } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { + type = "double"; + lastDoubleClick = {time: now, pos: start}; + } else { + type = "single"; + lastClick = {time: now, pos: start}; + } - setContentSize: function (contentSize) { - this.options.contentSize = contentSize; - this.scrollbar.setContentSize(contentSize); - }, + var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; + if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && + type == "single" && (contained = sel.contains(start)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && + (cmp(contained.to(), start) > 0 || start.xRel < 0)) + leftButtonStartDrag(cm, e, start, modifier); + else + leftButtonSelect(cm, e, start, type, modifier); + } - setPosition: function (position) { - this.options.position = position; - this.scrollbar.setPosition(position); - }, + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, e, start, modifier) { + var display = cm.display, startTime = +new Date; + var dragEnd = operation(cm, function(e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + if (!modifier && +new Date - 200 < startTime) + extendSelection(cm.doc, start); + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + setTimeout(function() {document.body.focus(); display.input.focus();}, 20); + else + display.input.focus(); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + } - setSize: function (size) { - this.setWidth(size); - this.options.size = size; - this.scrollbar.setSize(size); - }, + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, e, start, type, addNew) { + var display = cm.display, doc = cm.doc; + e_preventDefault(e); - populate: function () { - this.scrollbar.populate(); + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; + if (addNew && !e.shiftKey) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + ourRange = ranges[ourIndex]; + else + ourRange = new Range(start, start); + } else { + ourRange = doc.sel.primary(); + ourIndex = doc.sel.primIndex; } -}); -BI.GridTableHorizontalScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; -$.shortcut("bi.grid_table_horizontal_scrollbar", BI.GridTableHorizontalScrollbar);/** - * - * 表格 - * - * Created by GUY on 2015/9/22. - * @class BI.TableHeaderCell - * @extends BI.Single - */ -BI.TableHeaderCell = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.TableHeaderCell.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-table-header-cell", - text: "" - }) - }, - _init: function () { - BI.TableHeaderCell.superclass._init.apply(this, arguments); - BI.createWidget({ - type: "bi.label", - element: this, - textAlign: "center", - height: this.options.height, - text: this.options.text, - value: this.options.value - }) - } -}); + if (e.altKey) { + type = "rect"; + if (!addNew) ourRange = new Range(start, start); + start = posFromMouse(cm, e, true, true); + ourIndex = -1; + } else if (type == "double") { + var word = cm.findWordAt(start); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, word.anchor, word.head); + else + ourRange = word; + } else if (type == "triple") { + var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, line.anchor, line.head); + else + ourRange = line; + } else { + ourRange = extendRange(doc, ourRange, start); + } -$.shortcut("bi.table_header_cell", BI.TableHeaderCell);/** - * - * 表格 - * - * 能处理静态宽度以及动态宽度的表, 百分比宽度的表请使用PreviewTable - * - * Created by GUY on 2015/9/22. - * @class BI.Table - * @extends BI.Widget - */ -BI.Table = BI.inherit(BI.Widget, { + if (!addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + startSel = doc.sel; + } else if (ourIndex == -1) { + ourIndex = ranges.length; + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}); + } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0)); + startSel = doc.sel; + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } - _defaultConfig: function () { - return BI.extend(BI.Table.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-table", - logic: { //冻结的页面布局逻辑 - dynamic: false - }, + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return; + lastPos = pos; - isNeedResize: false,//是否需要调整列宽 - isResizeAdapt: true,//是否需要在调整列宽或区域宽度的时候它们自适应变化 + if (type == "rect") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); + } + if (!ranges.length) ranges.push(new Range(start, start)); + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}); + cm.scrollIntoView(pos); + } else { + var oldRange = ourRange; + var anchor = oldRange.anchor, head = pos; + if (type != "single") { + if (type == "double") + var range = cm.findWordAt(pos); + else + var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + } + var ranges = startSel.ranges.slice(0); + ranges[ourIndex] = new Range(clipPos(doc, anchor), head); + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); + } + } - isNeedFreeze: false,//是否需要冻结单元格 - freezeCols: [], //冻结的列号,从0开始,isNeedFreeze为true时生效 + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; - isNeedMerge: false,//是否需要合并单元格 - mergeCols: [], //合并的单元格列号 - mergeRule: function (row1, row2) { //合并规则, 默认相等时合并 - return BI.isEqual(row1, row2); - }, + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, type == "rect"); + if (!cur) return; + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt(); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function() { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } - columnSize: [], - headerRowSize: 25, - footerRowSize: 25, - rowSize: 25, + function done(e) { + counter = Infinity; + e_preventDefault(e); + display.input.focus(); + off(document, "mousemove", move); + off(document, "mouseup", up); + doc.history.lastSelOrigin = null; + } - regionColumnSize: false, + var move = operation(cm, function(e) { + if (!e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + on(document, "mousemove", move); + on(document, "mouseup", up); + } - header: [], - footer: false, - items: [] //二维数组 - }) - }, + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent, signalfn) { + try { var mX = e.clientX, mY = e.clientY; } + catch(e) { return false; } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; + if (prevent) e_preventDefault(e); - _calculateWidth: function (width) { - if (!width || width === "0") { - return ""; - } - width = BI.parseFloat(width); - if (width < 0) { - width = 0; - } - return width > 1.01 ? width : (width * 100 + "%"); - }, + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); - _calculateHeight: function (height) { - return height ? height : ""; - }, + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; - _isRightFreeze: function () { - return BI.isNotEmptyArray(this.options.freezeCols) && BI.first(this.options.freezeCols) !== 0; - }, + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signalfn(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } - _createTopLeft: function () { - var o = this.options, isRight = this._isRightFreeze(); - this.topLeftColGroupTds = {}; - this.topLeftBodyTds = {}; - this.topLeftBodyItems = {}; - var table = this._table(); - var colgroup = this._createColGroup(this.columnLeft, this.topLeftColGroupTds); - var body = this.topLeftBody = this._body(); - body.element.append(this._createHeaderCells(this.topLeftItems, this.columnLeft, this.mergeLeft, this.topLeftBodyTds, this.topLeftBodyItems)); - BI.createWidget({ - type: "bi.adaptive", - element: table, - items: [colgroup, body] - }); - if (isRight) { - var w = 0; - BI.each(o.columnSize, function (i, col) { - if (!o.freezeCols.contains(i)) { - w += col; - } - }); - if (BI.isNumeric(w) && w > 1) { - w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; - } - } - return (this.topLeftContainer = BI.createWidget({ - type: "bi.adaptive", - width: this._calculateWidth(w), - items: [table] - })); - }, + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true, signalLater); + } - _createTopRight: function () { - var o = this.options, isRight = this._isRightFreeze(); - this.topRightColGroupTds = {}; - this.topRightBodyTds = {}; - this.topRightBodyItems = {}; - var table = this._table(); - var colgroup = this._createColGroup(this.columnRight, this.topRightColGroupTds); - var body = this.topRightBody = this._body(); - body.element.append(this._createHeaderCells(this.topRightItems, this.columnRight, this.mergeRight, this.topRightBodyTds, this.topRightBodyItems, this.columnLeft.length)); - BI.createWidget({ - type: "bi.adaptive", - element: table, - items: [colgroup, body] - }); - if (!isRight) { - var w = 0; - BI.each(o.columnSize, function (i, col) { - if (!o.freezeCols.contains(i)) { - w += col; - } - }); - if (BI.isNumeric(w)) { - w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; - } - } - return (this.topRightContainer = BI.createWidget({ - type: "bi.adaptive", - width: w || undefined, - items: [table] - })); - }, + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; - _createBottomLeft: function () { - var o = this.options, isRight = this._isRightFreeze(); - this.bottomLeftColGroupTds = {}; - this.bottomLeftBodyTds = {}; - this.bottomLeftBodyItems = {}; - var table = this._table(); - var colgroup = this._createColGroup(this.columnLeft, this.bottomLeftColGroupTds); - var body = this._createBottomLeftBody(); - BI.createWidget({ - type: "bi.adaptive", - element: table, - items: [colgroup, body] + function onDrop(e) { + var cm = this; + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return; + e_preventDefault(e); + if (ie) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || isReadOnly(cm)) return; + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function(file, i) { + var reader = new FileReader; + reader.onload = operation(cm, function() { + text[i] = reader.result; + if (++read == n) { + pos = clipPos(cm.doc, pos); + var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); + } }); - if (isRight) { - var w = 0; - BI.each(o.columnSize, function (i, col) { - if (!o.freezeCols.contains(i)) { - w += col; - } - }); - if (BI.isNumeric(w) && w > 1) { - w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; - } + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(function() {cm.display.input.focus();}, 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey)) + var selected = cm.listSelections(); + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) for (var i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); + cm.replaceSelection(text, "around", "paste"); + cm.display.input.focus(); } - return (this.bottomLeftContainer = BI.createWidget({ - type: "bi.adaptive", - width: this._calculateWidth(w), - items: [table] - })); - }, + } + catch(e){} + } + } - _createBottomLeftBody: function () { - var body = this.bottomLeftBody = this._body(); - body.element.append(this._createCells(this.bottomLeftItems, this.columnLeft, this.mergeLeft, this.bottomLeftBodyTds, this.bottomLeftBodyItems)); - return body; - }, + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - _createBottomRight: function () { - var o = this.options, isRight = this._isRightFreeze(); - this.bottomRightColGroupTds = {}; - this.bottomRightBodyTds = {}; - this.bottomRightBodyItems = {}; - var table = this._table(); - var colgroup = this._createColGroup(this.columnRight, this.bottomRightColGroupTds); - var body = this._createBottomRightBody(); - BI.createWidget({ - type: "bi.adaptive", - element: table, - items: [colgroup, body] - }); - if (!isRight) { - var w = 0; - BI.each(o.columnSize, function (i, col) { - if (!o.freezeCols.contains(i)) { - w += col; - } - }); - if (BI.isNumeric(w) && w > 1) { - w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; - } - } - return (this.bottomRightContainer = BI.createWidget({ - type: "bi.adaptive", - width: this._calculateWidth(w), - items: [table] - })); - }, + e.dataTransfer.setData("Text", cm.getSelection()); - _createBottomRightBody: function () { - var body = this.bottomRightBody = this._body(); - body.element.append(this._createCells(this.bottomRightItems, this.columnRight, this.mergeRight, this.bottomRightBodyTds, this.bottomRightBodyItems, this.columnLeft.length)); - return body; - }, + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) img.parentNode.removeChild(img); + } + } - _createFreezeTable: function () { - var self = this, o = this.options; - var isRight = this._isRightFreeze(); - var split = this._split(o.header); - this.topLeftItems = split.left; - this.topRightItems = split.right; - split = this._split(o.items); - this.bottomLeftItems = split.left; - this.bottomRightItems = split.right; + // SCROLL EVENTS - this.columnLeft = []; - this.columnRight = []; - BI.each(o.columnSize, function (i, size) { - if (o.freezeCols.contains(i)) { - self[isRight ? "columnRight" : "columnLeft"].push(size); - } else { - self[isRight ? "columnLeft" : "columnRight"].push(size); - } - }); - this.mergeLeft = []; - this.mergeRight = []; - BI.each(o.mergeCols, function (i, col) { - if (o.freezeCols.contains(col)) { - self[isRight ? "mergeRight" : "mergeLeft"].push(col); - } else { - self[isRight ? "mergeLeft" : "mergeRight"].push(col); - } - }); + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplaySimple(cm, {top: val}); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + cm.display.scrollbars.setScrollTop(val); + if (gecko) updateDisplaySimple(cm); + startWorker(cm, 100); + } + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + cm.display.scrollbars.setScrollLeft(val); + } - var topLeft = this._createTopLeft(); - var topRight = this._createTopRight(); - var bottomLeft = this._createBottomLeft(); - var bottomRight = this._createBottomRight(); + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. - this.scrollTopLeft = BI.createWidget({ - type: "bi.adaptive", - cls: "scroll-top-left", - width: "100%", - height: "100%", - scrollable: false, - items: [topLeft] - }); - this.scrollTopRight = BI.createWidget({ - type: "bi.adaptive", - cls: "scroll-top-right", - width: "100%", - height: "100%", - scrollable: false, - items: [topRight] - }); - this.scrollBottomLeft = BI.createWidget({ - type: "bi.adaptive", - cls: "scroll-bottom-left", - width: "100%", - height: "100%", - scrollable: isRight || null, - scrollx: !isRight, - items: [bottomLeft] - }); - this.scrollBottomRight = BI.createWidget({ - type: "bi.adaptive", - cls: "scroll-bottom-right", - width: "100%", - height: "100%", - scrollable: !isRight || null, - scrollx: isRight, - items: [bottomRight] - }); - this.topLeft = BI.createWidget({ - type: "bi.adaptive", - cls: "top-left", - scrollable: false, - items: [this.scrollTopLeft] - }); - this.topRight = BI.createWidget({ - type: "bi.adaptive", - cls: "top-right", - scrollable: false, - items: [this.scrollTopRight] - }); - this.bottomLeft = BI.createWidget({ - type: "bi.adaptive", - cls: "bottom-left", - // scrollable: false, - items: [this.scrollBottomLeft] - }); - this.bottomRight = BI.createWidget({ - type: "bi.adaptive", - cls: "bottom-right", - scrollable: false, - items: [this.scrollBottomRight] - }); + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1/3; - var headerHeight = o.header.length * ((o.headerRowSize || o.rowSize) + 1) + 1; - var leftWidth = BI.sum(o.freezeCols, function (i, col) { - return o.columnSize[col] > 1 ? o.columnSize[col] + 1 : o.columnSize[col]; - }); + var wheelEventDelta = function(e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + return {x: dx, y: dy}; + }; + CodeMirror.wheelEventPixels = function(e) { + var delta = wheelEventDelta(e); + delta.x *= wheelPixelsPerUnit; + delta.y *= wheelPixelsPerUnit; + return delta; + }; - if (o.isNeedResize) { - var resizer; - var createResizer = function (size, position) { - var rowSize = self.getCalculateRegionRowSize(); - resizer = BI.createWidget({ - type: "bi.layout", - cls: "bi-resizer", - width: size.width, - height: rowSize[0] + rowSize[1] - }); - BI.createWidget({ - type: "bi.absolute", - element: "body", - items: [{ - el: resizer, - left: position.left, - top: position.top - rowSize[0] - }] - }); - }; - var resizeResizer = function (size, position) { - var rowSize = self.getCalculateRegionRowSize(); - var columnSize = self.getCalculateRegionColumnSize(); - var height = rowSize[0] + rowSize[1]; - var sumSize = columnSize[0] + columnSize[1]; - if (size.width > sumSize / 5 * 4) { - size.width = sumSize / 5 * 4; - } - if (size.width < 10) { - size.width = 10; - } - resizer.element.css({ - "left": position.left + "px", - "width": size.width + "px", - "height": height + "px" - }); - }; - var stopResizer = function () { - resizer && resizer.destroy(); - resizer = null; - }; - var handle; - if (o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { - if (isRight) { - var options = { - handles: "w", - minWidth: 15, - helper: "clone", - start: function (event, ui) { - createResizer(ui.size, ui.position); - self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE); - }, - resize: function (e, ui) { - resizeResizer(ui.size, ui.position); - self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE); - e.stopPropagation(); - //return false; - }, - stop: function (e, ui) { - stopResizer(); - if (o.isResizeAdapt) { - var increment = ui.size.width - (BI.sum(self.columnRight) + self.columnRight.length); - o.columnSize[self.columnLeft.length] += increment; - } else { - self.setRegionColumnSize(["fill", ui.size.width]); - } - self._resize(); - ui.element.css("left", ""); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); - } - }; - self.bottomRight.element.resizable(options); - handle = $(".ui-resizable-handle", this.bottomRight.element).css("top", -1 * headerHeight); - } else { - var options = { - handles: "e", - minWidth: 15, - helper: "clone", - start: function (event, ui) { - createResizer(ui.size, ui.position); - self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE); - }, - resize: function (e, ui) { - resizeResizer(ui.size, ui.position); - self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE); - e.stopPropagation(); - //return false; - }, - stop: function (e, ui) { - stopResizer(); - if (o.isResizeAdapt) { - var increment = ui.size.width - (BI.sum(self.columnLeft) + self.columnLeft.length); - o.columnSize[self.columnLeft.length - 1] += increment; - } else { - self.setRegionColumnSize([ui.size.width, "fill"]); - } - self._resize(); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); - } - }; - self.bottomLeft.element.resizable(options); - handle = $(".ui-resizable-handle", this.bottomLeft.element).css("top", -1 * headerHeight); - } - } - } - this._resize = function () { - if (self.scrollBottomLeft.element.is(":visible")) { - self.scrollBottomLeft.element.css({"overflow-x": "auto"}); - self.scrollBottomRight.element.css({"overflow-x": "auto"}); - self.setColumnSize(o.columnSize); - if (isRight) { - self.scrollBottomLeft.element.css({"overflow-y": "auto"}); - } else { - self.scrollBottomRight.element.css({"overflow-y": "auto"}); - } - if (self.scrollBottomLeft.element.hasHorizonScroll() || self.scrollBottomRight.element.hasHorizonScroll()) { - self.scrollBottomLeft.element.css("overflow-x", "scroll"); - self.scrollBottomRight.element.css("overflow-x", "scroll"); - } - if (self.scrollBottomRight.element.hasVerticalScroll()) { - self.scrollTopRight.element.css("overflow-y", "scroll"); - } else { - self.scrollTopRight.element.css("overflow-y", "hidden"); - } - if (self.scrollBottomLeft.element.hasVerticalScroll()) { - self.scrollTopLeft.element.css("overflow-y", "scroll"); - } else { - self.scrollTopLeft.element.css("overflow-y", "hidden"); - } - self.scrollTopLeft.element[0].scrollLeft = self.scrollBottomLeft.element[0].scrollLeft; - self.scrollTopRight.element[0].scrollLeft = self.scrollBottomRight.element[0].scrollLeft; - self.scrollBottomLeft.element[0].scrollTop = self.scrollBottomRight.element[0].scrollTop; - //调整拖拽handle的高度 - if (o.isNeedResize) { - handle && handle.css("height", self.bottomLeft.element.height() + headerHeight); - } - } - }; + function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; - var regionColumnSize = o.regionColumnSize; - if (o.freezeCols.length === 0) { - regionColumnSize = isRight ? ['fill', 0] : [0, 'fill']; - } else if (o.freezeCols.length >= o.columnSize.length) { - regionColumnSize = isRight ? [0, 'fill'] : ['fill', 0]; - } - this.partitions = BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { - rows: 2, - columns: 2, - columnSize: regionColumnSize || (isRight ? ['fill', leftWidth] : [leftWidth, 'fill']), - rowSize: [headerHeight, 'fill'], - items: [[{ - el: this.topLeft - }, { - el: this.topRight - }], [{ - el: this.bottomLeft - }, { - el: this.bottomRight - }]] - })))); + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + if (!(dx && scroll.scrollWidth > scroll.clientWidth || + dy && scroll.scrollHeight > scroll.clientHeight)) return; - //var scrollElement = isRight ? scrollBottomLeft.element : scrollBottomRight.element; - //var scrollTopElement = isRight ? scrollTopLeft.element : scrollTopRight.element; - //var otherElement = isRight ? scrollBottomRight.element : scrollBottomLeft.element; + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer; + } + } + } + } - this._initFreezeScroll(); - BI.nextTick(function () { - if (self.element.is(":visible")) { - self._resize(); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); - } - }); - BI.Resizers.add(this.getName(), function (e) { - if (BI.isWindow(e.target) && self.element.is(":visible")) { - self._resize(); - self.fireEvent(BI.Table.EVENT_TABLE_RESIZE); - } - }); - }, + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } - _initFreezeScroll: function () { - var self = this, o = this.options; - scroll(this.scrollBottomRight.element, this.scrollTopRight.element, this.scrollBottomLeft.element); - scroll(this.scrollBottomLeft.element, this.scrollTopLeft.element, this.scrollBottomRight.element); - - function scroll(scrollElement, scrollTopElement, otherElement) { - var scrolling, scrollingX; - var fn = function (event, delta, deltaX, deltaY) { - var inf = self._getScrollOffsetAndDur(event); - if (deltaY < 0 || deltaY > 0) { - if (scrolling) { - scrollElement[0].scrollTop = scrolling; - } - scrolling = scrollElement[0].scrollTop - delta * inf.offset; - var stopPropagation = false; - var st = scrollElement[0].scrollTop; - scrollElement[0].scrollTop = scrolling; - if (scrollElement[0].scrollTop !== st) { - stopPropagation = true; - } - scrollElement[0].scrollTop = st; - self._animateScrollTo(scrollElement, scrollElement[0].scrollTop, scrolling, inf.dur, "linear", { - onStart: function () { - }, - onUpdate: function (top) { - otherElement[0].scrollTop = top; - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, top); - }, - onComplete: function () { - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrolling); - scrolling = null; - } - }); + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplaySimple(cm, {top: top, bottom: bot}); + } + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function() { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } - //otherElement[0].scrollTop = scrollTop; - //scrollElement[0].scrollTop = scrollTop; - //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); - if (stopPropagation === true) { - event.stopPropagation(); - return false; - } - return; - } - //if (deltaX < 0 || deltaX > 0) { - // if (scrollingX) { - // scrollElement[0].scrollLeft = scrollingX; - // } - // scrollingX = scrollElement[0].scrollLeft + delta * inf.offset; - // var stopPropagation = false; - // var sl = scrollElement[0].scrollLeft; - // scrollElement[0].scrollLeft = scrollingX; - // if (scrollElement[0].scrollLeft !== sl) { - // stopPropagation = true; - // } - // scrollElement[0].scrollLeft = sl; - // self._animateScrollTo(scrollElement, scrollElement[0].scrollLeft, scrollingX, inf.dur, "linear", { - // direction: "left", - // onStart: function () { - // }, - // onUpdate: function (left) { - // scrollTopElement[0].scrollLeft = left; - // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, null, left); - // }, - // onComplete: function () { - // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, null, scrollingX); - // scrollingX = null; - // } - // }); - // - // - // //otherElement[0].scrollTop = scrollTop; - // //scrollElement[0].scrollTop = scrollTop; - // //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); - // if (stopPropagation === true) { - // event.stopPropagation(); - // return false; - // } - //} - }; - scrollElement.mousewheel(fn); - var scrollTop = 0, scrollLeft = 0; - scrollElement.scroll(function (e) { - var change = false; - if (scrollElement.scrollTop() != scrollTop) { - var old = otherElement.scrollTop(); - otherElement.scrollTop(scrollElement.scrollTop()); - scrollTop = scrollElement.scrollTop(); - if (Math.abs(old - otherElement[0].scrollTop) > 0.1) { - e.stopPropagation(); - change = true; - } - } - if (scrollElement.scrollLeft() != scrollLeft) { - var old = scrollTopElement.scrollLeft(); - scrollTopElement.scrollLeft(scrollElement.scrollLeft()); - scrollLeft = scrollElement.scrollLeft(); - if (Math.abs(old - scrollTopElement[0].scrollLeft) > 0.1) { - e.stopPropagation(); - change = true; - } - } - // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); - if (change === true) { - e.stopPropagation(); - //return false; - } - }); - } - }, + // KEY EVENTS - _animateScrollTo: function (el, from, to, duration, easing, op) { - var self = this; - var onStart = op.onStart, onComplete = op.onComplete, onUpdate = op.onUpdate; - var startTime = BI.getTime(), _delay, progress = 0, _request; - _cancelTween(); - _startTween(); - var diff = to - from; - el._stop = 0; - function _step() { - if (el._stop) { - return; - } - if (!progress) { - onStart.call(); - } - progress = BI.getTime() - startTime; - _tween(); - if (progress >= el.time) { - el.time = (progress > el.time) ? progress + _delay - (progress - el.time) : progress + _delay - 1; - if (el.time < progress + 1) { - el.time = progress + 1; - } - } - if (el.time < duration) { - el._id = _request(_step); - } else { - el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](to); - onComplete.call(); - } - } + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled(); + var prevShift = cm.display.shift, done = false; + try { + if (isReadOnly(cm)) cm.state.suppressEdits = true; + if (dropShift) cm.display.shift = false; + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } - function _tween() { - var top = to; - if (duration > 0) { - el.currVal = _ease(el.time, from, diff, duration, easing); - el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](top = Math.round(el.currVal)); - } else { - el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](to); - } - onUpdate(top); - } + function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); + if (result) return result; + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm); + } - function _startTween() { - _delay = 1000 / 60; - el.time = progress + _delay; - _request = (!requestAnimationFrame()) ? function (f) { - _tween(); - return setTimeout(f, 0.01); - } : requestAnimationFrame(); - el._id = _request(_step); + var stopSeq = new Delayed; + function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq; + if (seq) { + if (isModifierKey(name)) return "handled"; + stopSeq.set(50, function() { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null; + cm.display.input.reset(); } + }); + name = seq + " " + name; + } + var result = lookupKeyForEditor(cm, name, handle); - function requestAnimationFrame() { - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.msRequestAnimationFrame || - window.oRequestAnimationFrame; - } + if (result == "multi") + cm.state.keySeq = name; + if (result == "handled") + signalLater(cm, "keyHandled", cm, name, e); - function cancelAnimationFrame() { - return window.cancelAnimationFrame || - window.webkitCancelAnimationFrame || - window.mozCancelAnimationFrame || - window.msCancelAnimationFrame || - window.oCancelAnimationFrame || - window.cancelRequestAnimationFrame || - window.webkitCancelRequestAnimationFrame || - window.mozCancelRequestAnimationFrame || - window.msCancelRequestAnimationFrame || - window.oCancelRequestAnimationFrame - } + if (result == "handled" || result == "multi") { + e_preventDefault(e); + restartBlink(cm); + } - function _cancelTween() { - if (el._id == null) { - return; - } - if (!cancelAnimationFrame()) { - clearTimeout(el._id); - } else { - cancelAnimationFrame()(el._id); - } - el._id = null; - } + if (seq && !result && /\'$/.test(name)) { + e_preventDefault(e); + return true; + } + return !!result; + } - function _ease(t, b, c, d, type) { - switch (type) { - case "linear": - return c * t / d + b; - break; - case "mcsLinearOut": - t /= d; - t--; - return c * Math.sqrt(1 - t * t) + b; - break; - case "easeInOutSmooth": - t /= d / 2; - if (t < 1) { - return c / 2 * t * t + b; - } - t--; - return -c / 2 * (t * (t - 2) - 1) + b; - break; - case "easeInOutStrong": - t /= d / 2; - if (t < 1) { - return c / 2 * Math.pow(2, 10 * (t - 1)) + b; - } - t--; - return c / 2 * ( -Math.pow(2, -10 * t) + 2 ) + b; - break; - case "easeInOut": - case "mcsEaseInOut": - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t + b; - } - t -= 2; - return c / 2 * (t * t * t + 2) + b; - break; - case "easeOutSmooth": - t /= d; - t--; - return -c * (t * t * t * t - 1) + b; - break; - case "easeOutStrong": - return c * ( -Math.pow(2, -10 * t / d) + 1 ) + b; - break; - case "easeOut": - case "mcsEaseOut": - default: - var ts = (t /= d) * t, tc = ts * t; - return b + c * (0.499999999999997 * tc * ts + -2.5 * ts * ts + 5.5 * tc + -6.5 * ts + 4 * t); - } - } - }, + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + var name = keyName(e, true); + if (!name) return false; - _getScrollOffsetAndDur: function (event) { - var offset = 40, dur = 200; - if (event.originalEvent.wheelDelta) { - offset = Math.abs(event.originalEvent.wheelDelta); - } - if (event.deltaFactor < 2) { - offset = 3; - dur = 17; - } - return { - offset: offset, - dur: dur - }; - }, + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);}) + || dispatchKey(cm, name, e, function(b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); }); + } + } - resize: function () { - this._resize(); - }, + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, + function(b) { return doHandleBinding(cm, b, true); }); + } - _createCells: function (items, columnSize, mergeCols, TDs, Ws, start, rowSize) { - var self = this, o = this.options, preCol = {}, preRow = {}, preRW = {}, preCW = {}, map = {}; - columnSize = columnSize || o.columnSize; - mergeCols = mergeCols || o.mergeCols; - TDs = TDs || {}; - Ws = Ws || {}; - start = start || 0; - rowSize || (rowSize = o.rowSize); - var frag = document.createDocumentFragment(); - BI.each(items, function (i, rows) { - var tr = $("").addClass((i & 1) === 0 ? "odd" : "even"); - BI.each(rows, function (j, row) { - if (!map[i]) { - map[i] = {}; - } - if (!TDs[i]) { - TDs[i] = {}; - } - if (!Ws[i]) { - Ws[i] = {}; - } - map[i][j] = row; + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + cm.curOp.focus = activeElt(); + if (signalDOMEvent(cm, e)) return; + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut"); + } - if (o.isNeedMerge && mergeCols.contains(j)) { - if (i === 0 && j === 0) { - createOneEl(0, 0); - } else if (j === 0 && i > 0) { - var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); - if (isNeedMergeRow === true) { - mergeRow(i, j); - preRow[i] = preCol[j]; - preRW[i] = preCW[j]; - } else { - createOneEl(i, j); - } - } else if (i === 0 && j > 0) { - var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); - if (isNeedMergeCol === true) { - mergeCol(i, j); - preCol[j] = preRow[j - 1]; - preCW[j] = preRW[j - 1]; - } else { - createOneEl(i, j); - } - } else { - var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); - var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); - if (isNeedMergeCol && isNeedMergeRow) { - return; - } - if (isNeedMergeCol) { - mergeCol(i, j); - } - if (isNeedMergeRow) { - mergeRow(i, j); - } - if (!isNeedMergeCol && !isNeedMergeRow) { - createOneEl(i, j); - } - } - } else { - createOneEl(i, j); - } - }); - function mergeRow(i, j) { - var height = (preCol[j].attr("height") | 0) + rowSize + 1; - preCol[j].attr("height", height).css("height", height); - //preCW[j].element.css("height", height); - var rowspan = ((preCol[j].attr("rowspan") || 1) | 0) + 1; - preCol[j].attr("rowspan", rowspan); - preCol[j].__mergeRows.pushDistinct(i); - TDs[i][j] = preCol[j]; - Ws[i][j] = preCW[j]; - } + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + showCrossHair(cm); + } - function mergeCol(i, j) { - if (columnSize[j]) { - var width = preRow[i].attr("width") | 0; - if (width > 1.05 && columnSize[j]) { - width = width + columnSize[j] + 1; - if (j === columnSize.length - 1) { - width--; - } - } else { - width = width + columnSize[j] - } - width = self._calculateWidth(width); - preRow[i].attr("width", width).css("width", width); - preRW[i].element.width(width); - } - var colspan = ((preRow[i].attr("colspan") || 1) | 0) + 1; - preRow[i].attr("colspan", colspan); - preRow[i].__mergeCols.pushDistinct(j); - TDs[i][j] = preRow[i]; - Ws[i][j] = preRW[i]; - } + function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv; + addClass(lineDiv, "CodeMirror-crosshair"); - function createOneEl(r, c) { - var width = self._calculateWidth(columnSize[c]); - if (width > 1.05 && c === columnSize.length - 1) { - width--; - } - var height = self._calculateHeight(rowSize); - var td = $("").attr("height", height) - .attr("width", width).css({"width": width, "height": height, "position": "relative"}) - .addClass((c & 1) === 0 ? "odd-col" : "even-col") - .addClass(r === 0 ? "first-row" : "") - .addClass(c === 0 ? "first-col" : "") - .addClass(c === rows.length - 1 ? "last-col" : ""); - var w = BI.createWidget(map[r][c], { - type: "bi.table_cell", - textAlign: "left", - width: BI.isNumeric(width) ? width : "", - height: BI.isNumeric(height) ? height : "", - _row: r, - _col: c + start - }); - w.element.css("position", "relative"); - td.append(w.element); - tr.append(td); - preCol[c] = td; - preCol[c].__mergeRows = [r]; - preCW[c] = w; - preRow[r] = td; - preRow[r].__mergeCols = [c]; - preRW[r] = w; - TDs[r][c] = td; - Ws[r][c] = w; - } + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair"); + off(document, "keyup", up); + off(document, "mouseover", up); + } + } + on(document, "keyup", up); + on(document, "mouseover", up); + } - frag.appendChild(tr[0]); - }); - return frag; - }, + function onKeyUp(e) { + if (e.keyCode == 16) this.doc.sel.shift = false; + signalDOMEvent(this, e); + } - _createColGroupCells: function (columnSize, store) { - var self = this, o = this.options; - columnSize = columnSize || o.columnSize; - store = store || {}; - var frag = document.createDocumentFragment(); - BI.each(columnSize, function (i, size) { - var width = self._calculateWidth(size); - var col = $("").attr("width", width).css("width", width); - store[i] = col; - frag.appendChild(col[0]); - }); - return frag; - }, + function onKeyPress(e) { + var cm = this; + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (handleCharBinding(cm, e, ch)) return; + cm.display.input.onKeyPress(e); + } - _createHeaderCells: function (items, columnSize, mergeCols, TDs, Ws, start) { - var self = this, o = this.options; - start || (start = 0); - var frag = this._createCells(items, columnSize, BI.range(o.columnSize.length), TDs, Ws, start, o.headerRowSize || o.rowSize); + // FOCUS/BLUR EVENTS - if (o.isNeedResize === true) { - var tds = TDs[BI.size(TDs) - 1]; - BI.each(tds, function (j, td) { - j = j | 0; - var resizer; - var getHeight = function (size, position) { - var rowSize = self.getCalculateRegionRowSize(); - if (o.isNeedFreeze === true) { - var tableHeight = self.bottomRightContainer.element.outerHeight(); - return size.height + Math.min(rowSize[1], tableHeight); - } else { - var tableHeight = self.tableContainer.element.outerHeight(); - var offset = self.tableContainer.element.offset(); - var offsetTop = position.top - offset.top; - var height = tableHeight - offsetTop; - height = Math.min(height, rowSize[0] - offsetTop); - return height; - } - }; - if (j < BI.size(tds) - 1) { - td.resizable({ - handles: "e", - minWidth: 15, - helper: "clone", - start: function (event, ui) { - var height = getHeight(ui.size, ui.position); - resizer = BI.createWidget({ - type: "bi.layout", - cls: "bi-resizer", - width: ui.size.width, - height: height - }); + function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true; + setTimeout(function() { + if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false; + onBlur(cm); + } + }, 100); + } - BI.createWidget({ - type: "bi.absolute", - element: "body", - items: [{ - el: resizer, - left: ui.position.left, - top: ui.position.top - }] - }); - self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE); - }, - resize: function (e, ui) { - var height = getHeight(ui.size, ui.position); - resizer.element.css({"width": ui.size.width + "px", "height": height + "px"}); - //o.columnSize[start + j] = ui.size.width; - //self.setColumnSize(o.columnSize); - self.fireEvent(BI.Table.EVENT_TABLE_COLUMN_RESIZE); - e.stopPropagation(); - //return false; - }, - stop: function (e, ui) { - resizer.destroy(); - resizer = null; - o.columnSize[start + j] = ui.size.width - 1; - self.setColumnSize(o.columnSize); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE); - } - }) - } - }) - } - return frag; - }, + function onFocus(cm) { + if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; - _createFooterCells: function (items, columnSize, TDs, Ws) { - var o = this.options; - var frag = this._createCells(items, columnSize, [], TDs, Ws, 0); - return frag; - }, + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + addClass(cm.display.wrapper, "CodeMirror-focused"); + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset(); + if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730 + } + cm.display.input.receivedFocus(); + } + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.delayingBlurEvent) return; - _createColGroup: function (columnSize, store, widgets) { - var self = this, o = this.options; - this.colgroup = this._colgroup(); - this.colgroup.element.append(this._createColGroupCells(columnSize, store, widgets)); - return this.colgroup; - }, + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + rmClass(cm.display.wrapper, "CodeMirror-focused"); + } + clearInterval(cm.display.blinker); + setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); + } - _createHeader: function () { - var self = this, o = this.options; - if (o.header === false) { - return; - } - this.header = this._header(); - this.header.element.append(this._createHeaderCells(o.header, null, null, this.headerTds, this.headerItems)); - return this.header; - }, + // CONTEXT MENU HANDLING - _createFooter: function (columnSize, store, widgets) { - var self = this, o = this.options; - if (o.footer === false) { - return; - } - this.footer = this._footer(); - this.footer.element.append(this._createFooterCells(o.footer, null, this.footerTds, this.footerItems)); - return this.footer; - }, + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; + cm.display.input.onContextMenu(e); + } - _createBody: function () { - var self = this, o = this.options; - this.body = this._body(); - this.body.element.append(this._createCells(o.items, null, null, this.bodyTds, this.bodyItems)); - return this.body; - }, + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false, signal); + } - _createNormalTable: function () { - var self = this, o = this.options, table = this._table(); - this.colgroupTds = {}; - this.headerTds = {}; - this.footerTds = {}; - this.bodyTds = {}; + // UPDATING - this.headerItems = {}; - this.footerItems = {}; - this.bodyItems = {}; - var colgroup = this._createColGroup(null, this.colgroupTds); - var header = this._createHeader(); - var footer = this._createFooter(); - var body = this._createBody(); + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + var changeEnd = CodeMirror.changeEnd = function(change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; - BI.createWidget({ - type: "bi.adaptive", - element: table, - items: [colgroup, header, footer, body] - }); + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos; + if (cmp(pos, change.to) <= 0) return changeEnd(change); - var w = BI.sum(this.options.columnSize) || undefined; - w = this._calculateWidth(w); - if (BI.isNumeric(w) && w > 1) { - w += o.columnSize.length; - } - this.tableContainer = BI.createWidget({ - type: "bi.adaptive", - width: this._calculateWidth(w), - items: [table] - }); + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; + return Pos(line, ch); + } - this.scrollBottomRight = BI.createWidget({ - type: "bi.adaptive", - width: "100%", - height: "100%", - cls: "scroll-bottom-right", - scrollable: true, - items: [this.tableContainer] - }); + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(out, doc.sel.primIndex); + } - BI.createWidget({ - type: "bi.adaptive", - cls: "bottom-right", - element: this, - scrollable: false, - items: [this.scrollBottomRight] - }); + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch); + else + return Pos(nw.line + (pos.line - old.line), pos.ch); + } - this._resize = function () { - if (self.element.is(":visible")) { - self.setColumnSize(o.columnSize); - } - }; + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex); + } - this._initNormalScroll(); - BI.Resizers.add(this.getName(), function (e) { - if (self.element.is(":visible") && BI.isWindow(e.target)) { - self._resize(); - self.fireEvent(BI.Table.EVENT_TABLE_RESIZE); - } - }); - BI.nextTick(function () { - if (self.element.is(":visible")) { - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); - } - }); - }, + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function() { this.canceled = true; } + }; + if (update) obj.update = function(from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - _initNormalScroll: function () { - var self = this; - var scrolling, scrollX; - this.scrollBottomRight.element.mousewheel(function (event, delta, deltaX, deltaY) { - var inf = self._getScrollOffsetAndDur(event); - if (deltaY < 0 || deltaY > 0) { - var ele = self.scrollBottomRight.element; - if (scrolling) { - ele[0].scrollTop = scrolling; - } + if (obj.canceled) return null; + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; + } - scrolling = ele[0].scrollTop - delta * inf.offset; - var stopPropagation = false; - var st = ele[0].scrollTop; - ele[0].scrollTop = scrolling; - if (ele[0].scrollTop !== st) { - stopPropagation = true; - } - ele[0].scrollTop = st; - self._animateScrollTo(ele, ele[0].scrollTop, scrolling, inf.dur, "linear", { - onStart: function () { - }, - onUpdate: function (top) { - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, top); - }, - onComplete: function () { - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrolling); - scrolling = null; - } - }); - //var scrollTop = self.scrollBottomRight.element[0].scrollTop = self.scrollBottomRight.element[0].scrollTop - delta * offset; - //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); - if (stopPropagation === true) { - event.stopPropagation(); - return false; - } - } - }); - var scrollTop = 0, scrollLeft = 0; - this.scrollBottomRight.element.scroll(function (e) { - var change = false; - var scrollElement = self.scrollBottomRight.element; - if (scrollElement.scrollTop() != scrollTop) { - if (Math.abs(scrollElement.scrollTop() - scrollTop) > 0.1) { - e.stopPropagation(); - change = true; - } - scrollTop = scrollElement.scrollTop(); - } - if (scrollElement.scrollLeft() != scrollLeft) { - if (Math.abs(scrollElement.scrollLeft() - scrollLeft) > 0.1) { - e.stopPropagation(); - change = true; - } - scrollLeft = scrollElement.scrollLeft(); - } - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); - if (change === true) { - e.stopPropagation(); - //return false; - } - return false; - }); - }, + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } - _split: function (items) { - var o = this.options, left = [], right = [], isRight = this._isRightFreeze(); - BI.each(items, function (i, rows) { - left.push([]); - right.push([]); - BI.each(rows, function (j, cell) { - if (o.freezeCols.contains(j)) { - (isRight ? right : left)[i].push(cell); - } else { - (isRight ? left : right)[i].push(cell); - } - }) - }); - return { - left: left, - right: right - } - }, + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } - _table: function () { - return BI.createWidget({ - type: "bi.layout", - tagName: "table", - cls: "table", - attribute: {"cellspacing": 0, "cellpadding": 0} - }); - }, + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); + } else { + makeChangeInner(doc, change); + } + } - _header: function () { - return BI.createWidget({ - type: "bi.layout", - cls: "header", - tagName: "thead" - }); - }, + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - _footer: function () { - return BI.createWidget({ - type: "bi.layout", - cls: "footer", - tagName: "tfoot" - }); - }, + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; - _body: function () { - return BI.createWidget({ - type: "bi.layout", - tagName: "tbody", - cls: "body" - }); - }, + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } - _colgroup: function () { - return BI.createWidget({ - type: "bi.layout", - tagName: "colgroup" - }); - }, + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits) return; - _init: function () { - BI.Table.superclass._init.apply(this, arguments); + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; - this.populate(this.options.items); - }, + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + for (var i = 0; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break; + } + if (i == source.length) return; + hist.lastOrigin = hist.lastSelOrigin = null; - setColumnSize: function (columnSize) { - var self = this, o = this.options; - var isRight = this._isRightFreeze(); - o.columnSize = columnSize || []; - if (o.isNeedFreeze) { - var columnLeft = []; - var columnRight = []; - BI.each(o.columnSize, function (i, size) { - if (o.freezeCols.contains(i)) { - isRight ? columnRight.push(size) : columnLeft.push(size); - } else { - isRight ? columnLeft.push(size) : columnRight.push(size); - } - }); - var topleft = 0, topright = 1, bottomleft = 2, bottomright = 3; - var run = function (direction) { - var colgroupTds, bodyTds, bodyItems, sizes; - switch (direction) { - case topleft: - colgroupTds = self.topLeftColGroupTds; - bodyTds = self.topLeftBodyTds; - bodyItems = self.topLeftBodyItems; - sizes = columnLeft; - break; - case topright: - colgroupTds = self.topRightColGroupTds; - bodyTds = self.topRightBodyTds; - bodyItems = self.topRightBodyItems; - sizes = columnRight; - break; - case bottomleft: - colgroupTds = self.bottomLeftColGroupTds; - bodyTds = self.bottomLeftBodyTds; - bodyItems = self.bottomLeftBodyItems; - sizes = columnLeft; + for (;;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}); + return; + } + selAfter = event; + } + else break; + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({changes: antiChanges, generation: hist.generation}); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return; + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + if (distance == 0) return; + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function(range) { + return new Range(Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch)); + }), doc.sel.primIndex); + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance); + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + regLineChange(doc.cm, l, "gutter"); + } + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); + else updateDoc(doc, change, spans); + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function(line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + signalCursorActivity(cm); + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function(line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (change.full) + regChange(cm); + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text"); + else + regChange(cm, from.line, to.line + 1, lendiff); + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }; + if (changeHandler) signalLater(cm, "change", cm, obj); + if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); + } + cm.display.selForContextMenu = null; + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = splitLines(code); + makeChange(doc, {from: from, to: to, text: code, origin: origin}); + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, coords) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) return; + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + + (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + + (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + + coords.left + "px; width: 2px;"); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0; + for (var limit = 0; limit < 5; limit++) { + var changed = false, coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), + Math.min(coords.top, endCoords.top) - margin, + Math.max(coords.left, endCoords.left), + Math.max(coords.bottom, endCoords.bottom) + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) break; + } + return coords; + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = displayHeight(cm), result = {}; + if (y2 - y1 > screen) y2 = y1 + screen; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; + var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); + var tooWide = x2 - x1 > screenw; + if (tooWide) x2 = x1 + screenw; + if (x1 < 10) + result.scrollLeft = 0; + else if (x1 < screenleft) + result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); + else if (x2 > screenw + screenleft - 3) + result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; + return result; + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollPos(cm, left, top) { + if (left != null || top != null) resolveScrollToPos(cm); + if (left != null) + cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; + if (top != null) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(), from = cur, to = cur; + if (!cm.options.lineWrapping) { + from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; + to = Pos(cur.line, cur.ch + 1); + } + cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), + Math.min(from.top, to.top) - range.margin, + Math.max(from.right, to.right), + Math.max(from.bottom, to.bottom) + range.margin); + cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + } + + // API UTILITIES + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) how = "add"; + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) how = "prev"; + else state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) line.stateAfter = null; + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass || indentation > 150) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + return true; + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i, new Range(pos, pos)); + break; + } + } + } + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); + return line; + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break; + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function() { + for (var i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); + ensureCursorVisible(cm); + }); + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "char", "column" (like char, but doesn't + // cross line boundaries), "word" (across next word), or "group" (to + // the start of next group of word or non-word-non-whitespace + // chars). The visually param controls whether, in right-to-left + // text, direction 1 means to move towards the next index in the + // string, or towards the character to the right of the current + // position. The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + var possible = true; + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return (possible = false); + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return (possible = false); + } else ch = next; + return true; + } + + if (unit == "char") moveOnce(); + else if (unit == "column") moveOnce(true); + else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) type = "s"; + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce();} + break; + } + + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), origDir, true); + if (!possible) result.hitSide = true; + return result; + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (;;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + // EDITOR METHODS + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus();}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function(option) {return this.options[option];}, + getDoc: function() {return this.doc;}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: methodOp(function(how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var from = range.from(), to = range.to(); + var start = Math.max(end, from.line); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + indentLine(this, j, how); + var newRanges = this.doc.sel.ranges; + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) ensureCursorVisible(this); + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise); + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true); + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + var type; + if (ch == 0) type = styles[2]; + else for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else { type = styles[mid * 2 + 2]; break; } + } + var cut = type ? type.indexOf("cm-overlay ") : -1; + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0]; + }, + + getHelpers: function(pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) return found; + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]); + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) found.push(val); + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i = 0; i < help._global.length; i++) { + var cur = help._global[i]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val); + } + return found; + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) pos = range.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? range.from() : range.to(); + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function(line, mode) { + var end = false, lineObj; + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + lineObj = getLine(this.doc, line); + } else { + lineObj = line; + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + + (end ? this.doc.height - heightAtLine(lineObj) : 0); + }, + + defaultTextHeight: function() { return textHeight(this.display); }, + defaultCharWidth: function() { return charWidth(this.display); }, + + setGutterMarker: methodOp(function(line, gutterID, value) { + return changeLine(this.doc, line, "gutter", function(line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: methodOp(function(gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function(line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regLineChange(cm, i, "gutter"); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + lineInfo: function(line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets}; + }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + node.setAttribute("cm-ignore-events", "true"); + this.display.input.setUneditable(node); + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd](this); + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: methodOp(function(dir, unit) { + var cm = this; + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); + else + return dir < 0 ? range.from() : range.to(); + }, sel_move); + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete"); + else + deleteNearSelection(this, function(range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; + }); + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: methodOp(function(dir, unit) { + var cm = this, doc = this.doc, goals = []; + var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function(range) { + if (collapse) + return dir < 0 ? range.from() : range.to(); + var headPos = cursorCoords(cm, range.head, "div"); + if (range.goalColumn != null) headPos.left = range.goalColumn; + goals.push(headPos.left); + var pos = findPosV(cm, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); + return pos; + }, sel_move); + if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i]; + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function(ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + addClass(this.display.cursorDiv, "CodeMirror-overwrite"); + else + rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function() { return this.display.input.getField() == activeElt(); }, + + scrollTo: methodOp(function(x, y) { + if (x != null || y != null) resolveScrollToPos(this); + if (x != null) this.curOp.scrollLeft = x; + if (y != null) this.curOp.scrollTop = y; + }), + getScrollInfo: function() { + var scroller = this.display.scroller; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)}; + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null}; + if (margin == null) margin = this.options.cursorScrollMargin; + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null}; + } else if (range.from == null) { + range = {from: range, to: null}; + } + if (!range.to) range.to = range.from; + range.margin = margin || 0; + + if (range.from.line != null) { + resolveScrollToPos(this); + this.curOp.scrollToPos = range; + } else { + var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), + Math.min(range.from.top, range.to.top) - range.margin, + Math.max(range.from.right, range.to.right), + Math.max(range.from.bottom, range.to.bottom) + range.margin); + this.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + }), + + setSize: methodOp(function(width, height) { + var cm = this; + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) cm.display.wrapper.style.width = interpret(width); + if (height != null) cm.display.wrapper.style.height = interpret(height); + if (cm.options.lineWrapping) clearLineMeasurementCache(this); + var lineNo = cm.display.viewFrom; + cm.doc.iter(lineNo, cm.display.viewTo, function(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) + if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } + ++lineNo; + }); + cm.curOp.forceUpdate = true; + signal(cm, "refresh", this); + }), + + operation: function(f){return runInOp(this, f);}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + this.curOp.forceUpdate = true; + clearCaches(this); + this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); + updateGutterSpace(this); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + this.display.input.reset(); + this.scrollTo(doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; + signalLater(this, "swapDoc", this, old); + return old; + }), + + getInputField: function(){return this.display.input.getField();}, + getWrapperElement: function(){return this.display.wrapper;}, + getScrollerElement: function(){return this.display.scroller;}, + getGutterElement: function(){return this.display.gutters;} + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + // Functions to run when options are changed. + var optionHandlers = CodeMirror.optionHandlers = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; + } + + // Passed to option handlers when there is no old value. + var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function(cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function(cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function(cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + if (old != CodeMirror.Init) cm.refresh(); + }); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); + option("electricChars", true); + option("inputStyle", mobile ? "contenteditable" : "textarea", function() { + throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME + }, true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function(cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", function(cm, val, old) { + var next = getKeyMap(val); + var prev = old != CodeMirror.Init && getKeyMap(old); + if (prev && prev.detach) prev.detach(cm, next); + if (next.attach) next.attach(cm, prev || null); + }); + option("extraKeys", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function(cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true); + option("scrollbarStyle", "native", function(cm) { + initScrollbars(cm); + updateScrollbars(cm); + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); + }, true); + option("lineNumbers", false, function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + option("lineWiseCopyCut", true); + + option("readOnly", false, function(cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + cm.display.disabled = true; + } else { + cm.display.disabled = false; + if (!val) cm.display.input.reset(); + } + }); + option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true); + option("dragDrop", true, dragDropChanged); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1, updateSelection, true); + option("singleCursorHeightPerLine", true, updateSelection, true); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function(cm){cm.refresh();}, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function(cm, val) { + if (!val) cm.display.input.resetPosition(); + }); + + option("tabindex", null, function(cm, val) { + cm.display.input.getField().tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; + }; + + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") found = {name: found}; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; + }; + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + CodeMirror.getMode = function(options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; + }; + + // Minimal default mode. + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function(name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function(name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({pred: predicate, val: value}); + }; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because nested + // modes need to do this for their inner modes. + + var copyState = CodeMirror.copyState = function(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + }; + + var startState = CodeMirror.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + }; + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + CodeMirror.innerMode = function(mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state}; + }; + + // STANDARD COMMANDS + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = CodeMirror.commands = { + selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, + singleSelection: function(cm) { + cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); + }, + killLine: function(cm) { + deleteNearSelection(cm, function(range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + return {from: range.head, to: Pos(range.head.line + 1, 0)}; + else + return {from: range.head, to: Pos(range.head.line, len)}; + } else { + return {from: range.from(), to: range.to()}; + } + }); + }, + deleteLine: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; + }); + }, + delLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), to: range.from()}; + }); + }, + delWrappedLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var leftPos = cm.coordsChar({left: 0, top: top}, "div"); + return {from: leftPos, to: range.from()}; + }); + }, + delWrappedLineRight: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + return {from: range.from(), to: rightPos }; + }); + }, + undo: function(cm) {cm.undo();}, + redo: function(cm) {cm.redo();}, + undoSelection: function(cm) {cm.undoSelection();}, + redoSelection: function(cm) {cm.redoSelection();}, + goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, + goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, + goLineStart: function(cm) { + cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, + {origin: "+move", bias: 1}); + }, + goLineStartSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + return lineStartSmart(cm, range.head); + }, {origin: "+move", bias: 1}); + }, + goLineEnd: function(cm) { + cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, + {origin: "+move", bias: -1}); + }, + goLineRight: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + }, sel_move); + }, + goLineLeft: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: 0, top: top}, "div"); + }, sel_move); + }, + goLineLeftSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var pos = cm.coordsChar({left: 0, top: top}, "div"); + if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); + return pos; + }, sel_move); + }, + goLineUp: function(cm) {cm.moveV(-1, "line");}, + goLineDown: function(cm) {cm.moveV(1, "line");}, + goPageUp: function(cm) {cm.moveV(-1, "page");}, + goPageDown: function(cm) {cm.moveV(1, "page");}, + goCharLeft: function(cm) {cm.moveH(-1, "char");}, + goCharRight: function(cm) {cm.moveH(1, "char");}, + goColumnLeft: function(cm) {cm.moveH(-1, "column");}, + goColumnRight: function(cm) {cm.moveH(1, "column");}, + goWordLeft: function(cm) {cm.moveH(-1, "word");}, + goGroupRight: function(cm) {cm.moveH(1, "group");}, + goGroupLeft: function(cm) {cm.moveH(-1, "group");}, + goWordRight: function(cm) {cm.moveH(1, "word");}, + delCharBefore: function(cm) {cm.deleteH(-1, "char");}, + delCharAfter: function(cm) {cm.deleteH(1, "char");}, + delWordBefore: function(cm) {cm.deleteH(-1, "word");}, + delWordAfter: function(cm) {cm.deleteH(1, "word");}, + delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, + delGroupAfter: function(cm) {cm.deleteH(1, "group");}, + indentAuto: function(cm) {cm.indentSelection("smart");}, + indentMore: function(cm) {cm.indentSelection("add");}, + indentLess: function(cm) {cm.indentSelection("subtract");}, + insertTab: function(cm) {cm.replaceSelection("\t");}, + insertSoftTab: function(cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from(); + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); + spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); + } + cm.replaceSelections(spaces); + }, + defaultTab: function(cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.execCommand("insertTab"); + }, + transposeChars: function(cm) { + runInOp(cm, function() { + var ranges = cm.listSelections(), newSel = []; + for (var i = 0; i < ranges.length; i++) { + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (line) { + if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1); + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose"); + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text; + if (prev) + cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); + } + } + newSel.push(new Range(cur, cur)); + } + cm.setSelections(newSel); + }); + }, + newlineAndIndent: function(cm) { + runInOp(cm, function() { + var len = cm.listSelections().length; + for (var i = 0; i < len; i++) { + var range = cm.listSelections()[i]; + cm.replaceRange("\n", range.anchor, range.head, "+input"); + cm.indentLine(range.from().line + 1, null, true); + ensureCursorVisible(cm); + } + }); + }, + toggleOverwrite: function(cm) {cm.toggleOverwrite();} + }; + + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; + var alt, ctrl, shift, cmd; + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; + else if (/^a(lt)?$/i.test(mod)) alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; + else if (/^s(hift)$/i.test(mod)) shift = true; + else throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) name = "Alt-" + name; + if (ctrl) name = "Ctrl-" + name; + if (cmd) name = "Cmd-" + name; + if (shift) name = "Shift-" + name; + return name; + } + + // This is a kludge to keep keymaps mostly working as raw objects + // (backwards compatibility) while at the same time support features + // like normalization and multi-stroke key bindings. It compiles a + // new normalized keymap, and then updates the old object to reflect + // this. + CodeMirror.normalizeKeyMap = function(keymap) { + var copy = {}; + for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname]; + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; + if (value == "...") { delete keymap[keyname]; continue; } + + var keys = map(keyname.split(" "), normalizeKeyName); + for (var i = 0; i < keys.length; i++) { + var val, name; + if (i == keys.length - 1) { + name = keys.join(" "); + val = value; + } else { + name = keys.slice(0, i + 1).join(" "); + val = "..."; + } + var prev = copy[name]; + if (!prev) copy[name] = val; + else if (prev != val) throw new Error("Inconsistent bindings for " + name); + } + delete keymap[keyname]; + } + for (var prop in copy) keymap[prop] = copy[prop]; + return keymap; + }; + + var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) { + map = getKeyMap(map); + var found = map.call ? map.call(key, context) : map[key]; + if (found === false) return "nothing"; + if (found === "...") return "multi"; + if (found != null && handle(found)) return "handled"; + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + return lookupKey(key, map.fallthrough, handle, context); + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context); + if (result) return result; + } + } + }; + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + var isModifierKey = CodeMirror.isModifierKey = function(value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + }; + + // Look up the name of a key as indicated by an event object. + var keyName = CodeMirror.keyName = function(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false; + var base = keyNames[event.keyCode], name = base; + if (name == null || event.altGraphKey) return false; + if (event.altKey && base != "Alt") name = "Alt-" + name; + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; + if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; + return name; + }; + + function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val; + } + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function(textarea, options) { + options = options ? copyObj(options) : {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabIndex) + options.tabindex = textarea.tabIndex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function() { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + options.finishInit = function(cm) { + cm.save = save; + cm.getTextArea = function() { return textarea; }; + cm.toTextArea = function() { + cm.toTextArea = isNaN; // Prevent this from being ran twice + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + }; + + textarea.style.display = "none"; + var cm = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = CodeMirror.StringStream = function(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + var nextMarkerId = 0; + + var TextMarker = CodeMirror.TextMarker = function(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + this.id = ++nextMarkerId; + }; + eventMixin(TextMarker); + + // Clear the marker. + TextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); + else if (cm) { + if (span.to != null) max = lineNo(line); + if (span.from != null) min = lineNo(line); + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(this.lines[i]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm.doc); + } + if (cm) signalLater(cm, "markerCleared", cm, this); + if (withOp) endOperation(cm); + if (this.parent) this.parent.clear(); + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function(side, lineObj) { + if (side == null && this.type == "bookmark") side = 1; + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) return from; + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) return to; + } + } + return from && {from: from, to: to}; + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function() { + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) return; + runInOp(cm, function() { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + updateLineHeight(line, line.height + dHeight); + } + }); + }; + + TextMarker.prototype.attachLine = function(line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function(line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type); + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) copyObj(options, marker, false); + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker; + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); + if (options.insertLeft) marker.widgetNode.insertLeft = true; + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one"); + sawCollapsedSpans = true; + } + + if (marker.addToHistory) + addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function(line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true; + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.collapsed) + regChange(cm, from.line, to.line + 1); + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); + if (marker.atomic) reCheckSelection(cm.doc); + signalLater(cm, "markerAdded", cm, marker); + } + return marker; + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0; i < markers.length; ++i) + markers[i].parent = this; + }; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function(side, lineObj) { + return this.primary.find(side, lineObj); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function(doc) { + if (widget) options.widgetNode = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), + function(m) { return m.parent; }); + } + + function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find(); + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); + marker.markers.push(subMark); + subMark.parent = marker; + } + } + } + + function detachSharedMarkers(markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], linked = [marker.primary.doc];; + linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j]; + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null; + marker.markers.splice(j--, 1); + } + } + } + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } + return nw; + } + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } + return nw; + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + if (change.full) return null; + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first); + if (last && last != first) last = clearEmptySpans(last); + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1); + } + if (!spans.length) return null; + return spans; + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function(line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({from: p.from, to: m.from}); + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({from: m.to, to: p.to}); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) return lenDiff; + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) return -fromCmp; + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) return toCmp; + return b.id - a.id; + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) continue; + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; + if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || + fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) + return true; + } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line; + return line; + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + (lines || (lines = [])).push(line); + } + return lines; + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) return lineN; + return lineNo(vis); + } + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN; + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) return lineN; + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line; + return lineNo(line) + 1; + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.widgetNode) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + // LINE WIDGETS + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = CodeMirror.LineWidget = function(doc, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.doc = doc; + this.node = node; + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollPos(cm, null, diff); + } + + LineWidget.prototype.clear = function() { + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) line.widgets = null; + var height = widgetHeight(this); + updateLineHeight(line, Math.max(0, line.height - height)); + if (cm) runInOp(cm, function() { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + }); + }; + LineWidget.prototype.changed = function() { + var oldH = this.height, cm = this.doc.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + updateLineHeight(line, line.height + diff); + if (cm) runInOp(cm, function() { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + }); + }; + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + var cm = widget.doc.cm; + if (!cm) return 0; + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;"; + if (widget.coverGutter) + parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; + if (widget.noHScroll) + parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); + } + return widget.height = widget.node.offsetHeight; + } + + function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options); + var cm = doc.cm; + if (cm && widget.noHScroll) cm.display.alignWidgets = true; + changeLine(doc, handle, "widget", function(line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, null, widget.height); + cm.curOp.forceUpdate = true; + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + Line.prototype.lineNo = function() { return lineNo(this); }; + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + function extractLineClasses(type, output) { + if (type) for (;;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) break; + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (output[prop] == null) + output[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + output[prop] += " " + lineClass[2]; + } + return type; + } + + function callBlankLine(mode, state) { + if (mode.blankLine) return mode.blankLine(state); + if (!mode.innerMode) return; + var inner = CodeMirror.innerMode(mode, state); + if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); + } + + function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; + var style = mode.token(stream, state); + if (stream.pos > stream.start) return style; + } + throw new Error("Mode " + mode.name + " failed to advance stream."); + } + + // Utility for getTokenAt and getLineTokens + function takeToken(cm, pos, precise, asArray) { + function getObj(copy) { + return {start: stream.start, end: stream.pos, + string: stream.current(), + type: style || null, + state: copy ? copyState(doc.mode, state) : state}; + } + + var doc = cm.doc, mode = doc.mode, style; + pos = clipPos(doc, pos); + var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); + var stream = new StringStream(line.text, cm.options.tabSize), tokens; + if (asArray) tokens = []; + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos; + style = readToken(mode, stream, state); + if (asArray) tokens.push(getObj(true)); + } + return asArray ? tokens : getObj(); + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + var inner = cm.options.addModeClass && [null]; + if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) processLine(cm, text, state, stream.pos); + stream.pos = text.length; + style = null; + } else { + style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); + } + if (inner) { + var mName = inner[0].name; + if (mName) style = "m-" + (style ? mName + " " + style : mName); + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 50000); + f(curStart, curStyle); + } + curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, state, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {}; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function(end, style) { + st.push(end, style); + }, lineClasses, forceToEnd); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function(end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, "cm-overlay " + style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; + } + } + }, lineClasses); + } + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; + } + + function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); + line.styles = result.styles; + if (result.classes) line.styleClasses = result.classes; + else if (line.styleClasses) line.styleClasses = null; + if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; + } + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, state, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize); + stream.start = stream.pos = startAt || 0; + if (text == "") callBlankLine(mode, state); + while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { + readToken(mode, stream, state); + stream.start = stream.pos; + } + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) return null; + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")); + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order; + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) + builder.addToken = buildTokenBadBidi(builder.addToken, order); + builder.map = []; + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); + if (line.styleClasses) { + if (line.styleClasses.bgClass) + builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); + if (line.styleClasses.textClass) + builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); + (lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + // See issue #2901 + if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) + builder.content.className = "cm-tab-wrap-hack"; + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + if (builder.pre.className) + builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); + + return builder; + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + token.setAttribute("aria-label", token.title); + return token; + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) return; + var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text; + var special = builder.cm.state.specialChars, mustWrap = false; + if (!special.test(text)) { + builder.col += text.length; + var content = document.createTextNode(displayText); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie && ie_version < 9) mustWrap = true; + builder.pos += text.length; + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + txt.setAttribute("role", "presentation"); + txt.setAttribute("cm-text", "\t"); + builder.col += tabWidth; + } else { + var txt = builder.cm.options.specialCharPlaceholder(m[0]); + txt.setAttribute("cm-text", m[0]); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt); + builder.pos++; + } + } + if (style || startStyle || endStyle || mustWrap || css) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle, css); + if (title) token.title = title; + return builder.content.appendChild(token); + } + builder.content.appendChild(content); + } + + function splitSpaces(old) { + var out = " "; + for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; + out += " "; + return out; + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function(builder, text, style, startStyle, endStyle, title, css) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (;;) { + // Find the part that overlaps with the start of this text + for (var i = 0; i < order.length; i++) { + var part = order[i]; + if (part.to > start && part.from <= start) break; + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) builder.map.push(builder.pos, builder.pos + size, widget); + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + widget = builder.content.appendChild(document.createElement("span")); + widget.setAttribute("cm-marker", marker.id); + } + if (widget) { + builder.cm.display.input.setUneditable(widget); + builder.content.appendChild(widget); + } + builder.pos += size; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = []; + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m); + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to; + spanEndStyle = ""; + } + if (m.className) spanStyle += " " + m.className; + if (m.css) css = m.css; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return; + if (collapsed.to == pos) collapsed = false; + } + if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder.cm.options); + } + } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore); + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null;} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + function linesFor(start, end) { + for (var i = start, result = []; i < end; ++i) + result.push(new Line(text[i], spansFor(i), estimateHeight)); + return result; + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)); + doc.remove(text.length, doc.size - text.length); + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + var added = linesFor(1, text.length - 1); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + var added = linesFor(1, text.length - 1); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, height = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length; }, + // Remove the n lines at offset 'at'. + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + // Helper used to collapse a small branch into a single leaf. + collapse: function(lines) { + lines.push.apply(lines, this.lines); + }, + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) lines[i].parent = this; + }, + // Used to iterate over a part of the tree. + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size; }, + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function(lines) { + for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); + }, + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + while (child.lines.length > 50) { + var spilled = child.lines.splice(child.lines.length - 25, 25); + var newleaf = new LeafChunk(spilled); + child.height -= newleaf.height; + this.children.splice(i + 1, 0, newleaf); + newleaf.parent = this; + } + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + // When a node has grown, check whether it should be split. + maybeSpill: function() { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function(at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function(text, mode, firstLine) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + + if (typeof text == "string") text = splitLines(text); + updateDoc(this, {from: start, to: start, text: text}); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep, lineFilter) { + var lines = getLines(this, this.first, this.first + this.size, lineFilter); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: splitLines(code), origin: "setValue", full: true}, true); + setSelection(this, simpleSelection(top)); + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, + getLineNumber: function(line) {return lineNo(line);}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(line); + }, + + lineCount: function() {return this.size;}, + firstLine: function() {return this.first;}, + lastLine: function() {return this.first + this.size - 1;}, + + clipPos: function(pos) {return clipPos(this, pos);}, + + getCursor: function(start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") pos = range.head; + else if (start == "anchor") pos = range.anchor; + else if (start == "end" || start == "to" || start === false) pos = range.to(); + else pos = range.from(); + return pos; + }, + listSelections: function() { return this.sel.ranges; }, + somethingSelected: function() {return this.sel.somethingSelected();}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads, options)); + }), + extendSelectionsBy: docMethodOp(function(f, options) { + extendSelections(this, map(this.sel.ranges, f), options); + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) return; + for (var i = 0, out = []; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); + setSelection(this, normalizeSelection(out, primary), options); + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); + }), + + getSelection: function(lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) return lines; + else return lines.join(lineSep || "\n"); + }, + getSelections: function(lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) sel = sel.join(lineSep || "\n"); + parts[i] = sel; + } + return parts; + }, + replaceSelection: function(code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + dup[i] = code; + this.replaceSelections(dup, collapse, origin || "+input"); + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin}; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]); + if (newSel) setSelectionReplaceHistory(this, newSel); + else if (this.cm) ensureCursorVisible(this.cm); + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), + + setExtending: function(val) {this.extend = val;}, + getExtending: function() {return this.extend;}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; + for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; + return {undo: done, redo: undone}; + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration);}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)}; + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (classTest(cls).test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(classTest(cls)); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + removeLineWidget: function(widget) { widget.clear(); }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function(line) { + var spans = line.markedSpans; + if (spans) for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(lineNo == from.line && from.ch > span.to || + span.from == null && lineNo != from.line|| + lineNo == to.line && span.from > to.ch) && + (!filter || filter(span.marker))) + found.push(span.marker.parent || span.marker); + } + ++lineNo; + }); + return found; + }, + getAllMarks: function() { + var markers = []; + this.iter(function(line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first; + this.iter(function(line) { + var sz = line.text.length + 1; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + 1; + }); + return index; + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function(options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + copySharedMarkers(copy, findSharedMarkers(this)); + return copy; + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + detachSharedMarkers(findSharedMarkers(this)); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode;}, + getEditor: function() {return this.cm;} + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments);}; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) findMaxLine(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); + for (var chunk = doc; !chunk.lines;) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function(line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to, lineFilter) { + var out = []; + doc.iter(from, to, function(line) { + var text = line.text; + if(lineFilter){ + text = lineFilter(line); + } + out.push(text); + }); + return out; + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) for (var n = line; n; n = n.parent) n.height += diff; + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0; i < chunk.children.length; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = this.lastSelOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); + return histChange; + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) array.pop(); + else break; + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done); + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done); + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done); + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, ore are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done); + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation}; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) hist.done.shift(); + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = hist.lastSelOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) signal(doc, "historyAdded"); + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel; + else + pushSelectionToHistory(sel, hist.done); + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastSelOp = opId; + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone); + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel); + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue; + } + var changes = event.changes, newChanges = []; + copy.push({changes: newChanges}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue; + } + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT UTILITIES + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + var e_preventDefault = CodeMirror.e_preventDefault = function(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + }; + var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + }; + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; + + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var on = CodeMirror.on = function(emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + }; + + var off = CodeMirror.off = function(emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + for (var i = 0; i < arr.length; ++i) + if (arr[i] == f) { arr.splice(i, 1); break; } + } + }; + + var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); + }; + + var orphanDelayedCallbacks = null; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + function signalLater(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2), list; + if (operationGroup) { + list = operationGroup.delayedCallbacks; + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks; + } else { + list = orphanDelayedCallbacks = []; + setTimeout(fireOrphanDelayed, 0); + } + function bnd(f) {return function(){f.apply(null, args);};}; + for (var i = 0; i < arr.length; ++i) + list.push(bnd(arr[i])); + } + + function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks; + orphanDelayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity; + if (!arr) return; + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); + for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) + set.push(arr[i]); + } + + function hasHandler(emitter, type) { + var arr = emitter._handlers && emitter._handlers[type]; + return arr && arr.length > 0; + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerGap = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; + + // Reused option objects for setSelection & friends + var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; + + function Delayed() {this.id = null;} + Delayed.prototype.set = function(ms, f) { + clearTimeout(this.id); + this.id = setTimeout(f, ms); + }; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + }; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + function findColumn(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) nextTab = string.length; + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col); + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) return pos; + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length-1]; } + + var selectInput = function(node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; + else if (ie) // Suppress mysterious IE10 errors + selectInput = function(node) { try { node.select(); } catch(_e) {} }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + if (array[i] == elt) return i; + return -1; + } + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); + return out; + } + + function nothing() {} + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) copyObj(props, inst); + return inst; + }; + + function copyObj(obj, target, overwrite) { + if (!target) target = {}; + for (var prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop]; + return target; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args);}; + } + + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var isWordCharBasic = CodeMirror.isWordChar = function(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + }; + function isWordChar(ch, helper) { + if (!helper) return isWordCharBasic(ch); + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; + return helper.test(ch); + } + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + var range; + if (document.createRange) range = function(node, start, end, endNode) { + var r = document.createRange(); + r.setEnd(endNode || node, end); + r.setStart(node, start); + return r; + }; + else range = function(node, start, end) { + var r = document.body.createTextRange(); + try { r.moveToElementText(node.parentNode); } + catch(e) { return r; } + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r; + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + var contains = CodeMirror.contains = function(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + child = child.parentNode; + if (parent.contains) + return parent.contains(child); + do { + if (child.nodeType == 11) child = child.host; + if (child == parent) return true; + } while (child = child.parentNode); + }; + + function activeElt() { return document.activeElement; } + // Older versions of IE throws unspecified error when touching + // document.activeElement in some cases (during loading, in iframe) + if (ie && ie_version < 11) activeElt = function() { + try { return document.activeElement; } + catch(e) { return document.body; } + }; + + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } + var rmClass = CodeMirror.rmClass = function(node, cls) { + var current = node.className; + var match = classTest(cls).exec(current); + if (match) { + var after = current.slice(match.index + match[0].length); + node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); + } + }; + var addClass = CodeMirror.addClass = function(node, cls) { + var current = node.className; + if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; + }; + function joinClasses(a, b) { + var as = a.split(" "); + for (var i = 0; i < as.length; i++) + if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; + return b; + } + + // WINDOW-WIDE EVENTS + + // These must be handled carefully, because naively registering a + // handler for each editor will cause the editors to never be + // garbage collected. + + function forEachCodeMirror(f) { + if (!document.body.getElementsByClassName) return; + var byClass = document.body.getElementsByClassName("CodeMirror"); + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror; + if (cm) f(cm); + } + } + + var globalsRegistered = false; + function ensureGlobalHandlers() { + if (globalsRegistered) return; + registerGlobalHandlers(); + globalsRegistered = true; + } + function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer; + on(window, "resize", function() { + if (resizeTimer == null) resizeTimer = setTimeout(function() { + resizeTimer = null; + forEachCodeMirror(onResize); + }, 100); + }); + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function() { + forEachCodeMirror(onBlur); + }); + } + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + node.setAttribute("cm-text", ""); + return node; + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects; + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) + var r1 = range(txt, 1, 2).getBoundingClientRect(); + return badBidiRects = (r1.right - r0.right < 3); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function(string){return string.split(/\r\n?|\n/);}; + + var hasSelection = window.getSelection ? function(te) { + try { return te.selectionStart != te.selectionEnd; } + catch(e) { return false; } + } : function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function() { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function"; + })(); + + var badZoomedRects = null; + function hasBadZoomedRects(measure) { + if (badZoomedRects != null) return badZoomedRects; + var node = removeChildrenAndAdd(measure, elt("span", "x")); + var normal = node.getBoundingClientRect(); + var fromRange = range(node, 0, 1).getBoundingClientRect(); + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; + } + + // KEY NAMES + + var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"}; + CodeMirror.keyNames = keyNames; + (function() { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line = getLine(cm.doc, lineN); + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + lineN = null; + } + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN == null ? lineNo(line) : lineN, ch); + } + function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line); + var line = getLine(cm.doc, start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; + return Pos(start.line, inWS ? 0 : firstNonWS); + } + return start; + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + bidiOther = null; + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) return i; + if ((cur.from == pos || cur.to == pos)) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + if (cur.from != cur.to) bidiOther = found; + return i; + } else { + if (cur.from != cur.to) bidiOther = i; + return found; + } + } + } + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar(line.text.charAt(pos))); + return pos; + } + + // This is needed in order to move 'visually' through bi-directional + // text -- i.e., pressing left should make the cursor go left, even + // when in RTL text. The tricky part is the 'jumps', where RTL and + // LTR text touch each other. This often requires the cursor offset + // to move more than one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (;;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); + else if (0x6ee <= code && code <= 0x8ac) return "r"; + else if (0x2000 <= code && code <= 0x200b) return "w"; + else if (code == 0x200c) return "b"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function(str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + var before = (i ? types[i-1] : outerType) == "L"; + var after = (end < len ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push(new BidiSpan(0, start, i)); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) {} + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, new BidiSpan(2, nstart, j)); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + if (order[0].level == 2) + order.unshift(new BidiSpan(1, order[0].to, order[0].to)); + if (order[0].level != lst(order).level) + order.push(new BidiSpan(order[0].level, len, len)); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "5.4.1"; + + return CodeMirror; +});; +(function ($) { + /** + * 公式编辑控件 + * @class BI.FormulaEditor + * @extends BI.Widget + */ + BI.FormulaEditor = BI.inherit(BI.Single, { + _defaultConfig: function () { + return $.extend(BI.FormulaEditor.superclass._defaultConfig.apply(), { + baseCls: 'bi-formula-editor', + watermark: '', + value: '', + fieldTextValueMap: {}, + showHint: true + }); + }, + _init: function () { + BI.FormulaEditor.superclass._init.apply(this, arguments); + var o = this.options, self = this; + this.editor = CodeMirror(this.element[0], { + textWrapping: true, + lineWrapping: true, + lineNumbers: false, + mode: 'formula' + }); + this.editor.on("change", function (cm, change) { + self._checkWaterMark(); + if(o.showHint){ + CodeMirror.showHint(cm, CodeMirror.formulaHint, {completeSingle: false}); + } + BI.nextTick(function () { + self.fireEvent(BI.FormulaEditor.EVENT_CHANGE) + }); + }); + + this.editor.on("focus", function () { + self._checkWaterMark(); + self.fireEvent(BI.FormulaEditor.EVENT_FOCUS); + }); + + this.editor.on("blur", function () { + self.fireEvent(BI.FormulaEditor.EVENT_BLUR); + }); + + + if (BI.isKey(o.value)) { + self.setValue(o.value); + } + + if (BI.isKey(this.options.watermark)) { + var self = this; + this.watermark = BI.createWidget({ + type: "bi.label", + cls: "bi-water-mark", + text: this.options.watermark, + whiteSpace: "nowrap", + textAlign: "left" + }); + BI.createWidget({ + type: "bi.absolute", + element: self, + items: [{ + el: self.watermark, + left: 0, + top: 0 + }] + }); + + this.watermark.element.bind( + "mousedown", function (e) { + self.insertString(""); + self.editor.focus(); + e.stopEvent(); + } + ); + this.watermark.element.bind("click", function (e) { + self.editor.focus(); + e.stopEvent(); + }); + this.watermark.element.css({ + position: "absolute", + left: 3, + right: 3, + top: 6, + bottom: 0 + }); + } + }, + + _checkWaterMark: function () { + var o = this.options; + if (!this.disabledWarterMark && BI.isEmptyString(this.editor.getValue()) && BI.isKey(o.watermark)) { + this.watermark && this.watermark.visible(); + } else { + this.watermark && this.watermark.invisible(); + } + }, + + disableWarterMark: function () { + this.disabledWarterMark = true; + this._checkWaterMark(); + }, + + focus: function() { + this.editor.focus(); + }, + + /** + * 添加字段 + * @param field + */ + insertField: function (field) { + var from = this.editor.getCursor(); + this.editor.replaceSelection(field); + var to = this.editor.getCursor(); + this.editor.markText(from, to, {className: 'fieldName', atomic: true, startStyle : "start", endStyle:"end"}); + this.editor.replaceSelection(" "); + this.editor.focus(); + }, + + insertFunction: function (fn) { + var from = this.editor.getCursor(); + this.editor.replaceSelection(fn); + var to = this.editor.getCursor(); + this.editor.markText(from, to, {className: "#function", atomic: true}); + this.editor.replaceSelection("() "); + to = this.editor.getCursor(); + to.ch = to.ch - 2; + this.editor.setCursor(to); + this.editor.focus(); + }, + insertOperator: function (op) { + var from = this.editor.getCursor(); + this.editor.replaceSelection(op); + var to = this.editor.getCursor(); + this.editor.markText(from, to, {className: "%operator", atomic: true}); + this.editor.replaceSelection(" "); + this.editor.focus(); + }, + + setFunction: function (v) { + var from = this.editor.getCursor(); + this.editor.replaceSelection(v); + var to = this.editor.getCursor(); + this.editor.markText(from, to, {className: "#function", atomic: true}); + }, + + insertString: function (str) { + this.editor.replaceSelection(str); + this.editor.focus(); + }, + + getFormulaString: function () { + return this.editor.getValue(); + }, + + getUsedFields: function () { + var fieldMap = this.options.fieldTextValueMap; + var fields = []; + this.editor.getValue(true, function (line) { + var value = line.text; + _.forEach(line.markedSpans, function (i, ms) { + switch (i.marker.className) { + case "fieldName": + var dId = fieldMap[value.substr(i.from, i.to - i.from)]; + if (!fields.contains(dId)) { + fields.push(dId); + } + + } + }); + }); + return fields; + }, + + getCheckString: function () { + return this.editor.getValue(true, function (line) { + var rawText = line.text, value = line.text, num = 0; + value.text = rawText; + _.forEach(line.markedSpans, function (i, ms) { + + switch (i.marker.className) { + case "fieldName": + var fieldNameLength = i.to - i.from; + value = value.substr(0, i.from + num) + "$a" + value.substr(i.to + num, value.length); + num = num + 2 - fieldNameLength; + break; + } + + }); + return value; + }); + }, + + getValue: function () { + var fieldMap = this.options.fieldTextValueMap; + return this.editor.getValue("\n", function (line) { + var rawText = line.text, value = line.text, num = 0; + value.text = rawText; + _.forEach(line.markedSpans, function (i, ms) { + switch (i.marker.className) { + case "fieldName": + var fieldNameLength = i.to - i.from; + var fieldId = fieldMap[value.substr(i.from + num, fieldNameLength)]; + value = value.substr(0, i.from + num) + "$\{" + fieldMap[value.substr(i.from + num, fieldNameLength)] + "\}" + value.substr(i.to + num, value.length); + num += fieldId.length - fieldNameLength + 3; + break; + } + }); + return value; + }); + }, + + setValue: function (value) { + this.editor.setValue(value); + }, + + setFieldTextValueMap: function (fieldTextValueMap) { + this.options.fieldTextValueMap = fieldTextValueMap; + }, + + refresh: function () { + var self = this; + BI.nextTick(function () { + self.editor.refresh(); + }); + } + + }); + BI.FormulaEditor.EVENT_CHANGE = "EVENT_CHANGE"; + BI.FormulaEditor.EVENT_BLUR = "EVENT_BLUR"; + BI.FormulaEditor.EVENT_FOCUS = "EVENT_FOCUS"; + $.shortcut("bi.formula", BI.FormulaEditor); +})(jQuery); +/** + * z-index在1亿层级 + * 弹出提示消息框,用于模拟阻塞操作(通过回调函数实现) + * @class BI.Msg + */ +$.extend(BI, { + Msg: function () { + + var messageShow, $mask, $pop; + + return { + alert: function (title, message, callback) { + this._show(false, title, message, callback); + }, + confirm: function (title, message, callback, min_width) { + this._show(true, title, message, callback); + }, + prompt: function (title, message, value, callback, min_width) { + FR.Msg.prompt(title, message, value, callback, min_width); + }, + toast: function (message, level, context) { + context = context || $("body"); + var toast = BI.createWidget({ + type: "bi.toast", + level: level, + text: message + }); + BI.createWidget({ + type: "bi.absolute", + element: context, + items: [{ + el: toast, + left: "50%", + top: 0 + }] + }); + if (toast.element.outerWidth() > context.outerWidth()) { + toast.setWidth(context.width()); + } + toast.element.css({"margin-left": -1 * toast.element.outerWidth() / 2}); + toast.invisible(); + toast.element.slideDown(500, function () { + BI.delay(function () { + toast.element.slideUp(500, function () { + toast.destroy(); + }) + }, 5000) + }) + }, + _show: function (hasCancel, title, message, callback) { + $mask = $('
    ').css({ + position: 'absolute', + 'zIndex': BI.zIndex_tip - 2, + top: 0, + left: 0, + right: 0, + bottom: 0, + opacity: 0.5 + }).appendTo('body'); + $pop = $('
    ').css({ + position: 'absolute', + 'zIndex': BI.zIndex_tip - 1, + top: 0, + left: 0, + right: 0, + bottom: 0 + }).appendTo('body'); + var close = function () { + messageShow.destroy(); + $mask.remove(); + }; + var controlItems = []; + if (hasCancel === true) { + controlItems.push({ + el: { + type: 'bi.button', + text: BI.i18nText("BI-Basic_Cancel"), + height: 30, + level: 'ignore', + handler: function () { + close(); + if (BI.isFunction(callback)) { + callback.apply(null, [false]); + } + } + } + }); + } + controlItems.push({ + el: { + type: 'bi.button', + text: BI.i18nText("BI-Basic_OK"), + height: 30, + handler: function () { + close(); + if (BI.isFunction(callback)) { + callback.apply(null, [true]); + } + } + } + }); + var conf = { + element: $pop, + type: 'bi.center_adapt', + items: [ + { + type: 'bi.border', + cls: 'bi-message-content', + items: { + 'north': { + el: { + type: 'bi.border', + cls: 'bi-message-title', + items: { + center: { + el: { + type: 'bi.label', + text: title || BI.i18nText("BI-Basic_Prompt"), + textAlign: 'left', + hgap: 20, + height: 50 + } + }, + east: { + el: { + type: 'bi.icon_button', + cls: 'bi-message-close close-font', +// height: 50, + handler: function () { + close(); + } + }, + width: 60 + } + } + }, + height: 50 + }, + 'center': { + el: { + type: "bi.text", + cls: "bi-message-text", + tgap: 60, + hgap: 20, + lineHeight: 30, + whiteSpace: "normal", + text: message + } + }, + 'south': { + el: { + type: "bi.absolute", + items: [{ + el: { + type: 'bi.right_vertical_adapt', + hgap: 5, + items: controlItems + }, + top: 0, + left: 20, + right: 20, + bottom: 0 + }] + + }, + height: 60 + } + }, + width: 400, + height: 300 + } + ] + }; + + messageShow = BI.createWidget(conf); + } + }; + }() +});/** + * Grid + * + * Created by GUY on 2016/1/11. + * @class BI.Grid + * @extends BI.Widget + */ +BI.Grid = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.Grid.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-grid", + width: 400, + height: 300, + overflowX: true, + overflowY: true, + overscanColumnCount: 0, + overscanRowCount: 0, + rowHeightGetter: BI.emptyFn, + columnWidthGetter: BI.emptyFn, + estimatedColumnSize: 100, + estimatedRowSize: 30, + scrollLeft: 0, + scrollTop: 0, + items: [] + }); + }, + + _init: function () { + BI.Grid.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.renderedCells = []; + this.renderedKeys = []; + this._scrollLock = false; + this._debounceRelease = BI.debounce(function () { + self._scrollLock = false; + }, 150); + this.container = BI.createWidget({ + type: "bi.absolute" + }); + this.element.scroll(function () { + if (self._scrollLock === true) { + return; + } + o.scrollLeft = self.element.scrollLeft(); + o.scrollTop = self.element.scrollTop(); + self._calculateChildrenToRender(); + self.fireEvent(BI.Grid.EVENT_SCROLL, { + scrollLeft: o.scrollLeft, + scrollTop: o.scrollTop + }); + }); + BI.createWidget({ + type: "bi.vertical", + element: this, + scrollable: o.overflowX === true && o.overflowY === true, + scrolly: o.overflowX === false && o.overflowY === true, + scrollx: o.overflowX === true && o.overflowY === false, + items: [this.container] + }); + if (o.items.length > 0) { + this._populate(); + } + if (o.scrollLeft !== 0 || o.scrollTop !== 0) { + BI.nextTick(function () { + self.element.scrollTop(o.scrollTop); + self.element.scrollLeft(o.scrollLeft); + }); + } + }, + + _getOverscanIndices: function (cellCount, overscanCellsCount, startIndex, stopIndex) { + return { + overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), + overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) + } + }, + + _calculateChildrenToRender: function () { + var self = this, o = this.options; + + var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()), + overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount; + + if (height > 0 && width > 0) { + var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); + var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); + + var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft); + var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); + + this._renderedColumnStartIndex = visibleColumnIndices.start; + this._renderedColumnStopIndex = visibleColumnIndices.stop; + this._renderedRowStartIndex = visibleRowIndices.start; + this._renderedRowStopIndex = visibleRowIndices.stop; + + var overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex) + + var overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex); + + var columnStartIndex = overscanColumnIndices.overscanStartIndex; + var columnStopIndex = overscanColumnIndices.overscanStopIndex; + var rowStartIndex = overscanRowIndices.overscanStartIndex; + var rowStopIndex = overscanRowIndices.overscanStopIndex; + + var renderedCells = [], renderedKeys = []; + + for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { + var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); + + for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { + var key = [rowIndex, columnIndex]; + var columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); + + var index = BI.deepIndexOf(this.renderedKeys, key); + if (index > -1) { + if (columnDatum.size !== this.renderedCells[index]._width) { + this.renderedCells[index]._width = columnDatum.size; + this.renderedCells[index].el.setWidth(columnDatum.size); + } + if (rowDatum.size !== this.renderedCells[index]._height) { + this.renderedCells[index]._height = rowDatum.size; + this.renderedCells[index].el.setHeight(rowDatum.size); + } + if (this.renderedCells[index].left !== columnDatum.offset + horizontalOffsetAdjustment) { + this.renderedCells[index].el.element.css("left", (columnDatum.offset + horizontalOffsetAdjustment) + "px"); + } + if (this.renderedCells[index].top !== rowDatum.offset + verticalOffsetAdjustment) { + this.renderedCells[index].el.element.css("top", (rowDatum.offset + verticalOffsetAdjustment) + "px"); + } + renderedCells.push(this.renderedCells[index]); + } else { + var child = BI.createWidget(BI.extend({ + type: "bi.label", + width: columnDatum.size, + height: rowDatum.size + }, o.items[rowIndex][columnIndex], { + cls: (o.items[rowIndex][columnIndex].cls || "") + " grid-cell" + (rowIndex === 0 ? " first-row" : "") + (columnIndex === 0 ? " first-col" : ""), + _rowIndex: rowIndex, + _columnIndex: columnIndex, + _left: columnDatum.offset + horizontalOffsetAdjustment, + _top: rowDatum.offset + verticalOffsetAdjustment + })); + renderedCells.push({ + el: child, + left: columnDatum.offset + horizontalOffsetAdjustment, + top: rowDatum.offset + verticalOffsetAdjustment, + _width: columnDatum.size, + _height: rowDatum.size + }); + } + renderedKeys.push(key); + } + } + //已存在的, 需要添加的和需要删除的 + var existSet = {}, addSet = {}, deleteArray = []; + BI.each(renderedKeys, function (i, key) { + if (BI.deepContains(self.renderedKeys, key)) { + existSet[i] = key; + } else { + addSet[i] = key; + } + }); + BI.each(this.renderedKeys, function (i, key) { + if (BI.deepContains(existSet, key)) { + return; + } + if (BI.deepContains(addSet, key)) { + return; + } + deleteArray.push(i); + }); + BI.each(deleteArray, function (i, index) { + self.renderedCells[index].el.destroy(); + }); + var addedItems = []; + BI.each(addSet, function (index) { + addedItems.push(renderedCells[index]) + }); + BI.createWidget({ + type: "bi.absolute", + element: this.container, + items: addedItems + }); + this.renderedCells = renderedCells; + this.renderedKeys = renderedKeys; + } + }, + + _getMaxScrollLeft: function () { + return Math.max(0, this._columnSizeAndPositionManager.getTotalSize() - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); + }, + + _getMaxScrollTop: function () { + return Math.max(0, this._rowSizeAndPositionManager.getTotalSize() - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); + }, + + _populate: function () { + var self = this, o = this.options; + if (o.items.length > 0) { + this.columnCount = o.items[0].length; + this.rowCount = o.items.length; + this.container.setWidth(this.columnCount * o.estimatedColumnSize); + this.container.setHeight(this.rowCount * o.estimatedRowSize); + + this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, o.columnWidthGetter, o.estimatedColumnSize); + this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, o.rowHeightGetter, o.estimatedRowSize); + + this._calculateChildrenToRender(); + this.element.scrollTop(o.scrollTop); + this.element.scrollLeft(o.scrollLeft); + } + }, + + setScrollLeft: function (scrollLeft) { + if (this.options.scrollLeft === scrollLeft) { + return; + } + this._scrollLock = true; + this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); + this._debounceRelease(); + this._calculateChildrenToRender(); + this.element.scrollLeft(this.options.scrollLeft); + }, + + setScrollTop: function (scrollTop) { + if (this.options.scrollTop === scrollTop) { + return; + } + this._scrollLock = true; + this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); + this._debounceRelease(); + this._calculateChildrenToRender(); + this.element.scrollTop(this.options.scrollTop); + }, + + setOverflowX: function (b) { + var self = this; + if (this.options.overflowX !== !!b) { + this.options.overflowX = !!b; + BI.nextTick(function () { + self.element.css({overflowX: !!b ? "auto" : "hidden"}); + }); + } + }, + + setOverflowY: function (b) { + var self = this; + if (this.options.overflowY !== !!b) { + this.options.overflowY = !!b; + BI.nextTick(function () { + self.element.css({overflowY: !!b ? "auto" : "hidden"}); + }); + } + }, + + getScrollLeft: function () { + return this.options.scrollLeft; + }, + + getScrollTop: function () { + return this.options.scrollTop; + }, + + getMaxScrollLeft: function () { + return this._getMaxScrollLeft(); + }, + + getMaxScrollTop: function () { + return this._getMaxScrollTop(); + }, + + setEstimatedColumnSize: function (width) { + this.options.estimatedColumnSize = width; + }, + + setEstimatedRowSize: function (height) { + this.options.estimatedRowSize = height; + }, + + restore: function () { + BI.each(this.renderedCells, function (i, cell) { + cell.el.destroy(); + }); + this.renderedCells = []; + this.renderedKeys = []; + this._scrollLock = false; + }, + + populate: function (items) { + if (items && items !== this.options.items) { + this.options.items = items; + this.restore(); + } + this._populate(); + } +}); +BI.Grid.EVENT_SCROLL = "EVENT_SCROLL"; +$.shortcut('bi.grid_view', BI.Grid);/** + * floatBox弹出层, + * @class BI.FloatBox + * @extends BI.Widget + */ +BI.FloatBox = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.FloatBox.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-float-box", + width: 600, + height: 500 + }) + }, + _init: function () { + BI.FloatBox.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.showAction = new BI.ShowAction({ + tar: this + }); + this._center = BI.createWidget(); + this._north = BI.createWidget(); + this.element.draggable({ + cursor: BICst.cursorUrl, + handle: ".bi-message-title", + drag: function (e, ui) { + var W = $("body").width(), H = $("body").height(); + if (ui.position.left + o.width > W) { + ui.position.left = W - o.width; + } + if (ui.position.top + o.height > H) { + ui.position.top = H - o.height; + } + if (ui.position.left < 0) { + ui.position.left = 0; + } + if (ui.position.top < 0) { + ui.position.top = 0; + } + } + }); + this._south = BI.createWidget(); + BI.createWidget({ + type: 'bi.border', + element: this, + items: { + 'north': { + el: { + type: 'bi.border', + cls: 'bi-message-title', + items: { + center: { + el: { + type: "bi.absolute", + items: [{ + el: this._north, + left: 10, + top: 0, + right: 0, + bottom: 0 + }] + } + }, + east: { + el: { + type: 'bi.icon_button', + cls: 'bi-message-close close-font', + height: 50, + handler: function () { + self.currentSectionProvider.close(); + } + }, + width: 60 + } + } + }, + height: 50 + }, + 'center': { + el: { + type: "bi.absolute", + items: [{ + el: this._center, + left: 10, + top: 10, + right: 10, + bottom: 10 + }] + } + }, + 'south': { + el: { + type: "bi.absolute", + items: [{ + el: this._south, + left: 10, + top: 0, + right: 10, + bottom: 0 + }] + }, + height: 60 + } + } + }) + }, + + populate: function (sectionProvider) { + var self = this; + this.currentSectionProvider = sectionProvider; + sectionProvider.rebuildNorth(this._north); + sectionProvider.rebuildCenter(this._center); + sectionProvider.rebuildSouth(this._south); + if (sectionProvider instanceof BI.Widget) { + sectionProvider.on(BI.PopoverSection.EVENT_CLOSE, function () { + self.close(); + }) + } + }, + + show: function () { + this.showAction.actionPerformed(); + }, + + hide: function () { + this.showAction.actionBack(); + }, + + open: function () { + this.show(); + this.fireEvent(BI.FloatBox.EVENT_FLOAT_BOX_OPEN); + }, + + close: function () { + this.hide(); + this.fireEvent(BI.FloatBox.EVENT_FLOAT_BOX_CLOSED); + }, + + setZindex: function (zindex) { + this.element.css({"z-index": zindex}); + } +}); + +$.shortcut("bi.float_box", BI.FloatBox); + +BI.FloatBox.EVENT_FLOAT_BOX_CLOSED = "EVENT_FLOAT_BOX_CLOSED"; +BI.FloatBox.EVENT_FLOAT_BOX_OPEN = "EVENT_FLOAT_BOX_CLOSED"; +/** + * 下拉框弹出层, zIndex在1000w + * @class BI.PopupView + * @extends BI.Widget + */ +BI.PopupView = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-view", + maxWidth: 'auto', + minWidth: 100, + //maxHeight: 200, + minHeight: 25, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + hgap: 0, + direction: BI.Direction.Top, //工具栏的方向 + stopEvent: false,//是否停止mousedown、mouseup事件 + stopPropagation: false, //是否停止mousedown、mouseup向上冒泡 + logic: { + dynamic: true + }, + + tool: false, //自定义工具栏 + tabs: [], //导航栏 + buttons: [], //toolbar栏 + + el: { + type: "bi.button_group", + items: [], + chooseType: 0, + behaviors: {}, + layouts: [{ + type: "bi.vertical" + }] + } + }) + }, + + _init: function () { + BI.PopupView.superclass._init.apply(this, arguments); + var self = this, o = this.options; + var fn = function (e) { + e.stopPropagation(); + }, stop = function (e) { + e.stopEvent(); + return false; + }; + this.element.css({ + "z-index": BI.zIndex_popup, + "min-width": o.minWidth + "px", + "max-width": o.maxWidth + "px" + }).bind({"click": fn}); + + //FIXME IE8下 jquery.mousewheeel.js 第一次执行65行$elem["offsetParent"]()的时候报错:未指明的错误 但是第二次或者调试的时候展开一下$elem内容均能避免上述问题 + try { + this.element.bind("mousewheel", fn); + } catch (e) { + this.element.bind("mousewheel", fn); + } + + o.stopPropagation && this.element.bind({"mousedown": fn, "mouseup": fn, "mouseover": fn}); + o.stopEvent && this.element.bind({"mousedown": stop, "mouseup": stop, "mouseover": stop}); + this.tool = this._createTool(); + this.tab = this._createTab(); + this.view = this._createView(); + this.toolbar = this._createToolBar(); + + this.button_group.on(BI.Controller.EVENT_CHANGE, function (type) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.PopupView.EVENT_CHANGE); + } + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { + scrolly: false, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + vgap: o.vgap, + hgap: o.hgap, + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, + BI.extend({ + cls: "list-view-outer" + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tool, this.tab, this.view, this.toolbar) + }))) + ) + })))); + }, + + _createView: function () { + var o = this.options; + this.button_group = BI.createWidget(o.el, {type: "bi.button_group"}); + this.button_group.element.css({"min-height": o.minHeight + "px"}); + return this.button_group; + }, + + _createTool: function () { + var o = this.options; + if (false === o.tool) { + return; + } + return BI.createWidget(o.tool) + }, + + _createTab: function () { + var o = this.options; + if (o.tabs.length === 0) { + return; + } + return BI.createWidget({ + type: "bi.center", + cls: "list-view-tab", + height: 25, + items: o.tabs + }) + }, + + _createToolBar: function () { + var o = this.options; + if (o.buttons.length === 0) { + return; + } + + return BI.createWidget({ + type: "bi.center", + cls: "list-view-toolbar", + height: 30, + items: BI.createItems(o.buttons, { + once: false, + shadow: true, + isShadowShowingOnSelected: true + }) + }) + }, + + getView: function () { + return this.button_group; + }, + + populate: function (items) { + this.button_group.populate.apply(this.button_group, arguments); + }, + + resetWidth: function (w) { + this.options.width = w; + this.element.width(w); + }, + + resetHeight: function (h) { + var tbHeight = this.toolbar ? (this.toolbar.attr("height") || 30) : 0, + tabHeight = this.tab ? (this.tab.attr("height") || 25) : 0, + toolHeight = ((this.tool && this.tool.attr("height")) || 25) * ((this.tool && this.tool.isVisible()) ? 1 : 0); + this.view.resetHeight ? this.view.resetHeight(h - tbHeight - tabHeight - toolHeight - 2) : + this.view.element.css({"max-height": (h - tbHeight - tabHeight - toolHeight - 2) + "px"}) + }, + + setEnable: function (arg) { + BI.PopupView.superclass.setEnable.apply(this, arguments); + this.view && this.view.setEnable(arg); + }, + + setValue: function (selectedValues) { + this.tab && this.tab.setValue(selectedValues); + this.button_group.setValue(selectedValues); + }, + + getValue: function () { + return this.button_group.getValue(); + } +}); +BI.PopupView.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.popup_view", BI.PopupView);/** + * guy + * @class BI.ScrollView + * @extends BI.Widget + */ +BI.ScrollView = BI.inherit(BI.Widget, { + + _const: { + dropDownHeight: 15, + expandIcon: "column-next-page-h-font", + collapseIcon: "column-pre-page-h-font" + }, + + _defaultConfig: function() { + return BI.extend(BI.ScrollView.superclass._defaultConfig.apply(this, arguments), { + baseCls:"bi-scroll-view", + scrollHeight: 50, + maxHeight: 300 + }) + }, + + _init : function() { + BI.ScrollView.superclass._init.apply(this, arguments); + + this.scrollUp = false; + this.scroll = BI.createWidget({ + type: "bi.vertical", + cls: "scroll-container", + scrolly: true + }) + BI.createWidget({ + type: "bi.vertical", + element: this, + scrolly: false, + items: [this.scroll] + }) + + this.dropdown = BI.createWidget({ + type: "bi.icon_button", + height: this._const.dropDownHeight, + cls: "scroll-drop-down-icon " + this._const.expandIcon, + handler: BI.bind(this._dropDownOrUp, this) + }) + + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.dropdown, + left: 0, + right: 0, + bottom: -1 * this._const.dropDownHeight + }] + }) + this.populate(this.options.items); + }, + + _dropDownOrUp: function(){ + if(!this.scrollUp){ + var height = this.element.height(); + height += this.options.scrollHeight; + height = Math.min(height, this.scroll.element[0].scrollHeight, this.options.maxHeight); + this.element.height(height); + this._checkDropDownState(); + } else { + var height = this.element.height(); + height -= this.options.scrollHeight; + height = Math.max(height, this.options.height); + this.element.height(height); + this._checkDropDownState(); + } + }, + + _checkDropDownState: function(){ + var height = this.element.height(); + if(!this._checkScroll() || height >= this.options.maxHeight){ + this.scrollUp = true; + this.dropdown.element.removeClass(this._const.expandIcon).addClass(this._const.collapseIcon); + } else if(height <= this.options.height){ + this.scrollUp = false; + this.dropdown.element.addClass(this._const.expandIcon); + } else { + this.dropdown.element.addClass(this.scrollUp ? this._const.collapseIcon : this._const.expandIcon); + } + }, + + _checkScroll: function(){ + this.scroll.element.height(this.element.height()); + return this.scroll.element[0].scrollHeight > this.scroll.element[0].clientHeight; + }, + + _checkDropDown: function(){ + if(this._checkScroll()){ + this.dropdown.visible(); + //this.scrollUp = false; + this._checkDropDownState(); + } else { + this.dropdown.invisible(); + } + }, + + populate: function(){ + this.scroll.populate.apply(this.scroll, arguments); + this.resize(); + }, + + resize: function(){ + this.element.height(this.options.height); + BI.nextTick(BI.bind(this._checkDropDown, this)); + }, + + addItem: function(){ + this.scroll.addItem.apply(this.scroll, arguments); + BI.nextTick(BI.bind(this._checkDropDown, this)); + } +}); + +$.shortcut("bi.scroll_view", BI.ScrollView);/** + * 搜索面板 + * + * Created by GUY on 2015/9/28. + * @class BI.SearcherView + * @extends BI.Pane + */ + +BI.SearcherView = BI.inherit(BI.Pane, { + _defaultConfig: function () { + var conf = BI.SearcherView.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-searcher-view", + tipText: BI.i18nText("BI-No_Select"), + chooseType: BI.Selection.Single, + + matcher: {//完全匹配的构造器 + type: "bi.button_group", + behaviors: { + redmark: function () { + return true; + } + }, + items: [], + layouts: [{ + type: "bi.vertical" + }] + }, + searcher: { + type: "bi.button_group", + behaviors: { + redmark: function () { + return true; + } + }, + items: [], + layouts: [{ + type: "bi.vertical" + }] + } + }) + }, + + _init: function () { + BI.SearcherView.superclass._init.apply(this, arguments); + var self = this, o = this.options; + + this.matcher = BI.createWidget(o.matcher, { + type: "bi.button_group", + chooseType: o.chooseType, + behaviors: { + redmark: function () { + return true; + } + }, + layouts: [{ + type: "bi.vertical" + }] + }); + this.matcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); + } + }); + this.spliter = BI.createWidget({ + type: "bi.vertical", + height: 1, + hgap: 10, + items: [{ + type: "bi.layout", + height: 1, + cls: "searcher-view-spliter" + }] + }); + this.searcher = BI.createWidget(o.searcher, { + type: "bi.button_group", + chooseType: o.chooseType, + behaviors: { + redmark: function () { + return true; + } + }, + layouts: [{ + type: "bi.vertical" + }] + }); + this.searcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + if (type === BI.Events.CLICK) { + self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); + } + }); + + BI.createWidget({ + type: "bi.vertical", + element: this, + items: [this.matcher, this.spliter, this.searcher] + }); + }, + + startSearch: function () { + + }, + + stopSearch: function () { + + }, + + setValue: function (v) { + this.matcher.setValue(v); + this.searcher.setValue(v); + }, + + getValue: function () { + return this.matcher.getValue().concat(this.searcher.getValue()); + }, + + populate: function (searchResult, matchResult, keyword) { + searchResult || (searchResult = []); + matchResult || (matchResult = []); + this.setTipVisible(searchResult.length + matchResult.length === 0); + this.spliter.setVisible(BI.isNotEmptyArray(matchResult) && BI.isNotEmptyArray(searchResult)); + this.matcher.populate(matchResult, keyword); + this.searcher.populate(searchResult, keyword); + }, + + empty: function () { + this.searcher.empty(); + this.matcher.empty(); + }, + + hasMatched: function () { + return this.matcher.getAllButtons().length > 0; + } +}); +BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; + +$.shortcut("bi.searcher_view", BI.SearcherView);/** + * 分页控件 + * + * Created by GUY on 2015/8/31. + * @class BI.Pager + * @extends BI.Widget + */ +BI.Pager = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.Pager.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-pager", + behaviors: {}, + layouts: [{ + type: "bi.horizontal", + hgap: 10, + vgap: 0 + }], + + dynamicShow: true, //是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 + //dynamicShow为false时以下两个有用 + dynamicShowFirstLast: false,//是否动态显示首页、尾页 + dynamicShowPrevNext: false,//是否动态显示上一页、下一页 + pages: false, //总页数 + curr: function () { + return 1; + }, //初始化当前页 + groups: 0, //连续显示分页数 + jump: BI.emptyFn, //分页的回调函数 + + first: false, //是否显示首页 + last: false, //是否显示尾页 + prev: "上一页", + next: "下一页", + + firstPage: 1, + lastPage: function () { //在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 + return 1; + }, + hasPrev: BI.emptyFn, //pages不可用时有效 + hasNext: BI.emptyFn //pages不可用时有效 + }) + }, + _init: function () { + BI.Pager.superclass._init.apply(this, arguments); + var self = this; + this.currPage = BI.result(this.options, "curr"); + //翻页太灵敏 + this._lock = false; + this._debouce = BI.debounce(function () { + self._lock = false; + }, 300); + this._populate(); + }, + + _populate: function () { + var self = this, o = this.options, view = [], dict = {}; + this.empty(); + var pages = BI.result(o, "pages"); + var curr = BI.result(this, "currPage"); + var groups = BI.result(o, "groups"); + var first = BI.result(o, "first"); + var last = BI.result(o, "last"); + var prev = BI.result(o, "prev"); + var next = BI.result(o, "next"); + + if (pages === false) { + groups = 0; + first = false; + last = false; + } else { + groups > pages && (groups = pages); + } + + //计算当前组 + dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); + + //当前页非首页,则输出上一页 + if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { + if (BI.isKey(prev)) { + view.push({ + text: prev, + value: "prev", + disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) + }) + } else { + view.push(BI.extend({ + disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) + }, prev)); + } + } + + //当前组非首组,则输出首页 + if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { + view.push({ + text: first, + value: "first", + disabled: !(dict.index > 1 && groups !== 0) + }); + if (dict.index > 1 && groups !== 0) { + view.push({ + type: "bi.label", + cls: "page-ellipsis", + text: "\u2026" + }); + } + } + + //输出当前页组 + dict.poor = Math.floor((groups - 1) / 2); + dict.start = dict.index > 1 ? curr - dict.poor : 1; + dict.end = dict.index > 1 ? (function () { + var max = curr + (groups - dict.poor - 1); + return max > pages ? pages : max; + }()) : groups; + if (dict.end - dict.start < groups - 1) { //最后一组状态 + dict.start = dict.end - groups + 1; + } + var s = dict.start, e = dict.end; + if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { + s++; + e--; + } + for (; s <= e; s++) { + if (s === curr) { + view.push({ + text: s, + value: s, + selected: true + }) + } else { + view.push({ + text: s, + value: s + }) + } + } + + //总页数大于连续分页数,且当前组最大页小于总页,输出尾页 + if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { + if (pages > groups && dict.end < pages && groups !== 0) { + view.push({ + type: "bi.label", + cls: "page-ellipsis", + text: "\u2026" + }); + } + view.push({ + text: last, + value: "last", + disabled: !(pages > groups && dict.end < pages && groups !== 0) + }) + } + + //当前页不为尾页时,输出下一页 + dict.flow = !prev && groups === 0; + if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { + view.push((function () { + if (BI.isKey(next)) { + if (pages === false) { + return {text: next, value: "next", disabled: o.hasNext(curr) === false} + } + return (dict.flow && curr === pages) + ? + {text: next, value: "next", disabled: true} + : + {text: next, value: "next", disabled: !(curr !== pages && next || dict.flow)}; + } else { + return BI.extend({ + disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow) + }, next); + } + }())); + } + + this.button_group = BI.createWidget({ + type: "bi.button_group", + element: this, + items: BI.createItems(view, { + cls: "page-item", + height: 23, + hgap: 10 + }), + behaviors: o.behaviors, + layouts: o.layouts + }); + this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { + if (self._lock === true) { + return; + } + self._lock = true; + self._debouce(); + if (type === BI.Events.CLICK) { + var v = self.button_group.getValue()[0]; + switch (v) { + case "first": + self.currPage = 1; break; - case bottomright: - colgroupTds = self.bottomRightColGroupTds; - bodyTds = self.bottomRightBodyTds; - bodyItems = self.bottomRightBodyItems; - sizes = columnRight; + case "last": + self.currPage = pages; + break; + case "prev": + self.currPage--; + break; + case "next": + self.currPage++; + break; + default: + self.currPage = v; + break; + } + o.jump.apply(self, [{ + pages: pages, + curr: self.currPage + }]); + self._populate(); + self.fireEvent(BI.Pager.EVENT_CHANGE, obj); + } + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + this.fireEvent(BI.Pager.EVENT_AFTER_POPULATE); + }, + + getCurrentPage: function () { + return this.currPage; + }, + + setAllPages: function (pages) { + this.options.pages = pages; + }, + + hasPrev: function (v) { + v || (v = 1); + var o = this.options; + var pages = this.options.pages; + return pages === false ? o.hasPrev(v) : v > 1; + }, + + hasNext: function (v) { + v || (v = 1); + var o = this.options; + var pages = this.options.pages; + return pages === false ? o.hasNext(v) : v < pages; + }, + + setValue: function (v) { + var o = this.options; + v = v | 0; + v = v < 1 ? 1 : v; + if (o.pages === false) { + var lastPage = BI.result(o, "lastPage"), firstPage = 1; + this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); + } else { + v = v > o.pages ? o.pages : v; + this.currPage = v; + } + this._populate(); + }, + + getValue: function () { + var val = this.button_group.getValue()[0]; + switch (val) { + case "prev": + return -1; + case "next": + return 1; + case "first": + return BI.MIN; + case "last": + return BI.MAX; + default : + return val; + } + }, + + attr: function (key, value) { + BI.Pager.superclass.attr.apply(this, arguments); + if (key === "curr") { + this.currPage = BI.result(this.options, "curr"); + } + }, + + populate: function () { + this._populate(); + } +}); +BI.Pager.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Pager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; +$.shortcut("bi.pager", BI.Pager);/** + * Created by Young's on 2016/8/17. + * 加载面板,一般只用于 requestAsync 中 + */ +BI.RequstLoading = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.RequstLoading.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.RequstLoading.superclass._init.apply(this, arguments); + var self = this, o = this.options; + var mask = BI.Maskers.create(BI.RequstLoading.MASK_ID); + this.callback = o.callback; + this.paneTab = BI.createWidget({ + type: "bi.tab", + cardCreator: BI.bind(this._cardCreator, this), + defaultShowIndex: BI.RequstLoading.ERROR, + width: 400, + height: 300 + }); + var tempIcon = BI.createWidget({ + type: "bi.icon_button", + cls: "data-link-test-fail-icon", + width: 0, + height: 0 + }); + BI.createWidget({ + type: "bi.absolute", + element: $('body'), + items: [{ + el: tempIcon, + bottom: 0 + }] + }); + + BI.createWidget({ + type: "bi.absolute", + element: mask, + cls: "bi-request-loading", + items: [{ + el: { + type: "bi.layout", + cls: "mask-pane" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + }, { + el: { + type: "bi.center_adapt", + items: [this.paneTab] + }, + top: 0, + left: 0, + right: 0, + bottom: 0 + }] + }); + }, + + _cardCreator: function (v) { + var self = this; + var cancel = BI.createWidget({ + type: "bi.button", + text: BI.i18nText("BI-Basic_Cancel"), + title: BI.i18nText("BI-Basic_Cancel"), + level: "ignore", + height: 28, + width: 90, + handler: function () { + BI.Maskers.hide(BI.RequstLoading.MASK_ID); + } + }); + var retry = BI.createWidget({ + type: "bi.button", + text: BI.i18nText("BI-Basic_Retry"), + title: BI.i18nText("BI-Basic_Retry"), + level: "common", + height: 28, + width: 90, + handler: function () { + self.paneTab.setSelect(BI.RequstLoading.LOADING); + self.callback(); + } + }); + switch (v) { + case BI.RequstLoading.LOADING: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "loading-bar-icon", + items: [{ + type: "bi.icon", + width: 208, + height: 15 + }] + }, { + type: "bi.label", + cls: "loading-comment", + text: BI.i18nText("BI-Basic_Loading"), + height: 30 + }], + width: 208, + height: 200, + vgap: 10 + }); + case BI.RequstLoading.LOADING_TIMEOUT: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "loading-bar-icon", + items: [{ + type: "bi.icon", + width: 208, + height: 15 + }] + }, { + type: "bi.label", + cls: "loading-comment", + text: BI.i18nText("BI-Basic_Loading"), + height: 30 + }, { + type: "bi.label", + text: BI.i18nText("BI-Request_Time_Out_Toast_Tip"), + cls: "load-timeout-warning" + }, { + type: "bi.left_right_vertical_adapt", + items: { + left: [cancel], + right: [retry] + }, + height: 30, + llgap: 100, + rrgap: 100 + }], + vgap: 10 + }); + case BI.RequstLoading.ERROR: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "data-link-test-fail-icon", + items: [{ + type: "bi.icon", + width: 126, + height: 126 + }] + }, { + type: "bi.label", + text: BI.i18nText("BI-Connection_Lost"), + cls: "load-fail-comment" + }, { + type: "bi.left_right_vertical_adapt", + items: { + left: [cancel], + right: [retry] + }, + height: 30, + llgap: 100, + rrgap: 100 + }], + vgap: 20 + }); + } + }, + + showLoading: function () { + BI.Maskers.show(BI.RequstLoading.MASK_ID); + this.paneTab.setSelect(BI.RequstLoading.LOADING); + }, + + showError: function () { + BI.Maskers.show(BI.RequstLoading.MASK_ID); + this.paneTab.setSelect(BI.RequstLoading.ERROR); + }, + + setCallback: function (callback) { + this.callback = callback; + } +}); +BI.extend(BI.RequstLoading, { + MASK_ID: "___request__loading___", + LOADING: 1, + LOADING_TIMEOUT: 2, + ERROR: 3 +}); +$.shortcut("bi.request_loading", BI.RequstLoading);/** + * 超链接 + * + * Created by GUY on 2015/9/9. + * @class BI.A + * @extends BI.Text + * @abstract + */ +BI.A = BI.inherit(BI.Text, { + _defaultConfig: function () { + var conf = BI.A.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-a display-block", + href: "", + target: "_blank", + el: null, + element: "" + }) + }, + _init: function () { + var o = this.options; + BI.A.superclass._init.apply(this, arguments); + this.element.attr({href: o.href, target: o.target}); + if (o.el) { + BI.createWidget(o.el, { + element: this + }); + } + } +}); + +$.shortcut("bi.a", BI.A);/** + * guy + * 加载条 + * @type {*|void|Object} + */ +BI.LoadingBar = BI.inherit(BI.Single, { + consts: { + loadedText: BI.i18nText("BI-Load_More"), + endText: BI.i18nText("BI-No_More_Data") + }, + _defaultConfig: function() { + var conf = BI.LoadingBar.superclass._defaultConfig.apply(this, arguments); + return BI.extend( conf, { + baseCls : (conf.baseCls ||"")+' bi-loading-bar', + height: 30, + handler: BI.emptyFn + }) + }, + _init : function() { + BI.LoadingBar.superclass._init.apply(this, arguments); + var self = this; + this.loaded = BI.createWidget({ + type: "bi.text_button", + cls: "loading-text", + text: this.consts.loadedText, + width: 120, + handler: this.options.handler + }) + this.loaded.on(BI.Controller.EVENT_CHANGE, function(type){ + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }) + + this.loading = BI.createWidget({ + type: "bi.layout", + height:this.options.height, + cls: "loading-background cursor-default" + }) + var loaded = BI.createWidget({ + type: "bi.center_adapt", + items: [this.loaded] + }) + var loading = BI.createWidget({ + type: "bi.center_adapt", + items: [this.loading] + }) + this.cardLayout = BI.createWidget({ + type: "bi.card", + element: this, + items: [{ + el: loaded, + cardName: "loaded" + }, { + el: loading, + cardName: "loading" + }] + }) + this.invisible(); + }, + + _reset: function(){ + this.visible(); + this.loaded.setText(this.consts.loadedText); + this.loaded.enable(); + }, + + setLoaded: function(){ + this._reset(); + this.cardLayout.showCardByName("loaded"); + }, + + setEnd: function(){ + this.setLoaded(); + this.loaded.setText(this.consts.endText); + this.loaded.disable(); + }, + + setLoading: function(){ + this._reset(); + this.cardLayout.showCardByName("loading"); + } +}); + +$.shortcut("bi.loading_bar", BI.LoadingBar);/** + * @class BI.IconButton + * @extends BI.BasicButton + * 图标的button + */ +BI.IconButton = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + var conf = BI.IconButton.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-icon-button horizon-center", + iconWidth: null, + iconHeight: null + }) + }, + + _init: function () { + BI.IconButton.superclass._init.apply(this, arguments); + var o = this.options; + this.element.css({ + textAlign: 'center' + }); + this.icon = BI.createWidget({ + type: 'bi.icon', + width: o.iconWidth, + height: o.iconHeight + }); + if (BI.isNumber(o.height) && o.height > 0 && BI.isNull(o.iconWidth) && BI.isNull(o.iconHeight)) { + this.element.css("lineHeight", o.height + "px"); + BI.createWidget({ + type: "bi.default", + element: this, + items: [this.icon] + }) + } else { + BI.createWidget({ + element: this, + type: 'bi.center_adapt', + items: [this.icon] + }); + } + }, + + doClick: function () { + BI.IconButton.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.IconButton.EVENT_CHANGE, this); + } + } +}); +BI.IconButton.EVENT_CHANGE = "IconButton.EVENT_CHANGE"; +$.shortcut("bi.icon_button", BI.IconButton);/** + * 图片的button + * + * Created by GUY on 2016/1/27. + * @class BI.ImageButton + * @extends BI.BasicButton + */ +BI.ImageButton = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + var conf = BI.ImageButton.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-image-button", + src: "", + iconWidth: "100%", + iconHeight: "100%" + }) + }, + + _init: function () { + BI.ImageButton.superclass._init.apply(this, arguments); + var o = this.options; + this.image = BI.createWidget({ + type: "bi.img", + width: o.iconWidth, + height: o.iconHeight, + src: o.src + }); + if (BI.isNumber(o.iconWidth) || BI.isNumber(o.iconHeight)) { + BI.createWidget({ + type: "bi.center_adapt", + element: this, + items: [this.image] + }) + } else { + BI.createWidget({ + type: "bi.adaptive", + element: this, + items: [this.image], + scrollable: false + }) + } + }, + + setWidth: function (w) { + BI.ImageButton.superclass.setWidth.apply(this, arguments); + this.options.width = w; + }, + + setHeight: function (h) { + BI.ImageButton.superclass.setHeight.apply(this, arguments); + this.options.height = h; + }, + + setImageWidth: function (w) { + this.image.setWidth(w); + }, + + setImageHeight: function (h) { + this.image.setHeight(h); + }, + + getImageWidth: function () { + return this.image.element.width(); + }, + + getImageHeight: function () { + return this.image.element.height(); + }, + + setSrc: function (src) { + this.options.src = src; + this.image.setSrc(src); + }, + + getSrc: function () { + return this.image.getSrc(); + }, + + doClick: function () { + BI.ImageButton.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.ImageButton.EVENT_CHANGE, this); + } + } +}); +BI.ImageButton.EVENT_CHANGE = "ImageButton.EVENT_CHANGE"; +$.shortcut("bi.image_button", BI.ImageButton);(function ($) { + + /** + * 文字类型的按钮 + * @class BI.Button + * @extends BI.BasicButton + * + * @cfg {JSON} options 配置属性 + * @cfg {'common'/'success'/'warning'/'ignore'} [options.level='common'] 按钮类型,用不同颜色强调不同的场景 + */ + BI.Button = BI.inherit(BI.BasicButton, { + _const: { + minWidth: 90 + }, + + _defaultConfig: function () { + var conf = BI.Button.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + ' bi-button', + shadow: true, + isShadowShowingOnSelected: true, + readonly: true, + iconClass: "", + level: 'common', + textAlign: "center", + whiteSpace: "nowrap", + forceCenter: false, + textWidth: null, + textHeight: null, + hgap: 10, + vgap: 0, + tgap: 0, + bgap: 0, + lgap: 0, + rgap: 0 + }) + }, + + _init: function () { + BI.Button.superclass._init.apply(this, arguments); + var o = this.options, self = this; + if (BI.isNumber(o.height)) { + this.element.css({height: o.height - 2, lineHeight: (o.height - 2) + 'px'}); + } + if (BI.isKey(o.iconClass)) { + this.icon = BI.createWidget({ + type: "bi.icon", + width: 18 + }); + this.text = BI.createWidget({ + type: "bi.label", + text: o.text, + value: o.value + }); + BI.createWidget({ + type: "bi.horizontal_auto", + cls: "button-" + o.level + " " + o.iconClass, + element: this, + hgap: o.hgap, + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + lgap: o.lgap, + rgap: o.rgap, + items: [{ + type: "bi.horizontal", + items: [this.icon, this.text] + }] + }) + } else { + this.text = BI.createWidget({ + type: "bi.label", + cls: "button-" + o.level, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + forceCenter: o.forceCenter, + textWidth: o.textWidth, + textHeight: o.textHeight, + hgap: o.hgap, + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + lgap: o.lgap, + rgap: o.rgap, + element: this, + text: o.text, + value: o.value + }); + } + this.element.css({"min-width": this._const.minWidth - 2 + "px"}); + }, + + doClick: function () { + BI.Button.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.Button.EVENT_CHANGE, this); + } + }, + + setText: function (text) { + BI.Button.superclass.setText.apply(this, arguments); + this.text.setText(text); + }, + + setValue: function (text) { + BI.Button.superclass.setValue.apply(this, arguments); + if (!this.isReadOnly()) { + this.text.setValue(text); + } + }, + + setEnable: function (b) { + BI.Button.superclass.setEnable.apply(this, arguments); + this.text.setEnable(b); + this.icon && this.icon.setEnable(b); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + destroy: function () { + BI.Button.superclass.destroy.apply(this, arguments); + } + }); + $.shortcut('bi.button', BI.Button); + BI.Button.EVENT_CHANGE = "EVENT_CHANGE"; +})(jQuery);/** + * guy + * 可以点击的一行文字 + * @class BI.TextButton + * @extends BI.BasicButton + * 文字button + */ +BI.TextButton = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + var conf = BI.TextButton.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-button", + textAlign: "center", + whiteSpace: "nowrap", + forceCenter: false, + textWidth: null, + textHeight: null, + hgap: 0, + lgap: 0, + rgap: 0, + text: "", + py: "" + }) + }, + + _init: function () { + BI.TextButton.superclass._init.apply(this, arguments); + var o = this.options; + this.text = BI.createWidget({ + type: "bi.label", + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textWidth: o.textWidth, + textHeight: o.textHeight, + forceCenter: o.forceCenter, + width: o.width, + height: o.height, + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + text: o.text, + value: o.value, + py: o.py + }); + }, + + doClick: function () { + BI.TextButton.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.TextButton.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + setText: function (text) { + BI.TextButton.superclass.setText.apply(this, arguments); + text = BI.isArray(text) ? text.join(",") : text; + this.text.setText(text); + }, + + setStyle: function (style) { + this.text.setStyle(style); + }, + + setValue: function (text) { + BI.TextButton.superclass.setValue.apply(this, arguments); + if (!this.isReadOnly()) { + text = BI.isArray(text) ? text.join(",") : text; + this.text.setValue(text); + } + } +}); +BI.TextButton.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.text_button", BI.TextButton);/** + * 带有一个占位 + * + * Created by GUY on 2015/9/11. + * @class BI.BlankIconIconTextItem + * @extends BI.BasicButton + */ +BI.BlankIconIconTextItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.BlankIconIconTextItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", + logic: { + dynamic: false + }, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.BlankIconIconTextItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + var blank = BI.createWidget({ + type: "bi.layout", + width: o.blankWidth + }) + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }); + this.icon1 = BI.createWidget({ + type: "bi.icon_button", + cls: o.iconCls1, + forceNotSelected: true, + width: c.commonWidth + }); + this.icon2 = BI.createWidget({ + type: "bi.icon_button", + cls: o.iconCls2, + forceNotSelected: true, + width: c.commonWidth + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon1, this.icon2, this.text) + })))); + }, + + doClick: function () { + BI.BlankIconIconTextItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.BlankIconIconTextItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + setSelected: function (b) { + BI.BlankIconIconTextItem.superclass.setSelected.apply(this, arguments); + this.icon1.setSelected(b); + this.icon2.setSelected(b); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + } +}); +BI.BlankIconIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.blank_icon_icon_text_item", BI.BlankIconIconTextItem);/** + * guy + * 一个占位符和两个icon和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/15. + * @class BI.BlankIconTextIconItem + * @extends BI.BasicButton + */ +BI.BlankIconTextIconItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.BlankIconTextIconItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-blank-icon-text-icon-item", + logic: { + dynamic: false + }, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.BlankIconTextIconItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + + var icon1 = BI.createWidget({ + type: "bi.center_adapt", + cls: o.iconCls1, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }) + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: { + type: "bi.center_adapt", + cls: o.iconCls2, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }, + top: 0, + bottom: 0, + right: 0 + }] + }) + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", { + type: "bi.layout", + width: o.blankWidth + }, icon1, this.text, { + type: "bi.layout", + width: c.commonWidth + }) + })))); + }, + + doClick: function () { + BI.BlankIconTextIconItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.BlankIconTextIconItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + } +}); +BI.BlankIconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.blank_icon_text_icon_item", BI.BlankIconTextIconItem);/** + * 带有一个占位 + * + * Created by GUY on 2015/9/11. + * @class BI.BlankIconTextItem + * @extends BI.BasicButton + */ +BI.BlankIconTextItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.BlankIconTextItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", + logic: { + dynamic: false + }, + cls: "close-ha-font", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.BlankIconTextItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + var blank = BI.createWidget({ + type: "bi.layout", + width: o.blankWidth + }) + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + this.icon = BI.createWidget({ + type: "bi.center_adapt", + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon, this.text) + })))); + }, + + doClick: function () { + BI.BlankIconTextItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.BlankIconTextItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + } +}); +BI.BlankIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.blank_icon_text_item", BI.BlankIconTextItem);/** + * guy + * 两个icon和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/9. + * @class BI.IconTextIconItem + * @extends BI.BasicButton + */ +BI.IconTextIconItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.IconTextIconItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-icon-text-icon-item", + logic: { + dynamic: false + }, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.IconTextIconItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + + var icon1 = BI.createWidget({ + type: "bi.center_adapt", + cls: o.iconCls1, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }) + var blank = BI.createWidget({ + type: "bi.layout", + width: c.commonWidth + }) + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: { + type: "bi.center_adapt", + cls: o.iconCls2, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }, + top: 0, + bottom: 0, + right: 0 + }] + }) + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) + })))); + }, + + doClick: function () { + BI.IconTextIconItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.IconTextIconItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + } +}); +BI.IconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.icon_text_icon_item", BI.IconTextIconItem);/** + * guy + * + * Created by GUY on 2015/9/9. + * @class BI.IconTextItem + * @extends BI.BasicButton + */ +BI.IconTextItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.IconTextItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-icon-text-item", + direction: BI.Direction.Left, + logic: { + dynamic: false + }, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.IconTextItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }); + this.icon = BI.createWidget({ + type: "bi.center_adapt", + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.icon, this.text) + })))); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doClick: function () { + BI.IconTextItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.IconTextItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + } +}); +BI.IconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.icon_text_item", BI.IconTextItem);/** + * + * 图标的button + * + * Created by GUY on 2015/9/9. + * @class BI.TextIconItem + * @extends BI.BasicButton + */ +BI.TextIconItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.TextIconItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-icon-item", + logic: { + dynamic: false + }, + cls: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.TextIconItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }); + this.icon = BI.createWidget({ + type: "bi.center_adapt", + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) + })))); + }, + + doClick: function () { + BI.TextIconItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.TextIconItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + } +}); +BI.TextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.text_icon_item", BI.TextIconItem);/** + * guy + * 一个button和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/9. + * @class BI.TextItem + * @extends BI.BasicButton + */ +BI.TextItem = BI.inherit(BI.BasicButton, { + + _defaultConfig: function () { + var conf = BI.TextItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-item", + textAlign: "left", + whiteSpace: "nowrap", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.TextItem.superclass._init.apply(this, arguments); + var o = this.options; + this.text = BI.createWidget({ + type: "bi.label", + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, + height: o.height, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + py: o.py + }); + }, + + doClick: function () { + BI.TextItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.TextItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + } +}); +BI.TextItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.text_item", BI.TextItem);/** + * guy + * Created by GUY on 2015/9/9. + * @class BI.IconTextIconNode + * @extends BI.NodeButton + */ +BI.IconTextIconNode = BI.inherit(BI.NodeButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.IconTextIconNode.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-icon-text-icon-node", + logic: { + dynamic: false + }, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.IconTextIconNode.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + + var icon1 = BI.createWidget({ + type: "bi.center_adapt", + cls: o.iconCls1, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }) + var blank = BI.createWidget({ + type: "bi.layout", + width: c.commonWidth + }) + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: { + type: "bi.center_adapt", + cls: o.iconCls2, + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }, + top: 0, + bottom: 0, + right: 0 + }] + }) + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) + })))); + }, + + doClick: function () { + BI.IconTextIconNode.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.IconTextIconNode.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + } +}); +BI.IconTextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.icon_text_icon_node", BI.IconTextIconNode);/** + * guy + * Created by GUY on 2015/9/9. + * @class BI.IconTextNode + * @extends BI.NodeButton + */ +BI.IconTextNode = BI.inherit(BI.NodeButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.IconTextNode.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-icon-text-node", + logic: { + dynamic: false + }, + cls: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.IconTextNode.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + this.icon = BI.createWidget({ + type: "bi.center_adapt", + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }) + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", this.icon, this.text) + })))); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doClick: function () { + BI.IconTextNode.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.IconTextNode.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + } +}); +BI.IconTextNode.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.icon_text_node", BI.IconTextNode);/** + * Created by GUY on 2015/9/9. + * @class BI.TextIconNode + * @extends BI.NodeButton + */ +BI.TextIconNode = BI.inherit(BI.NodeButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.TextIconNode.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-icon-node", + logic: { + dynamic: false + }, + cls: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.TextIconNode.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }) + this.icon = BI.createWidget({ + type: "bi.center_adapt", + width: c.commonWidth, + items: [{ + el: { + type: "bi.icon", + width: o.iconWidth, + height: o.iconHeight + } + }] + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) + })))); + }, + + doClick: function () { + BI.TextIconNode.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.TextIconNode.EVENT_CHANGE, this.getValue(), this); + } + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + } +}); +BI.TextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.text_icon_node", BI.TextIconNode);/** + * guy + * + * Created by GUY on 2015/9/9. + * @class BI.TextNode + * @extends BI.NodeButton + */ +BI.TextNode = BI.inherit(BI.NodeButton, { + + _defaultConfig: function () { + var conf = BI.TextNode.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-node", + textAlign: "left", + whiteSpace: "nowrap", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.TextNode.superclass._init.apply(this, arguments); + var o = this.options; + this.text = BI.createWidget({ + type: "bi.label", + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, + height: o.height, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + py: o.py + }); + }, + + doClick: function () { + BI.TextNode.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.TextNode.EVENT_CHANGE, this.getValue(), this); + } + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + } +}); +BI.TextNode.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.text_node", BI.TextNode);/** + * + * Created by GUY on 2016/1/15. + * @class BI.CodeEditor + * @extends BI.Single + */ +BI.CodeEditor = BI.inherit(BI.Single, { + _defaultConfig: function () { + return $.extend(BI.CodeEditor.superclass._defaultConfig.apply(), { + baseCls: 'bi-code-editor', + value: '', + watermark: "" + }); + }, + _init: function () { + BI.CodeEditor.superclass._init.apply(this, arguments); + var o = this.options, self = this; + this.editor = CodeMirror(this.element[0], { + textWrapping: true, + lineWrapping: true, + lineNumbers: false + }); + this.editor.on("change", function (cm, change) { + BI.nextTick(function () { + self.fireEvent(BI.CodeEditor.EVENT_CHANGE) + }); + }); + + this.editor.on("focus", function () { + watermark.setVisible(false); + self.fireEvent(BI.CodeEditor.EVENT_FOCUS); + }); + + this.editor.on("blur", function () { + watermark.setVisible(BI.isEmptyString(self.getValue())); + self.fireEvent(BI.CodeEditor.EVENT_BLUR); + }); + + // this.editor.on("blur", function () { + // self.editor.execCommand("goLineEnd"); + // }); + + //水印 + var watermark = BI.createWidget({ + type: "bi.label", + text: o.watermark, + cls: "bi-water-mark", + whiteSpace: "nowrap", + textAlign: "left" + }); + watermark.element.bind( + "mousedown", function (e) { + self.insertString(""); + self.editor.focus(); + e.stopEvent(); + } + ); + watermark.element.bind("click", function (e) { + self.editor.focus(); + e.stopEvent(); + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: watermark, + top: 0, + left: 5 + }] + }); + + if (BI.isKey(o.value)) { + BI.nextTick(function () { + self.setValue(o.value); + }); + } + }, + + setEnable: function (b) { + BI.CodeEditor.superclass.setEnable.apply(this, arguments); + this.editor.setOption("readOnly", b === true ? false : "nocursor") + }, + + insertParam: function(param){ + var from = this.editor.getCursor(); + this.editor.replaceSelection(param); + var to = this.editor.getCursor(); + this.editor.markText(from, to, {className: 'param', atomic: true}); + this.editor.replaceSelection(" "); + this.editor.focus(); + }, + + insertString: function(str){ + this.editor.replaceSelection(str); + this.editor.focus(); + }, + + getValue: function () { + return this.editor.getValue("\n", function (line) { + var rawText = line.text, value = line.text, num = 0; + value.text = rawText; + _.forEach(line.markedSpans, function (i, ms) { + switch (i.marker.className) { + case "param": + var fieldNameLength = i.to - i.from; + value = value.substr(0, i.from + num) + "$\{" + value.substr(i.from + num, fieldNameLength) + "\}" + value.substr(i.to + num, value.length); + num += 3; break; } - BI.each(colgroupTds, function (i, colgroup) { - var width = colgroup.attr("width") | 0; - if (width !== sizes[i]) { - var w = self._calculateWidth(sizes[i]); - colgroup.attr("width", w).css("width", w); - BI.each(bodyTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(sizes, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].attr("width", wid).css("width", wid); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(bodyItems, function (j, items) { - if (items[i]) { - if (bodyTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(sizes, function (t, s) { - if (bodyTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += bodyTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } - } - }); - } - }) - }; - run(topleft); - run(topright); - run(bottomleft); - run(bottomright); + }); + return value; + }); + }, + + _analyzeContent: function (v) { + var regx = /\$[\{][^\}]*[\}]|(\s+)|\w*\w|\$\{[^\$\(\)\+\-\*\/)\$,]*\w\}|\$\{[^\$\(\)\+\-\*\/]*\w\}|\$\{[^\$\(\)\+\-\*\/]*[\u4e00-\u9fa5]\}|\w|(.)|\n/g; + return v.match(regx); + }, + + setValue: function (v) { + var self = this, result; + this.refresh(); + self.editor.setValue(""); + result = this._analyzeContent(v || ""); + BI.each(result, function (i, item) { + var fieldRegx = /\$[\{][^\}]*[\}]/; + var str = item.match(fieldRegx); + if (BI.isNotEmptyArray(str)) { + self.insertParam(str[0].substring(2, item.length - 1)); + } else { + self.insertString(item); + } + }) + }, + + refresh: function(){ + var self = this; + BI.nextTick(function () { + self.editor.refresh(); + }); + } +}); +BI.CodeEditor.EVENT_CHANGE = "EVENT_CHANGE"; +BI.CodeEditor.EVENT_BLUR = "EVENT_BLUR"; +BI.CodeEditor.EVENT_FOCUS = "EVENT_FOCUS"; +$.shortcut("bi.code_editor", BI.CodeEditor);/** + * Created by GUY on 2015/4/15. + * @class BI.Editor + * @extends BI.Single + */ +BI.Editor = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.Editor.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: "bi-editor", + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + tipType: "warning", + inputType: "text", + validationChecker: BI.emptyFn, + quitChecker: BI.emptyFn, + mouseOut: false, + allowBlank: false, + watermark: "", + errorText: "" + }) + }, + + _init: function () { + BI.Editor.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = this.addWidget(BI.createWidget({ + type: "bi.input", + element: "", + watermark: o.watermark, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + mouseOut: o.mouseOut, + allowBlank: o.allowBlank + })); + this.editor.element.css({ + "width": "100%", + "height": "100%", + "border": "none", + "outline": "none", + "padding": "0", + "margin": "0" + }); + if (BI.isKey(this.options.watermark)) { + this.watermark = BI.createWidget({ + type: "bi.label", + cls: "bi-water-mark", + text: this.options.watermark, + height: this.options.height, + forceCenter: true, + height: o.height - 2 * (o.vgap + o.tgap), + whiteSpace: "nowrap", + textAlign: "left" + }); + this.watermark.element.bind({ + mousedown: function (e) { + if (self.isEnabled()) { + self.editor.isEditing() || self.editor.focus(); + } else { + self.editor.isEditing() && self.editor.blur(); + } + e.stopEvent(); + } + }); + this.watermark.element.bind("click", function (e) { + if (self.isEnabled()) { + self.editor.isEditing() || self.editor.focus(); + } else { + self.editor.isEditing() && self.editor.blur(); + } + e.stopEvent(); + }); + this.watermark.element.css({ + position: "absolute", + left: "3px", + right: "3px", + top: "0px", + bottom: "0px" + }); + } + var items = [{ + el: { + type: "bi.default", + items: this.watermark ? [this.editor, this.watermark] : [this.editor] + }, + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + }]; + + BI.createWidget({ + type: "bi.absolute", + element: this, + items: items + }); + this.editor.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + this.editor.on(BI.Input.EVENT_FOCUS, function () { + self._checkError(); + self.element.addClass("bi-editor-focus"); + self.fireEvent(BI.Editor.EVENT_FOCUS, arguments); + }); + this.editor.on(BI.Input.EVENT_BLUR, function () { + self.setErrorVisible(false); + self.element.removeClass("bi-editor-focus"); + self.fireEvent(BI.Editor.EVENT_BLUR, arguments); + }); + this.editor.on(BI.Input.EVENT_CLICK, function () { + self.fireEvent(BI.Editor.EVENT_CLICK, arguments); + }); + this.editor.on(BI.Input.EVENT_CHANGE, function () { + self.fireEvent(BI.Editor.EVENT_CHANGE, arguments); + }); + this.editor.on(BI.Input.EVENT_KEY_DOWN, function (v) { + self.fireEvent(BI.Editor.EVENT_KEY_DOWN, arguments); + }); + this.editor.on(BI.Input.EVENT_QUICK_DOWN, function (v) { + self.watermark && self.watermark.invisible(); + }); + + this.editor.on(BI.Input.EVENT_VALID, function () { + self._checkWaterMark(); + self.setErrorVisible(false); + self.fireEvent(BI.Editor.EVENT_VALID, arguments); + }); + this.editor.on(BI.Input.EVENT_ERROR, function () { + self._checkWaterMark(); + self.fireEvent(BI.Editor.EVENT_ERROR, arguments); + self.setErrorVisible(self.isEditing()); + }); + this.editor.on(BI.Input.EVENT_RESTRICT, function () { + self._checkWaterMark(); + var tip = self.setErrorVisible(true); + tip && tip.element.fadeOut(100, function () { + tip.element.fadeIn(100); + }); + self.fireEvent(BI.Editor.EVENT_RESTRICT, arguments); + }); + this.editor.on(BI.Input.EVENT_EMPTY, function () { + self._checkWaterMark(); + self.fireEvent(BI.Editor.EVENT_EMPTY, arguments); + }); + this.editor.on(BI.Input.EVENT_ENTER, function () { + self.fireEvent(BI.Editor.EVENT_ENTER, arguments); + }); + this.editor.on(BI.Input.EVENT_SPACE, function () { + self.fireEvent(BI.Editor.EVENT_SPACE, arguments); + }); + this.editor.on(BI.Input.EVENT_BACKSPACE, function () { + self.fireEvent(BI.Editor.EVENT_BACKSPACE, arguments); + }); + this.editor.on(BI.Input.EVENT_REMOVE, function () { + self.fireEvent(BI.Editor.EVENT_REMOVE, arguments); + }); + this.editor.on(BI.Input.EVENT_START, function () { + self.fireEvent(BI.Editor.EVENT_START, arguments); + }); + this.editor.on(BI.Input.EVENT_PAUSE, function () { + self.fireEvent(BI.Editor.EVENT_PAUSE, arguments); + }); + this.editor.on(BI.Input.EVENT_STOP, function () { + self.fireEvent(BI.Editor.EVENT_STOP, arguments); + }); + this.editor.on(BI.Input.EVENT_CONFIRM, function () { + self.fireEvent(BI.Editor.EVENT_CONFIRM, arguments); + }); + this.element.click(function (e) { + e.stopPropagation(); + return false; + }); + if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { + this.setValue(this.options.value); + } else { + this._checkWaterMark(); + } + }, + + _checkToolTip: function () { + var o = this.options; + var errorText = o.errorText; + if (BI.isFunction(errorText)) { + errorText = errorText(this.editor.getValue()); + } + if (BI.isKey(errorText)) { + if (!this.isEnabled() || this.isValid() || (BI.Bubbles.has(this.getName()) && BI.Bubbles.get(this.getName()).isVisible())) { + this.setTitle(""); + } else { + this.setTitle(errorText); + } + } + }, + + _checkError: function () { + this.setErrorVisible(this.isEnabled() && !this.isValid()); + this._checkToolTip(); + }, + + _checkWaterMark: function () { + var o = this.options; + if (!this.disabledWarterMark && this.editor.getValue() === "" && BI.isKey(o.watermark)) { + this.watermark && this.watermark.visible(); + } else { + this.watermark && this.watermark.invisible(); + } + }, + + setErrorText: function (text) { + this.options.errorText = text; + }, + + getErrorText: function () { + return this.options.errorText; + }, + + setErrorVisible: function (b) { + var o = this.options; + var errorText = o.errorText; + if (BI.isFunction(errorText)) { + errorText = errorText(this.editor.getValue()); + } + if (!this.disabledError && BI.isKey(errorText)) { + BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this); + this._checkToolTip(); + return BI.Bubbles.get(this.getName()); + } + }, + + disableError: function () { + this.disabledError = true; + this._checkError(); + }, + + enableError: function () { + this.disabledError = false; + this._checkError(); + }, + + disableWarterMark: function () { + this.disabledWarterMark = true; + this._checkWaterMark(); + }, + + enableWarterMark: function () { + this.disabledWarterMark = false; + this._checkWaterMark(); + }, + + focus: function () { + this.element.addClass("text-editor-focus"); + this.editor.focus(); + }, + + blur: function () { + this.element.removeClass("text-editor-focus"); + this.editor.blur(); + }, + + selectAll: function () { + this.editor.selectAll(); + }, + + onKeyDown: function (k) { + this.editor.onKeyDown(k); + }, + + setValue: function (v) { + BI.Editor.superclass.setValue.apply(this, arguments); + this.editor.setValue(v); + this._checkError(); + this._checkWaterMark(); + }, + + getLastValidValue: function () { + return this.editor.getLastValidValue(); + }, + + resetLastValidValue: function () { + this.editor.resetLastValidValue(); + }, + + getValue: function () { + if (!this.isValid()) { + return BI.trim(this.editor.getLastValidValue()); + } + return BI.trim(this.editor.getValue()); + }, + + setValid: function (b) { + BI.Editor.superclass.setValid.apply(this, arguments); + this.editor.setValid(b); + }, + + isEditing: function () { + return this.editor.isEditing(); + }, + + isValid: function () { + return this.editor.isValid(); + }, + + setEnable: function (b) { + BI.Editor.superclass.setEnable.apply(this, arguments); + this.editor && this.editor.setEnable(b); + this.watermark && this.watermark.setEnable(b); + } +}); +BI.Editor.EVENT_CHANGE = "EVENT_CHANGE"; +BI.Editor.EVENT_FOCUS = "EVENT_FOCUS"; +BI.Editor.EVENT_BLUR = "EVENT_BLUR"; +BI.Editor.EVENT_CLICK = "EVENT_CLICK"; +BI.Editor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; +BI.Editor.EVENT_SPACE = "EVENT_SPACE"; +BI.Editor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; + +BI.Editor.EVENT_START = "EVENT_START"; +BI.Editor.EVENT_PAUSE = "EVENT_PAUSE"; +BI.Editor.EVENT_STOP = "EVENT_STOP"; +BI.Editor.EVENT_CONFIRM = "EVENT_CONFIRM"; +BI.Editor.EVENT_VALID = "EVENT_VALID"; +BI.Editor.EVENT_ERROR = "EVENT_ERROR"; +BI.Editor.EVENT_ENTER = "EVENT_ENTER"; +BI.Editor.EVENT_RESTRICT = "EVENT_RESTRICT"; +BI.Editor.EVENT_REMOVE = "EVENT_REMOVE"; +BI.Editor.EVENT_EMPTY = "EVENT_EMPTY"; + +$.shortcut("bi.editor", BI.Editor);/** + * 多文件 + * + * Created by GUY on 2016/4/13. + * @class BI.MultifileEditor + * @extends BI.Single + * @abstract + */ +BI.MultifileEditor = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.MultifileEditor.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-multifile-editor", + multiple: false, + maxSize: 1024 * 1024, + accept: "", + url: "" + }) + }, + + _init: function () { + var self = this, o = this.options; + BI.MultifileEditor.superclass._init.apply(this, arguments); + this.file = BI.createWidget({ + type: "bi.file", + cls: "multifile-editor", + width: "100%", + height: "100%", + name: o.name, + url: o.url, + multiple: o.multiple, + accept: o.accept, + maxSize: o.maxSize + }); + this.file.on(BI.File.EVENT_CHANGE, function () { + self.fireEvent(BI.MultifileEditor.EVENT_CHANGE, arguments); + }); + this.file.on(BI.File.EVENT_UPLOADSTART, function () { + self.fireEvent(BI.MultifileEditor.EVENT_UPLOADSTART, arguments); + }); + this.file.on(BI.File.EVENT_ERROR, function () { + self.fireEvent(BI.MultifileEditor.EVENT_ERROR, arguments); + }); + this.file.on(BI.File.EVENT_PROGRESS, function () { + self.fireEvent(BI.MultifileEditor.EVENT_PROGRESS, arguments); + }); + this.file.on(BI.File.EVENT_UPLOADED, function () { + self.fireEvent(BI.MultifileEditor.EVENT_UPLOADED, arguments); + }); + + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: { + type: "bi.adaptive", + scrollable: false, + items: [this.file] + }, + top: 0, + right: 0, + left: 0, + bottom: 0 + }] + }); + }, + + select: function () { + this.file.select(); + }, + + getValue: function () { + return this.file.getValue(); + }, + + upload: function () { + this.file.upload(); + }, + + reset: function () { + this.file.reset(); + }, + + setEnable: function (enable) { + BI.MultiFile.superclass.setEnable.apply(this, arguments); + this.file.setEnable(enable); + } +}); +BI.MultifileEditor.EVENT_CHANGE = "MultifileEditor.EVENT_CHANGE"; +BI.MultifileEditor.EVENT_UPLOADSTART = "MultifileEditor.EVENT_UPLOADSTART"; +BI.MultifileEditor.EVENT_ERROR = "MultifileEditor.EVENT_ERROR"; +BI.MultifileEditor.EVENT_PROGRESS = "MultifileEditor.EVENT_PROGRESS"; +BI.MultifileEditor.EVENT_UPLOADED = "MultifileEditor.EVENT_UPLOADED"; +$.shortcut("bi.multifile_editor", BI.MultifileEditor);/** + * + * Created by GUY on 2016/1/18. + * @class BI.TextAreaEditor + * @extends BI.Single + */ +BI.TextAreaEditor = BI.inherit(BI.Single, { + _defaultConfig: function () { + return $.extend(BI.TextAreaEditor.superclass._defaultConfig.apply(), { + baseCls: 'bi-textarea-editor', + value: '' + }); + }, + _init: function () { + BI.TextAreaEditor.superclass._init.apply(this, arguments); + var o = this.options, self = this; + this.content = BI.createWidget({ + type: "bi.layout", + tagName: "textarea", + width: "100%", + height: "100%", + cls: "textarea-editor-content display-block" + }); + this.content.element.css({"resize": "none"}); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: { + type: "bi.adaptive", + items: [this.content] + }, + left: 0, + right: 3, + top: 0, + bottom: 5 + }] + }); + + this.content.element.on("input propertychange", function (e) { + self._checkWaterMark(); + self.fireEvent(BI.TextAreaEditor.EVENT_CHANGE); + }); + + this.content.element.focus(function () { + if (self.isValid()) { + self._focus(); + self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); + } + $(document).bind("mousedown." + self.getName(), function (e) { + if (BI.DOM.isExist(self) && !self.element.__isMouseInBounds__(e)) { + $(document).unbind("mousedown." + self.getName()); + self.content.element.blur(); + } + }); + }); + this.content.element.blur(function () { + if (self.isValid()) { + self._blur(); + self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); + } + $(document).unbind("mousedown." + self.getName()); + }); + if (BI.isKey(o.value)) { + self.setValue(o.value); + } + if (BI.isNotNull(o.style)) { + self.setValue(o.style); + } + this._checkWaterMark(); + }, + + _checkWaterMark: function () { + var self = this, o = this.options; + var val = this.getValue(); + if (BI.isNotEmptyString(val)) { + this.watermark && this.watermark.destroy(); + this.watermark = null; + } else { + if (BI.isNotEmptyString(o.watermark)) { + if (!this.watermark) { + this.watermark = BI.createWidget({ + type: "bi.text_button", + cls: "bi-water-mark", + textAlign: "left", + height: 30, + text: o.watermark, + invalid: o.invalid, + disabled: o.disabled + }); + this.watermark.on(BI.TextButton.EVENT_CHANGE, function () { + self.focus(); + }); + BI.createWidget({ + type: 'bi.absolute', + element: this, + items: [{ + el: this.watermark, + left: 0, + top: 0, + right: 0 + }] + }) + } else { + this.watermark.setText(o.watermark); + this.watermark.setValid(!o.invalid); + this.watermark.setEnable(!o.disabled); + } + } + } + }, + + _focus: function () { + this.content.element.addClass("textarea-editor-focus"); + this._checkWaterMark(); + }, + + _blur: function () { + this.content.element.removeClass("textarea-editor-focus"); + this._checkWaterMark(); + }, + + focus: function () { + this._focus(); + this.content.element.focus(); + }, + + blur: function () { + this._blur(); + this.content.element.blur(); + }, + + getValue: function () { + return this.content.element.val(); + }, + + setValue: function (value) { + this.content.element.val(value); + }, + + setStyle: function (style) { + this.style = style; + this.element.css(style); + this.content.element.css(style) + }, + + getStyle: function () { + return this.style; + }, + + setValid: function (b) { + BI.TextAreaEditor.superclass.setValid.apply(this, arguments); + this.content.setValid(b); + this.watermark && this.watermark.setValid(b); + }, + + setEnable: function (b) { + BI.TextAreaEditor.superclass.setEnable.apply(this, arguments); + this.content.setEnable(b); + this.watermark && this.watermark.setEnable(b); + } +}); +BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; +BI.TextAreaEditor.EVENT_BLUR = "EVENT_BLUR"; +BI.TextAreaEditor.EVENT_FOCUS = "EVENT_FOCUS"; +$.shortcut("bi.textarea_editor", BI.TextAreaEditor);/** + * guy 图标 + * @class BI.Icon + * @extends BI.Single + */ +BI.Icon = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.Icon.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + tagName: "i", + baseCls: (conf.baseCls || "") + " x-icon b-font horizon-center display-block" + }) + }, + _init: function () { + BI.Icon.superclass._init.apply(this, arguments); + } +}); +$.shortcut("bi.icon", BI.Icon);/** + * @class BI.Iframe + * @extends BI.Single + * @abstract + * Created by GameJian on 2016/3/2. + */ +BI.Iframe = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.Iframe.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-iframe", + src: "", + width: "100%", + height: "100%" + }) + }, + + _init: function () { + var o = this.options; + this.options.element = $("')); + } catch (e) { + var form = document.createElement('form'), + iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); + form.setAttribute("enctype", "multipart/form-data"); + iframe.setAttribute("name", iframe.id = target); + iframe.setAttribute("src", url); + } + iframe.style.position = "absolute"; + iframe.style.left = iframe.style.top = "-10000px"; + iframe.onload = onload; + iframe.onerror = function (event) { + if (isFunction(handler.onerror)) { + handler.onerror(rpe, event || window.event); + } + }; + iframe.onreadystatechange = function () { + if (/loaded|complete/i.test(iframe.readyState)) { + onload(); + + //wei : todo,将附件信息放到handler.attach + } + else if (isFunction(handler.onloadprogress)) { + if (rpe.loaded < rpe.total) { + ++rpe.loaded; + } + handler.onloadprogress(rpe, { + readyState: { + loading: 2, + interactive: 3, + loaded: 4, + complete: 4 + }[iframe.readyState] || 1 + }); + } + }; + form.setAttribute("action", handler.url); + form.setAttribute("target", iframe.id); + form.setAttribute("method", "post"); + form.appendChild(handler.file); + form.style.display = "none"; + if (isFunction(handler.onloadstart)) { + handler.onloadstart(rpe, {}); + } + with (document.body || document.documentElement) { + appendChild(iframe); + appendChild(form); + form.submit(); + } + ; + return handler; + }; + } + xhr = null; + return sendFile; + })(Object.prototype.toString); + + var sendFiles = function (handler, maxSize, width, height) { + + var length = handler.files.length, + i = 0, + onload = handler.onload, + onloadstart = handler.onloadstart; + handler.current = 0; + handler.total = 0; + handler.sent = 0; + while (handler.current < length) { + handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); + handler.current++; + } + handler.current = 0; + if (length && handler.files[0].fileSize !== -1) { + handler.file = handler.files[handler.current]; + + sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { + handler.onloadstart = null; + handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); + if (++handler.current < length) { + handler.file = handler.files[handler.current]; + sendFile(handler, maxSize, width, height).onload = arguments.callee; + } else if (onload) { + handler.onloadstart = onloadstart; + handler.onload = onload; + handler.onload(rpe, xhr); + } + }; + } else if (length) { + handler.total = length * 100; + handler.file = handler.files[handler.current]; + sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { + var callee = arguments.callee; + handler.onloadstart = null; + handler.sent += 100; + if (++handler.current < length) { + if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { + handler.iframe.parentNode.removeChild(handler.iframe); + handler.iframe = null; + } + setTimeout(function () { + handler.file = handler.files[handler.current]; + sendFile(handler, maxSize, width, height).onload = callee; + }, 15); + } else if (onload) { + setTimeout(function () { + handler.iframe.parentNode.removeChild(handler.iframe); + handler.iframe = null; + handler.onloadstart = onloadstart; + handler.onload = onload; + handler.onload(rpe, xhr); + }, 15); + } + }; + } + return handler; + }; + + BI.File = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.File.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-file display-block", + element: "", + name: "", + url: "", + multiple: true, + accept: "", /**'*.jpg; *.zip'**/ + maxSize: 1024 * 1024 + }) + }, + + _init: function () { + var self = this, o = this.options; + BI.File.superclass._init.apply(this, arguments); + if (o.multiple === true) { + this.element.attr("multiple", "multiple"); + } + this.element.attr("name", o.name || this.getName()); + + BI.nextTick(function () { + // create the noswfupload.wrap Object + // wrap.maxSize 文件大小限制 + // wrap.maxlength 文件个数限制 + var _wrap = self.wrap = self._wrap(self.element[0], o.maxSize); + // fileType could contain whatever text but filter checks *.{extension} + // if present + + // handlers + + _wrap.onloadstart = function (rpe, xhr) { + //BI.Msg.toast("loadstart"); + self.fireEvent(BI.File.EVENT_UPLOADSTART); + }; + + _wrap.onprogress = function (rpe, xhr) { + //BI.Msg.toast("onprogress"); + // percent for each bar + + // fileSize is -1 only if browser does not support file info access + // this if splits recent browsers from others + if (this.file.fileSize !== -1) { + // simulation property indicates when the progress event is fake + if (rpe.simulation) { + + } else { + + } + } else { + // if fileSIze is -1 browser is using an iframe because it does + // not support + // files sent via Ajax (XMLHttpRequest) + // We can still show some information + } + self.fireEvent(BI.File.EVENT_PROGRESS, { + file: this.file, + total: rpe.total, + loaded: rpe.loaded, + simulation: rpe.simulation + }); + }; + + // generated if there is something wrong during upload + _wrap.onerror = function () { + // just inform the user something was wrong + self.fireEvent(BI.File.EVENT_ERROR); + }; + + // generated when every file has been sent (one or more, it does not + // matter) + _wrap.onload = function (rpe, xhr) { + var self_ = this; + // just show everything is fine ... + // ... and after a second reset the component + setTimeout(function () { + self_.clean(); // remove files from list + self_.hide(); // hide progress bars and enable input file + + //BI.Msg.toast("onload"); + self.fireEvent(BI.File.EVENT_UPLOADED); + // enable again the submit button/element + }, 1000); + }; + _wrap.url = o.url ? o.url : FR.servletURL + + '?op=fr_attach&cmd=ah_upload'; + _wrap.fileType = o.accept; //文件类型限制 + _wrap.attach_array = []; + _wrap.attach_names = []; + _wrap.attachNum = 0; + }); + }, + + _events: function (wrap) { + var self = this; + event.add(wrap.dom.input, "change", function () { + event.del(wrap.dom.input, "change", arguments.callee); + for (var input = wrap.dom.input.cloneNode(true), i = 0, files = F(wrap.dom.input); i < files.length; i++) { + var item = files.item(i); + var tempFile = item.value || item.name; + var value = item.fileName || (item.fileName = tempFile.split("\\").pop()), + ext = -1 !== value.indexOf(".") ? value.split(".").pop().toLowerCase() : "unknown", + size = item.fileSize || item.size; + if (wrap.fileType && -1 === wrap.fileType.indexOf("*." + ext)) { + //文件类型不支持 + BI.Msg.toast(BI.i18nText("BI-Upload_File_Type_Error")); + self.fireEvent(BI.File.EVENT_ERROR, { + errorType: 0, + file: item + }); + } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { + //文件大小不支持 + BI.Msg.toast(BI.i18nText("BI-Upload_File_Size_Error")); + self.fireEvent(BI.File.EVENT_ERROR, { + errorType: 1, + file: item + }); + } else { + wrap.files.unshift(item); + //BI.Msg.toast(value); + self.fireEvent(BI.File.EVENT_CHANGE, { + file: item + }); + } + } + input.value = ""; + wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); + wrap.dom.input = input; + event.add(wrap.dom.input, "change", arguments.callee); + }); + return wrap; + }, + + _wrap: function () { + var self = this, o = this.options; + // be sure input accept multiple files + var input = this.element[0]; + if (o.multiple === true) { + this.element.attr("multiple", "multiple"); + } + input.value = ""; + + // wrap Object + return this._events({ + + // DOM namespace + dom: { + input: input, // input file + disabled: false // internal use, checks input file state + }, + name: input.name, // name to send for each file ($_FILES[{name}] in the server) + // maxSize is the maximum amount of bytes for each file + maxSize: o.maxSize ? o.maxSize >> 0 : -1, + files: [], // file list + + // remove every file from the noswfupload component + clean: function () { + this.files = []; + }, + + // upload one file a time (which make progress possible rather than all files in one shot) + // the handler is an object injected into the wrap one, could be the wrap itself or + // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} + upload: function (handler) { + if (handler) { + for (var key in handler) { + this[key] = handler[key]; + } + } + sendFiles(this, this.maxSize); + return this; + }, + + // hide progress bar (total + current) and enable files selection + hide: function () { + if (this.dom.disabled) { + this.dom.disabled = false; + this.dom.input.removeAttribute("disabled"); + } + }, + + // show progress bar and disable file selection (used during upload) + // total and current are pixels used to style bars + // totalProp and currentProp are properties to change, "height" by default + show: function (total, current, totalProp, currentProp) { + if (!this.dom.disabled) { + this.dom.disabled = true; + this.dom.input.setAttribute("disabled", "disabled"); + } + } + }); + }, + + select: function () { + $(this.wrap.dom.input).click(); + }, + + upload: function (handler) { + this.wrap.upload(handler); + }, + + getValue: function () { + return this.wrap.attach_array; + }, + + reset: function () { + this.wrap.attach_array = []; + this.wrap.attach_names = []; + this.wrap.attachNum = 0; + }, + + setEnable: function (enable) { + BI.MultiFile.superclass.setEnable.apply(this, arguments); + if (enable === true) { + this.element.attr("disabled", "disabled"); + } else { + this.element.removeAttr("disabled"); + } + } + }); + BI.File.EVENT_CHANGE = "BI.File.EVENT_CHANGE"; + BI.File.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; + BI.File.EVENT_ERROR = "EVENT_ERROR"; + BI.File.EVENT_PROGRESS = "EVENT_PROGRESS"; + BI.File.EVENT_UPLOADED = "EVENT_UPLOADED"; + $.shortcut("bi.file", BI.File); +})();/** + * guy + * @class BI.Input 一个button和一行数 组成的一行listitem + * @extends BI.Single + * @type {*|void|Object} + */ +BI.Input = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-input display-block", + element: "", + validationChecker: BI.emptyFn, + quitChecker: BI.emptyFn,//按确定键能否退出编辑 + mouseOut: false, + allowBlank: false + }) + }, + + _init: function () { + BI.Input.superclass._init.apply(this, arguments); + var self = this; + var ctrlKey = false; + var inputEventValid = false; + var _keydown = BI.debounce(function (keyCode) { + self.onKeyDown(keyCode, ctrlKey); + self._keydown_ = false; + }, 300); + var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, true); + this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, true); + this.element + .keydown(function (e) { + inputEventValid = false; + ctrlKey = e.ctrlKey; + self.fireEvent(BI.Input.EVENT_QUICK_DOWN); + }) + .keyup(function (e) { + if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { + self._keydown_ = true; + _keydown(e.keyCode); + } + }) + .on("input propertychange", function (e) { + inputEventValid = true; + self._keydown_ = true; + _keydown(e.keyCode); + }) + .click(function (e) { + e.stopPropagation(); + _clk(); + }) + .mousedown(function (e) { + self.element.val(self.element.val()); + }) + .focusout(function (e) { + self._blurDebounce(); + }); + }, + + _focus: function () { + this.element.addClass("bi-input-focus"); + this._checkValidationOnValueChange(); + this._isEditing = true; + if (this.getValue() == "") { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_EMPTY); + } + this.fireEvent(BI.Input.EVENT_FOCUS); + }, + + _blur: function () { + var self = this; + if (self._keydown_ === true) { + BI.delay(blur, 300); + } else { + blur(); + } + function blur() { + if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { + self.element.val(self._lastValidValue ? self._lastValidValue : ""); + self._checkValidationOnValueChange(); + self._defaultState(); + } + self.element.removeClass("bi-input-focus"); + self._isEditing = false; + self._start = false; + if (self.isValid()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); + self.fireEvent(BI.Input.EVENT_CONFIRM); + } + self.fireEvent(BI.Input.EVENT_BLUR); + } + }, + + _click: function () { + if (this._isEditing !== true) { + this._focus(); + this.selectAll(); + this.fireEvent(BI.Input.EVENT_CLICK); + } + }, + + onClick: function () { + this._click(); + }, + + onKeyDown: function (keyCode, ctrlKey) { + if (!this.isValid() || BI.trim(this._lastValidValue) !== BI.trim(this.getValue())) { + this._checkValidationOnValueChange(); + } + if (this.isValid() && BI.trim(this.getValue()) !== "") { + if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") + || (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { + this._start = true; + this._pause = false; + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_START); + } + } + if (ctrlKey === true && keyCode === 86) {//ctrlKey+V + this._valueChange(); + } else { + if (keyCode == BI.KeyCode.ENTER) { + if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { + this.blur(); + this.fireEvent(BI.Input.EVENT_ENTER); + } else { + this.fireEvent(BI.Input.EVENT_RESTRICT); + } + } + if (keyCode == BI.KeyCode.SPACE) { + this.fireEvent(BI.Input.EVENT_SPACE); + } + if (keyCode == BI.KeyCode.BACKSPACE && this._lastValue == "") { + this.fireEvent(BI.Input.EVENT_REMOVE); + } + if (keyCode == BI.KeyCode.BACKSPACE || keyCode == BI.KeyCode.DELETE) { + this.fireEvent(BI.Input.EVENT_BACKSPACE); + } + } + this.fireEvent(BI.Input.EVENT_KEY_DOWN); + + if (BI.isEndWithBlank(this.getValue())) { + this._pause = true; + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); + this.fireEvent(BI.Input.EVENT_PAUSE); + this._defaultState(); + } else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && + BI.trim(this.getValue()) === "" && (this._lastValue !== null && BI.trim(this._lastValue) !== "")) { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_STOP); + this._valueChange(); + } else { + this._valueChange(); + } + }, + + //初始状态 + _defaultState: function () { + if (this.getValue() == "") { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_EMPTY); + } + this._lastValue = this.getValue(); + this._lastSubmitValue = null; + }, + + _valueChange: function () { + if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_CHANGE); + this._lastSubmitValue = BI.trim(this.getValue()); + } + if (this.getValue() == "") { + this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); + this.fireEvent(BI.Input.EVENT_EMPTY); + } + this._lastValue = this.getValue(); + }, + + _checkValidationOnValueChange: function () { + var o = this.options; + var v = this.getValue(); + this.setValid( + (o.allowBlank === true && BI.trim(v) == "") || + (BI.isNotEmptyString(BI.trim(v)) + && (v === this._lastValidValue || + o.validationChecker.apply(this, [BI.trim(v)]) !== false)) + ); + }, + + focus: function () { + if (!this.element.is(":visible")) { + throw new Error("input输入框在不可见下不能focus"); + } + if (!this._isEditing === true) { + this.element.focus(); + this._focus(); + this.selectAll(); + } + }, + + blur: function () { + if (!this.element.is(":visible")) { + throw new Error("input输入框在不可见下不能blur"); + } + if (this._isEditing === true) { + this.element.blur(); + this._blurDebounce(); + } + }, + + selectAll: function () { + if (!this.element.is(":visible")) { + throw new Error("input输入框在不可见下不能select"); + } + this.element.select(); + this._isEditing = true; + }, + + setValue: function (textValue) { + this.element.val(textValue); + BI.nextTick(BI.bind(function () { + this._checkValidationOnValueChange(); + this._defaultState(); + if (this.isValid()) { + this._lastSubmitValue = this.getValue(); + } + }, this)); + }, + + getValue: function () { + return this.element.val() || ""; + }, + + isEditing: function () { + return this._isEditing; + }, + + getLastValidValue: function () { + return this._lastValidValue; + }, + + setValid: function () { + BI.Input.superclass.setValid.apply(this, arguments); + if (this.isValid()) { + this._lastValidValue = this.getValue(); + this.element.removeClass("bi-input-error"); + this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); + } else { + if (this._lastValidValue === this.getValue()) { + this._lastValidValue = null; + } + this.element.addClass("bi-input-error"); + this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); + } + }, + + setEnable: function (b) { + BI.Input.superclass.setEnable.apply(this, [b]); + this.element[0].disabled = !b; + } +}); +BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; +BI.Input.EVENT_CLICK = "EVENT_CLICK"; +BI.Input.EVENT_BLUR = "EVENT_BLUR"; +BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; +BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; +BI.Input.EVENT_SPACE = "EVENT_SPACE"; +BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; + +BI.Input.EVENT_START = "EVENT_START"; +BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; +BI.Input.EVENT_STOP = "EVENT_STOP"; +BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; +BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; +BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; +BI.Input.EVENT_VALID = "EVENT_VALID"; +BI.Input.EVENT_ERROR = "EVENT_ERROR"; +BI.Input.EVENT_ENTER = "EVENT_ENTER"; +BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; +$.shortcut("bi.input", BI.Input);/** + * guy + * @extends BI.Single + * @type {*|void|Object} + */ +BI.Radio = BI.inherit(BI.IconButton, { + _defaultConfig: function() { + var conf = BI.Radio.superclass._defaultConfig.apply(this,arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-radio radio-icon", + selected: false, + handler: BI.emptyFn, + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16 + }) + }, + + _init : function() { + BI.Radio.superclass._init.apply(this, arguments); + }, + + doClick: function(){ + BI.Radio.superclass.doClick.apply(this, arguments); + if(this.isValid()){ + this.fireEvent(BI.Radio.EVENT_CHANGE); + } + } +}); +BI.Radio.EVENT_CHANGE = "Radio.EVENT_CHANGE"; + +$.shortcut("bi.radio", BI.Radio);/** + * Created by GUY on 2015/6/26. + */ + +BI.Label = BI.inherit(BI.Single, { + _defaultConfig: function () { + var conf = BI.Label.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-label", + textAlign: "center", + whiteSpace: "nowrap", //normal or nowrap + forceCenter: false, //是否无论如何都要居中, 不考虑超出边界的情况, 在未知宽度和高度时有效 + textWidth: null, + textHeight: null, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + text: "", + py: "", + keyword: "" + }) + }, + + _createJson: function () { + var o = this.options; + return { + type: "bi.text", + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + lineHeight: o.textHeight, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword + }; + }, + + _init: function () { + BI.Label.superclass._init.apply(this, arguments); + + if (this.options.textAlign === "center") { + this._createCenterEl(); + } else { + this._createNotCenterEl(); + } + }, + + _createCenterEl: function () { + var o = this.options; + var json = this._createJson(); + if (BI.isNumber(o.width) && o.width > 0) { + if (BI.isNumber(o.textWidth) && o.textWidth > 0) { + if (BI.isNumber(o.height) && o.height > 0) { + var gap = (o.width - o.textWidth) / 2; + BI.createWidget({ + type: "bi.adaptive", + height: o.height, + scrollable: o.whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)), + left: gap + o.hgap + o.lgap, + right: gap + o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + } + ] + }); + this.element.css({"line-height": o.height + "px"}); + return; + } + json.width = o.textWidth; + BI.createWidget({ + type: "bi.center_adapt", + scrollable: o.whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)) + } + ] + }); + return; + } + if (o.whiteSpace == "normal") { + this.text = BI.createWidget(json); + BI.createWidget({ + type: "bi.center_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [this.text] + }); + return; + } + if (BI.isNumber(o.height) && o.height > 0) { + this.element.css({ + "line-height": o.height + "px" + }); + BI.createWidget({ + type: "bi.absolute", + scrollable: o.whiteSpace === "normal", + element: this, + items: [{ + el: (this.text = BI.createWidget(json)), + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + }] + }); + return; + } + json.width = o.width - 2 * o.hgap; + BI.createWidget({ + type: "bi.center_adapt", + scrollable: o.whiteSpace === "normal", + element: this, + items: [{ + el: (this.text = BI.createWidget(json)) + }] + }); + return; + } + if (BI.isNumber(o.textWidth) && o.textWidth > 0) { + json.width = o.textWidth; + BI.createWidget({ + type: "bi.center_adapt", + scrollable: o.whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)) + } + ] + }); + return; + } + if (o.whiteSpace == "normal") { + this.text = BI.createWidget(json); + this.text = BI.createWidget({ + type: "bi.center_adapt", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + scrollable: o.whiteSpace === "normal", + element: this, + items: [this.text] + }); + return; + } + if (BI.isNumber(o.height) && o.height > 0) { + if (BI.isNumber(o.textHeight) && o.textHeight > 0) { + this.element.css({ + "line-height": o.height + "px" + }); + BI.createWidget({ + type: "bi.adaptive", + height: o.height, + scrollable: o.whiteSpace === "normal", + element: this, + items: [{ + el: (this.text = BI.createWidget(json)), + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + }] + }); + return; + } + BI.extend(json, { + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap + }); + this.element.css({ + "line-height": o.height + "px" + }); + this.text = BI.createWidget(BI.extend(json, { + element: this + })); + BI.createWidget({ + type: "bi.layout", + element: this.text, + scrollable: o.whiteSpace === "normal" + }); + return; + } + BI.extend(json, { + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap + }); + if (o.forceCenter) { + this.text = BI.createWidget(json); + BI.createWidget({ + type: "bi.center_adapt", + element: this, + items: [this.text] + }); + return; + } + this.text = BI.createWidget(BI.extend(json, { + element: this + })); + BI.createWidget({ + type: "bi.layout", + element: this.text, + scrollable: o.whiteSpace === "normal" + }) + }, + + _createNotCenterEl: function () { + var o = this.options; + var json = this._createJson(); + if (BI.isNumber(o.width) && o.width > 0) { + if (BI.isNumber(o.textWidth) && o.textWidth > 0) { + if (BI.isNumber(o.height) && o.height > 0) { + BI.createWidget({ + type: "bi.adaptive", + height: o.height, + scrollable: o.whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)), + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + } + ] + }); + this.element.css({"line-height": o.height + "px"}); + return; + } + json.width = o.textWidth; + BI.createWidget({ + type: "bi.vertical_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)) + } + ] + }); + return; + } + if (o.whiteSpace == "normal") { + this.text = BI.createWidget(json); + BI.createWidget({ + type: "bi.vertical_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [this.text] + }); + return; + } + if (BI.isNumber(o.height) && o.height > 0) { + this.element.css({ + "line-height": o.height + "px" + }); + BI.createWidget({ + type: "bi.absolute", + scrollable: o.whiteSpace === "normal", + element: this, + items: [{ + el: (this.text = BI.createWidget(json)), + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + }] + }); + return; + } + json.width = o.width - 2 * o.hgap - o.lgap - o.rgap; + BI.createWidget({ + type: "bi.vertical_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [{ + el: (this.text = BI.createWidget(json)) + }] + }); + return; + } + if (BI.isNumber(o.textWidth) && o.textWidth > 0) { + json.width = o.textWidth; + BI.createWidget({ + type: "bi.vertical_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [ + { + el: (this.text = BI.createWidget(json)) + } + ] + }); + return; + } + if (o.whiteSpace == "normal") { + this.text = BI.createWidget(json) + this.text = BI.createWidget({ + type: "bi.vertical_adapt", + scrollable: o.whiteSpace === "normal", + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + element: this, + items: [this.text] + }); + return; + } + if (BI.isNumber(o.height) && o.height > 0) { + if (BI.isNumber(o.textHeight) && o.textHeight > 0) { + this.element.css({ + "line-height": o.height + "px" + }); + BI.createWidget({ + type: "bi.adaptive", + height: o.height, + scrollable: o.whiteSpace === "normal", + element: this, + items: [{ + el: (this.text = BI.createWidget(json)), + left: o.hgap + o.lgap, + right: o.hgap + o.rgap, + top: o.vgap + o.tgap, + bottom: o.vgap + o.bgap + }] + }); + return; + } + BI.extend(json, { + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap + }); + this.element.css({ + "line-height": o.height + "px" + }); + this.text = BI.createWidget(BI.extend(json, { + element: this + })); + BI.createWidget({ + type: "bi.layout", + element: this.text, + scrollable: o.whiteSpace === "normal" + }); + return; + } + BI.extend(json, { + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap + }); + if (o.forceCenter) { + this.text = BI.createWidget(json); + BI.createWidget({ + type: "bi.vertical_adapt", + element: this, + items: [this.text] + }); + return; + } + this.text = BI.createWidget(BI.extend(json, { + element: this + })); + BI.createWidget({ + type: "bi.layout", + element: this.text, + scrollable: o.whiteSpace === "normal" + }) + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + }, + + setText: function (v) { + this.options.text = v; + this.text.setText(v); + }, + + getText: function () { + return this.options.text; + }, + + setStyle: function (css) { + this.text.setStyle(css) + }, + + setValue: function (v) { + BI.Label.superclass.setValue.apply(this, arguments); + if (!this.isReadOnly()) { + this.text.setValue(v); + } + }, + + populate: function () { + BI.Label.superclass.populate.apply(this, arguments); + } +}); + +$.shortcut("bi.label", BI.Label);/** + * guy a元素 + * @class BI.Link + * @extends BI.Text + */ +BI.Link = BI.inherit(BI.Label, { + _defaultConfig: function() { + var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-link", + href: "", + target: "_blank" + }) + }, + + _createJson: function(){ + var o = this.options; + return { + type:"bi.a", + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + lineHeight: o.textHeight, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + href: o.href, + target: o.target + }; + }, + + _init : function() { + BI.Link.superclass._init.apply(this, arguments); + } +}); + +$.shortcut("bi.link", BI.Link);/** + * guy + * tip提示 + * zIndex在10亿级别 + * @class BI.Tip + * @extends BI.Single + * @abstract + */ +BI.Tip = BI.inherit(BI.Single, { + _defaultConfig: function() { + var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-tip", + zIndex: BI.zIndex_tip + }) + }, + + _init : function() { + BI.Tip.superclass._init.apply(this, arguments); + this.element.css({"zIndex": this.options.zIndex}); + } +});/** + * 下拉 + * @class BI.Trigger + * @extends BI.Single + * @abstract + */ +BI.Trigger = BI.inherit(BI.Single, { + _defaultConfig: function() { + var conf = BI.Trigger.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-trigger cursor-pointer", + height: 30 + }) + }, + + _init : function() { + BI.Trigger.superclass._init.apply(this, arguments); + }, + + setKey: function(){ + + }, + + getKey: function(){ + + } +});/** + * svg绘图 + * + * Created by GUY on 2015/12/3. + * @class BI.Svg + * @extends BI.Widget + */ +BI.Svg = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.Svg.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-svg" + }) + }, + + _init: function () { + BI.Svg.superclass._init.apply(this, arguments); + this.paper = Raphael(this.element[0]); + + $(this.paper.canvas).width("100%").height("100%").css({"left": "0", "top": "0"}).appendTo(this.element); + + this.top = this.paper.top; + this.bottom = this.paper.bottom; + this.customAttributes = this.paper.customAttributes; + this.ca = this.paper.ca; + this.raphael = this.paper.raphael; + }, + + add: function () { + return this.paper.add.apply(this.paper, arguments); + }, + + path: function () { + return this.paper.path.apply(this.paper, arguments); + }, + + image: function () { + return this.paper.image.apply(this.paper, arguments); + }, + + rect: function () { + return this.paper.rect.apply(this.paper, arguments); + }, + + circle: function () { + return this.paper.circle.apply(this.paper, arguments); + }, + + ellipse: function () { + return this.paper.ellipse.apply(this.paper, arguments); + }, + + text: function () { + return this.paper.text.apply(this.paper, arguments); + }, + + print: function () { + return this.paper.print.apply(this.paper, arguments); + }, + + + setStart: function () { + return this.paper.setStart.apply(this.paper, arguments); + }, + + setFinish: function () { + return this.paper.setFinish.apply(this.paper, arguments); + }, + + setSize: function () { + return this.paper.setSize.apply(this.paper, arguments); + }, + + setViewBox: function () { + return this.paper.setViewBox.apply(this.paper, arguments); + }, + + + getById: function () { + return this.paper.getById.apply(this.paper, arguments); + }, + + getElementByPoint: function () { + return this.paper.getElementByPoint.apply(this.paper, arguments); + }, + + getElementsByPoint: function () { + return this.paper.getElementsByPoint.apply(this.paper, arguments); + }, + + getFont: function () { + return this.paper.getFont.apply(this.paper, arguments); + }, + + + set: function () { + return this.paper.set.apply(this.paper, arguments); + }, + remove: function () { + return this.paper.remove.apply(this.paper, arguments); + }, + clear: function () { + return this.paper.clear.apply(this.paper, arguments); + } +}); +$.shortcut("bi.svg", BI.Svg);/** + * + * 表格 + * + * Created by GUY on 2015/9/22. + * @class BI.TableCell + * @extends BI.Single + */ +BI.TableCell = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.TableCell.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-table-cell", + textAlign: "left", + text: "" + }) + }, + + _init: function () { + BI.TableCell.superclass._init.apply(this, arguments); + BI.createWidget({ + type: "bi.label", + element: this, + whiteSpace: "nowrap", + textAlign: this.options.textAlign, + height: this.options.height, + text: this.options.text, + value: this.options.value, + lgap: 5 + }) + } +}); + +$.shortcut("bi.table_cell", BI.TableCell);/** + * + * 表格单元格 + * + * Created by GUY on 2016/1/12. + * @class BI.CollectionTableCell + * @extends BI.Widget + */ +BI.CollectionTableCell = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.CollectionTableCell.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-collection-table-cell", + width: 0, + height: 0, + _left: 0, + _top: 0, + cell: {} + }) + }, + + _init: function () { + BI.CollectionTableCell.superclass._init.apply(this, arguments); + var o = this.options; + this.cell = BI.createWidget(BI.extend({ + type: "bi.label" + }, o.cell, { + cls: (o.cell.cls || "") + "collection-table-cell-wrapper", + width: o.width - (o._left === 0 ? 1 : 0) - 1, + height: o.height - (o._top === 0 ? 1 : 0) - 1 + })); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.cell, + left: 0, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + setWidth: function (width) { + BI.CollectionTableCell.superclass.setWidth.apply(this, arguments); + var o = this.options; + this.cell.setWidth(o.width - (o._left === 0 ? 1 : 0) - 1); + }, + + setHeight: function (height) { + BI.CollectionTableCell.superclass.setHeight.apply(this, arguments); + var o = this.options; + this.cell.setHeight(o.height - (o._top === 0 ? 1 : 0) - 1); + } +}); + +$.shortcut("bi.collection_table_cell", BI.CollectionTableCell);/** + * CollectionTable + * + * Created by GUY on 2016/1/12. + * @class BI.CollectionTable + * @extends BI.Widget + */ +BI.CollectionTable = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.CollectionTable.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-collection-table", + headerRowSize: 25, + rowSize: 25, + columnSize: [], + isNeedFreeze: false, + freezeCols: [], + isNeedMerge: false, + mergeCols: [], + mergeRule: BI.emptyFn, + header: [], + items: [], + regionColumnSize: [] + }); + }, + + _init: function () { + BI.CollectionTable.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this._width = 0; + this._height = 0; + this._scrollBarSize = BI.DOM.getScrollWidth(); + this.topLeftCollection = BI.createWidget({ + type: "bi.collection_view", + cellSizeAndPositionGetter: function (index) { + return self.topLeftItems[index]; + } + }); + this.topLeftCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { + self.bottomLeftCollection.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.topRightCollection = BI.createWidget({ + type: "bi.collection_view", + cellSizeAndPositionGetter: function (index) { + return self.topRightItems[index]; + } + }); + this.topRightCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { + self.bottomRightCollection.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.bottomLeftCollection = BI.createWidget({ + type: "bi.collection_view", + cellSizeAndPositionGetter: function (index) { + return self.bottomLeftItems[index]; + } + }); + this.bottomLeftCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { + self.bottomRightCollection.setScrollTop(scroll.scrollTop); + self.topLeftCollection.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.bottomRightCollection = BI.createWidget({ + type: "bi.collection_view", + cellSizeAndPositionGetter: function (index) { + return self.bottomRightItems[index]; + } + }); + this.bottomRightCollection.on(BI.Collection.EVENT_SCROLL, function (scroll) { + self.bottomLeftCollection.setScrollTop(scroll.scrollTop); + self.topRightCollection.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.topLeft = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.topLeftCollection] + }); + this.topRight = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.topRightCollection] + }); + this.bottomLeft = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.bottomLeftCollection] + }); + this.bottomRight = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.bottomRightCollection] + }); + this.contextLayout = BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.topLeft, + top: 0, + left: 0 + }, { + el: this.topRight, + top: 0 + }, { + el: this.bottomLeft, + left: 0 + }, { + el: this.bottomRight + }] + }); + + this.topScrollbar = BI.createWidget({ + type: "bi.grid_table_scrollbar", + width: BI.GridTableScrollbar.SIZE + }); + this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { + self.bottomLeftCollection.setScrollTop(scrollTop); + self.bottomRightCollection.setScrollTop(scrollTop); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.leftScrollbar = BI.createWidget({ + type: "bi.grid_table_horizontal_scrollbar", + height: BI.GridTableScrollbar.SIZE + }); + this.leftScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { + self.topLeftCollection.setScrollLeft(scrollLeft); + self.bottomLeftCollection.setScrollLeft(scrollLeft); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.rightScrollbar = BI.createWidget({ + type: "bi.grid_table_horizontal_scrollbar", + height: BI.GridTableScrollbar.SIZE + }); + this.rightScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { + self.topRightCollection.setScrollLeft(scrollLeft); + self.bottomRightCollection.setScrollLeft(scrollLeft); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.scrollBarLayout = BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.topScrollbar, + right: 0, + top: 0 + }, { + el: this.leftScrollbar, + left: 0 + }, { + el: this.rightScrollbar, + }] + }); + this._width = o.width - BI.GridTableScrollbar.SIZE; + this._height = o.height - BI.GridTableScrollbar.SIZE; + if (o.items.length > 0 || o.header.length < 0) { + this._digest(); + this._populate(); + } + }, + + _getFreezeColLength: function () { + return this.options.isNeedFreeze ? this.options.freezeCols.length : 0; + }, + + _populateScrollbar: function () { + var o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + this.topScrollbar.setContentSize(o.items.length * o.rowSize); + this.topScrollbar.setSize(this._height - o.header.length * o.headerRowSize); + this.topScrollbar.setPosition(this.bottomRightCollection.getScrollTop()); + this.topScrollbar.populate(); + + this.leftScrollbar.setContentSize(totalLeftColumnSize); + this.leftScrollbar.setSize(regionSize); + this.leftScrollbar.setPosition(this.bottomLeftCollection.getScrollLeft()); + this.leftScrollbar.populate(); + + this.rightScrollbar.setContentSize(totalRightColumnSize); + this.rightScrollbar.setSize(this._width - regionSize); + this.rightScrollbar.setPosition(this.bottomRightCollection.getScrollLeft()); + this.rightScrollbar.populate(); + + var items = this.scrollBarLayout.attr("items"); + items[0].top = o.header.length * o.headerRowSize; + items[1].top = this._height; + items[2].top = this._height; + items[2].left = regionSize; + this.scrollBarLayout.attr("items", items); + this.scrollBarLayout.resize(); + }, + + _populateTable: function () { + var self = this, o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + + var tlw = regionSize; + var tlh = regionSize >= summaryColumnSizeArray[freezeColLength - 1] ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); + var trw = this._width - regionSize; + var trh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); + var blw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? regionSize : (regionSize + this._scrollBarSize); + var blh = (regionSize >= (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + var brw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? (this._width - regionSize) : (this._width - regionSize + this._scrollBarSize); + var brh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + + var otlw = regionSize; + var otlh = o.header.length * o.headerRowSize; + var otrw = this._width - regionSize; + var otrh = o.header.length * o.headerRowSize; + var oblw = regionSize; + var oblh = this._height - o.header.length * o.headerRowSize; + var obrw = this._width - regionSize; + var obrh = this._height - o.header.length * o.headerRowSize; + + var digest = function (w, h, tw, th, el) { + if (w >= tw && h >= th) { + el.element.css({ + overflow: "hidden", + overflowX: "hidden", + overflowY: "hidden" + }) + } else if (w >= tw) { + el.element.css({ + overflow: "hidden", + overflowX: "hidden", + overflowY: "auto" + }) + } else if (h >= th) { + el.element.css({ + overflow: "hidden", + overflowX: "auto", + overflowY: "hidden" + }) + } else { + el.element.css({ + overflow: "auto", + overflowX: "auto", + overflowY: "auto" + }) + } + }; + + this.topLeft.setWidth(otlw); + this.topLeft.setHeight(otlh); + this.topRight.setWidth(otrw); + this.topRight.setHeight(otrh); + this.bottomLeft.setWidth(oblw); + this.bottomLeft.setHeight(oblh); + this.bottomRight.setWidth(obrw); + this.bottomRight.setHeight(obrh); + + this.topLeftCollection.setWidth(tlw); + this.topLeftCollection.setHeight(tlh); + this.topRightCollection.setWidth(trw); + this.topRightCollection.setHeight(trh); + this.bottomLeftCollection.setWidth(blw); + this.bottomLeftCollection.setHeight(blh); + this.bottomRightCollection.setWidth(brw); + this.bottomRightCollection.setHeight(brh); + + digest(tlw, tlh, totalLeftColumnSize, o.header.length * o.headerRowSize, this.topLeftCollection); + digest(trw, trh, totalRightColumnSize, o.header.length * o.headerRowSize, this.topRightCollection); + digest(blw, blh, totalLeftColumnSize, o.items.length * o.rowSize, this.bottomLeftCollection); + digest(brw, brh, totalRightColumnSize, o.items.length * o.rowSize, this.bottomRightCollection); + + var items = this.contextLayout.attr("items"); + items[1].left = regionSize; + items[2].top = o.header.length * o.headerRowSize; + items[3].left = regionSize; + items[3].top = o.header.length * o.headerRowSize; + this.contextLayout.attr("items", items); + this.contextLayout.resize(); + + var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; + var run = function (positions, items, rendered) { + BI.each(positions, function (i, item) { + var cell = { + type: "bi.collection_table_cell", + cell: items[item.row][item.col] + }; + rendered.push(cell); + }); + }; + run(this.topLeftItems, o.header, leftHeader); + run(this.topRightItems, o.header, rightHeader); + run(this.bottomLeftItems, o.items, leftItems); + run(this.bottomRightItems, o.items, rightItems); + + this.topLeftCollection.populate(leftHeader); + this.topRightCollection.populate(rightHeader); + this.bottomLeftCollection.populate(leftItems); + this.bottomRightCollection.populate(rightItems); + }, + + _digest: function () { + var o = this.options; + var freezeColLength = this._getFreezeColLength(); + this.topLeftItems = this._serialize(o.header, 0, freezeColLength, o.headerRowSize, o.columnSize, o.mergeCols); + this.topRightItems = this._serialize(o.header, freezeColLength, o.columnSize.length, o.headerRowSize, o.columnSize, true); + this.bottomLeftItems = this._serialize(o.items, 0, freezeColLength, o.rowSize, o.columnSize, o.mergeCols); + this.bottomRightItems = this._serialize(o.items, freezeColLength, o.columnSize.length, o.rowSize, o.columnSize, o.mergeCols); + }, + + _serialize: function (items, startCol, endCol, rowHeight, columnSize, mergeCols) { + var self = this, o = this.options; + var result = [], cache = {}, preCol = {}, preRow = {}, map = {}; + var summaryColumnSize = []; + for (var i = startCol; i < endCol; i++) { + if (i === startCol) { + summaryColumnSize[i] = columnSize[i]; + } else { + summaryColumnSize[i] = summaryColumnSize[i - 1] + columnSize[i]; + } + } + var mergeRow = function (i, j) { + preCol[j]._height += rowHeight; + preCol[j].__mergeRows.push(i); + }; + + var mergeCol = function (i, j) { + preRow[i]._width += columnSize[j]; + preRow[i].__mergeCols.push(j); + }; + + var createOneEl = function (r, c) { + var width = columnSize[c]; + var height = rowHeight; + map[r][c]._row = r; + map[r][c]._col = c; + map[r][c]._width = width; + map[r][c]._height = height; + preCol[c] = map[r][c]; + preCol[c].__mergeRows = [r]; + preRow[r] = map[r][c]; + preRow[r].__mergeCols = [c]; + + result.push({ + x: summaryColumnSize[c] - columnSize[c], + y: +r * rowHeight, + item: map[r][c] + }); + }; + + BI.each(items, function (i, cols) { + for (var j = startCol; j < endCol; j++) { + if (!cache[i]) { + cache[i] = {}; + } + if (!map[i]) { + map[i] = {}; + } + cache[i][j] = cols[j]; + map[i][j] = {}; + if (mergeCols === true || mergeCols.indexOf(j) > -1) { + if (i === 0 && j === startCol) { + createOneEl(0, startCol); + } else if (j === startCol && i > 0) { + var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); + if (isNeedMergeRow === true) { + mergeRow(i, j); + preRow[i] = preCol[j]; + } else { + createOneEl(i, j); + } + } else if (i === 0 && j > startCol) { + var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); + if (isNeedMergeCol === true) { + mergeCol(i, j); + preCol[j] = preRow[i]; + } else { + createOneEl(i, j); + } + } else { + var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); + var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); + if (isNeedMergeCol && isNeedMergeRow) { + continue; + //mergeRow(i, j);//优先合并列 + } + if (isNeedMergeCol) { + mergeCol(i, j); + } + if (isNeedMergeRow) { + mergeRow(i, j); + } + if (!isNeedMergeCol && !isNeedMergeRow) { + createOneEl(i, j); + } + } + } else { + createOneEl(i, j); + } + } + }); + return BI.map(result, function (i, item) { + return { + x: item.x, + y: item.y, + row: item.item._row, + col: item.item._col, + width: item.item._width, + height: item.item._height + } + }); + }, + + _populate: function () { + if (this._width <= 0 || this._height <= 0) { + return; + } + if (this._isNeedDigest === true) { + this._digest(); + } + this._populateTable(); + this._populateScrollbar(); + }, + + getRegionSize: function () { + var o = this.options; + var regionSize = o.regionColumnSize[0] || 0; + if (o.isNeedFreeze === false || o.freezeCols.length === 0) { + return 0; + } + if (!regionSize) { + BI.each(o.freezeCols, function (i, col) { + regionSize += o.columnSize[col]; + }); + } + return regionSize; + }, + + setVerticalScroll: function (scrollTop) { + this.bottomLeftCollection.setScrollTop(scrollTop); + this.bottomRightCollection.setScrollTop(scrollTop); + }, + + setLeftHorizontalScroll: function (scrollLeft) { + this.topLeftCollection.setScrollLeft(scrollLeft); + this.bottomLeftCollection.setScrollLeft(scrollLeft); + }, + + setRightHorizontalScroll: function (scrollLeft) { + this.topRightCollection.setScrollLeft(scrollLeft); + this.bottomRightCollection.setScrollLeft(scrollLeft); + }, + + getVerticalScroll: function () { + return this.bottomRightCollection.getScrollTop(); + }, + + getLeftHorizontalScroll: function () { + return this.bottomLeftCollection.getScrollLeft(); + }, + + getRightHorizontalScroll: function () { + return this.bottomRightCollection.getScrollLeft(); + }, + + setWidth: function (width) { + BI.CollectionTable.superclass.setWidth.apply(this, arguments); + this._width = this.options.width - BI.GridTableScrollbar.SIZE; + }, + + setHeight: function (height) { + BI.CollectionTable.superclass.setHeight.apply(this, arguments); + this._height = this.options.height - BI.GridTableScrollbar.SIZE; + }, + + setColumnSize: function (columnSize) { + this._isNeedDigest = true; + this.options.columnSize = columnSize; + }, + + setRegionColumnSize: function (regionColumnSize) { + this._isNeedDigest = true; + this.options.regionColumnSize = regionColumnSize; + }, + + getColumnSize: function () { + return this.options.columnSize; + }, + + getRegionColumnSize: function () { + return this.options.regionColumnSize; + }, + + populate: function (items, header) { + if (items && items !== this.options.items) { + this._isNeedDigest = true; + this.options.items = items; + this._restore(); + } + if (header && header !== this.options.header) { + this._isNeedDigest = true; + this.options.header = header; + this._restore(); + } + this._populate(); + }, + + _restore: function () { + this.topLeftCollection.restore(); + this.topRightCollection.restore(); + this.bottomLeftCollection.restore(); + this.bottomRightCollection.restore(); + }, + + restore: function () { + this._restore(); + } +}); +$.shortcut('bi.collection_table', BI.CollectionTable);/** + * QuickCollectionTable + * + * Created by GUY on 2016/1/12. + * @class BI.QuickCollectionTable + * @extends BI.CollectionTable + */ +BI.QuickCollectionTable = BI.inherit(BI.CollectionTable, { + _defaultConfig: function () { + return BI.extend(BI.QuickCollectionTable.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-quick-collection-table" + }); + }, + + _init: function () { + BI.QuickCollectionTable.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.topLeftCollection.setOverflowX(false); + this.topLeftCollection.setOverflowY(false); + this.topRightCollection.setOverflowX(false); + this.topRightCollection.setOverflowY(false); + this.bottomLeftCollection.setOverflowX(false); + this.bottomLeftCollection.setOverflowY(false); + this.bottomRightCollection.setOverflowX(false); + this.bottomRightCollection.setOverflowY(false); + this._leftWheelHandler = new BI.WheelHandler( + BI.bind(this._onWheelY, this), + BI.bind(this._shouldHandleX, this), + BI.bind(this._shouldHandleY, this) + ); + this._rightWheelHandler = new BI.WheelHandler( + BI.bind(this._onWheelY, this), + BI.bind(this._shouldHandleX, this), + BI.bind(this._shouldHandleY, this) + ); + this.bottomLeftCollection.element.mousewheel(function (e) { + self._leftWheelHandler.onWheel(e.originalEvent); + }); + this.bottomRightCollection.element.mousewheel(function (e) { + self._rightWheelHandler.onWheel(e.originalEvent); + }); + }, + + _shouldHandleX: function (delta) { + return false; + }, + + _shouldHandleY: function (delta) { + if (delta > 0) { + return this.bottomRightCollection.getScrollTop() < this.bottomRightCollection.getMaxScrollTop(); + } else { + return this.bottomRightCollection.getScrollTop() > 0; + } + }, + + _onWheelY: function (deltaX, deltaY) { + var self = this; + var scrollTop = this.bottomRightCollection.getScrollTop(); + scrollTop += deltaY; + this.bottomLeftCollection.setScrollTop(scrollTop); + this.bottomRightCollection.setScrollTop(scrollTop); + self._populateScrollbar(); + this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }, + + _populateTable: function () { + var self = this, o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + + var otlw = regionSize; + var otlh = o.header.length * o.headerRowSize; + var otrw = this._width - regionSize; + var otrh = o.header.length * o.headerRowSize; + var oblw = regionSize; + var oblh = this._height - o.header.length * o.headerRowSize; + var obrw = this._width - regionSize; + var obrh = this._height - o.header.length * o.headerRowSize; + + this.topLeft.setWidth(otlw); + this.topLeft.setHeight(otlh); + this.topRight.setWidth(otrw); + this.topRight.setHeight(otrh); + this.bottomLeft.setWidth(oblw); + this.bottomLeft.setHeight(oblh); + this.bottomRight.setWidth(obrw); + this.bottomRight.setHeight(obrh); + + this.topLeftCollection.setWidth(otlw); + this.topLeftCollection.setHeight(otlh); + this.topRightCollection.setWidth(otrw); + this.topRightCollection.setHeight(otrh); + this.bottomLeftCollection.setWidth(oblw); + this.bottomLeftCollection.setHeight(oblh); + this.bottomRightCollection.setWidth(obrw); + this.bottomRightCollection.setHeight(obrh); + + var items = this.contextLayout.attr("items"); + items[1].left = regionSize; + items[2].top = o.header.length * o.headerRowSize; + items[3].left = regionSize; + items[3].top = o.header.length * o.headerRowSize; + this.contextLayout.attr("items", items); + this.contextLayout.resize(); + + var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; + var run = function (positions, items, rendered) { + BI.each(positions, function (i, item) { + var cell = { + type: "bi.collection_table_cell", + cell: items[item.row][item.col] + }; + rendered.push(cell); + }); + }; + run(this.topLeftItems, o.header, leftHeader); + run(this.topRightItems, o.header, rightHeader); + run(this.bottomLeftItems, o.items, leftItems); + run(this.bottomRightItems, o.items, rightItems); + + this.topLeftCollection.populate(leftHeader); + this.topRightCollection.populate(rightHeader); + this.bottomLeftCollection.populate(leftItems); + this.bottomRightCollection.populate(rightItems); + } +}); +$.shortcut('bi.quick_collection_table', BI.QuickCollectionTable);/** + * + * 表格单元格 + * + * Created by GUY on 2016/1/12. + * @class BI.GridTableCell + * @extends BI.Widget + */ +BI.GridTableCell = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.GridTableCell.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-grid-table-cell", + width: 0, + height: 0, + _rowIndex: 0, + _columnIndex: 0, + _left: 0, + _top: 0, + cell: {} + }) + }, + + _init: function () { + BI.GridTableCell.superclass._init.apply(this, arguments); + var o = this.options; + this.cell = BI.createWidget(BI.extend({ + type: "bi.label" + }, o.cell, { + cls: (o.cell.cls || "") + "grid-table-cell-wrapper", + width: o.width - (o._columnIndex === 0 ? 1 : 0) - 1, + height: o.height - (o._rowIndex === 0 ? 1 : 0) - 1 + })); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.cell, + left: 0, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + setWidth: function (width) { + BI.GridTableCell.superclass.setWidth.apply(this, arguments); + var o = this.options; + this.cell.setWidth(o.width - (o._columnIndex === 0 ? 1 : 0) - 1); + }, + + setHeight: function (height) { + BI.GridTableCell.superclass.setHeight.apply(this, arguments); + var o = this.options; + this.cell.setHeight(o.height - (o._rowIndex === 0 ? 1 : 0) - 1); + } +}); + +$.shortcut("bi.grid_table_cell", BI.GridTableCell);/** + * GridTable + * + * Created by GUY on 2016/1/12. + * @class BI.GridTable + * @extends BI.Widget + */ +BI.GridTable = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.GridTable.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-grid-table", + headerRowSize: 25, + rowSize: 25, + columnSize: [], + isNeedFreeze: false, + freezeCols: [], + header: [], + items: [], + regionColumnSize: [] + }); + }, + + _init: function () { + BI.GridTable.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this._width = 0; + this._height = 0; + this._scrollBarSize = BI.DOM.getScrollWidth(); + var rowHeightGetter = function () { + return o.rowSize; + }; + var columnLeftWidthGetter = function (index) { + return o.columnSize[index]; + }; + var columnRightWidthGetter = function (index) { + return o.columnSize[index + self._getFreezeColLength()]; + }; + this.topLeftGrid = BI.createWidget({ + type: "bi.grid_view", + rowHeightGetter: rowHeightGetter, + columnWidthGetter: columnLeftWidthGetter, + }); + this.topLeftGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { + self.bottomLeftGrid.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.topRightGrid = BI.createWidget({ + type: "bi.grid_view", + rowHeightGetter: rowHeightGetter, + columnWidthGetter: columnRightWidthGetter, + }); + this.topRightGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { + self.bottomRightGrid.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.bottomLeftGrid = BI.createWidget({ + type: "bi.grid_view", + rowHeightGetter: rowHeightGetter, + columnWidthGetter: columnLeftWidthGetter, + }); + this.bottomLeftGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { + self.bottomRightGrid.setScrollTop(scroll.scrollTop); + self.topLeftGrid.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.bottomRightGrid = BI.createWidget({ + type: "bi.grid_view", + rowHeightGetter: rowHeightGetter, + columnWidthGetter: columnRightWidthGetter, + }); + this.bottomRightGrid.on(BI.Grid.EVENT_SCROLL, function (scroll) { + self.bottomLeftGrid.setScrollTop(scroll.scrollTop); + self.topRightGrid.setScrollLeft(scroll.scrollLeft); + self._populateScrollbar(); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.topLeft = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.topLeftGrid] + }); + this.topRight = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.topRightGrid] + }); + this.bottomLeft = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.bottomLeftGrid] + }); + this.bottomRight = BI.createWidget({ + type: "bi.vertical", + scrollable: false, + scrolly: false, + items: [this.bottomRightGrid] + }); + this.contextLayout = BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.topLeft, + top: 0, + left: 0 + }, { + el: this.topRight, + top: 0 + }, { + el: this.bottomLeft, + left: 0 + }, { + el: this.bottomRight + }] + }); + + this.topScrollbar = BI.createWidget({ + type: "bi.grid_table_scrollbar", + width: BI.GridTableScrollbar.SIZE + }); + this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { + self.bottomLeftGrid.setScrollTop(scrollTop); + self.bottomRightGrid.setScrollTop(scrollTop); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.leftScrollbar = BI.createWidget({ + type: "bi.grid_table_horizontal_scrollbar", + height: BI.GridTableScrollbar.SIZE + }); + this.leftScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { + self.topLeftGrid.setScrollLeft(scrollLeft); + self.bottomLeftGrid.setScrollLeft(scrollLeft); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.rightScrollbar = BI.createWidget({ + type: "bi.grid_table_horizontal_scrollbar", + height: BI.GridTableScrollbar.SIZE + }); + this.rightScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { + self.topRightGrid.setScrollLeft(scrollLeft); + self.bottomRightGrid.setScrollLeft(scrollLeft); + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }); + this.scrollBarLayout = BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.topScrollbar, + right: 0, + top: 0 + }, { + el: this.leftScrollbar, + left: 0 + }, { + el: this.rightScrollbar, + }] + }); + this._width = o.width - BI.GridTableScrollbar.SIZE; + this._height = o.height - BI.GridTableScrollbar.SIZE; + this.header = this._getHeader(); + this.items = this._getItems(); + if (o.items.length > 0) { + this._populate(); + } + }, + + _getFreezeColLength: function () { + return this.options.isNeedFreeze ? this.options.freezeCols.length : 0; + }, + + _populateScrollbar: function () { + var o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + this.topScrollbar.setContentSize(o.items.length * o.rowSize); + this.topScrollbar.setSize(this._height - o.header.length * o.headerRowSize); + this.topScrollbar.setPosition(Math.min(this.bottomLeftGrid.getScrollTop(), this.bottomRightGrid.getScrollTop())); + this.topScrollbar.populate(); + + this.leftScrollbar.setContentSize(totalLeftColumnSize); + this.leftScrollbar.setSize(regionSize); + this.leftScrollbar.setPosition(this.bottomLeftGrid.getScrollLeft()); + this.leftScrollbar.populate(); + + this.rightScrollbar.setContentSize(totalRightColumnSize); + this.rightScrollbar.setSize(this._width - regionSize); + this.rightScrollbar.setPosition(this.bottomRightGrid.getScrollLeft()); + this.rightScrollbar.populate(); + + var items = this.scrollBarLayout.attr("items"); + items[0].top = o.header.length * o.headerRowSize; + items[1].top = this._height; + items[2].top = this._height; + items[2].left = regionSize; + this.scrollBarLayout.attr("items", items); + this.scrollBarLayout.resize(); + }, + + _getHeader: function () { + var o = this.options; + var freezeColLength = this._getFreezeColLength(); + var leftHeader = [], rightHeader = []; + BI.each(o.header, function (i, cols) { + leftHeader[i] = []; + rightHeader[i] = []; + BI.each(cols, function (j, col) { + var cell = { + type: "bi.grid_table_cell", + cell: col + }; + if (j < freezeColLength) { + leftHeader[i].push(cell); + } else { + rightHeader[i].push(cell); + } + }); + }); + return [leftHeader, rightHeader]; + }, + + _getItems: function () { + var o = this.options; + var freezeColLength = this._getFreezeColLength(); + var leftItems = [], rightItems = []; + BI.each(o.items, function (i, cols) { + leftItems[i] = []; + rightItems[i] = []; + BI.each(cols, function (j, col) { + var cell = { + type: "bi.grid_table_cell", + cell: col + }; + if (j < freezeColLength) { + leftItems[i].push(cell); + } else { + rightItems[i].push(cell); + } + }); + }); + return [leftItems, rightItems]; + }, + + _populateTable: function () { + var self = this, o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + + var tlw = regionSize; + var tlh = regionSize >= summaryColumnSizeArray[freezeColLength - 1] ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); + var trw = this._width - regionSize; + var trh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (o.header.length * o.headerRowSize) : (o.header.length * o.headerRowSize + this._scrollBarSize); + var blw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? regionSize : (regionSize + this._scrollBarSize); + var blh = (regionSize >= (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + var brw = (this._height - o.header.length * o.headerRowSize >= totalRowSize) ? (this._width - regionSize) : (this._width - regionSize + this._scrollBarSize); + var brh = (this._width - regionSize >= totalColumnSize - (summaryColumnSizeArray[freezeColLength - 1] || 0)) ? (this._height - o.header.length * o.headerRowSize) : (this._height - o.header.length * o.headerRowSize + this._scrollBarSize); + + var otlw = regionSize; + var otlh = o.header.length * o.headerRowSize; + var otrw = this._width - regionSize; + var otrh = o.header.length * o.headerRowSize; + var oblw = regionSize; + var oblh = this._height - o.header.length * o.headerRowSize; + var obrw = this._width - regionSize; + var obrh = this._height - o.header.length * o.headerRowSize; + + var digest = function (w, h, tw, th, el) { + if (w >= tw && h >= th) { + el.element.css({ + overflow: "hidden", + overflowX: "hidden", + overflowY: "hidden" + }) + } else if (w >= tw) { + el.element.css({ + overflow: "hidden", + overflowX: "hidden", + overflowY: "auto" + }) + } else if (h >= th) { + el.element.css({ + overflow: "hidden", + overflowX: "auto", + overflowY: "hidden" + }) + } else { + el.element.css({ + overflow: "auto", + overflowX: "auto", + overflowY: "auto" + }) + } + }; + + this.topLeft.setWidth(otlw); + this.topLeft.setHeight(otlh); + this.topRight.setWidth(otrw); + this.topRight.setHeight(otrh); + this.bottomLeft.setWidth(oblw); + this.bottomLeft.setHeight(oblh); + this.bottomRight.setWidth(obrw); + this.bottomRight.setHeight(obrh); + + this.topLeftGrid.setWidth(tlw); + this.topLeftGrid.setHeight(tlh); + this.topRightGrid.setWidth(trw); + this.topRightGrid.setHeight(trh); + this.bottomLeftGrid.setWidth(blw); + this.bottomLeftGrid.setHeight(blh); + this.bottomRightGrid.setWidth(brw); + this.bottomRightGrid.setHeight(brh); + + digest(tlw, tlh, totalLeftColumnSize, o.header.length * o.headerRowSize, this.topLeftGrid); + digest(trw, trh, totalRightColumnSize, o.header.length * o.headerRowSize, this.topRightGrid); + digest(blw, blh, totalLeftColumnSize, o.items.length * o.rowSize, this.bottomLeftGrid); + digest(brw, brh, totalRightColumnSize, o.items.length * o.rowSize, this.bottomRightGrid); + + this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); + this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); + this.topRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); + this.topRightGrid.setEstimatedRowSize(o.headerRowSize); + this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); + this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); + this.bottomRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); + this.bottomRightGrid.setEstimatedRowSize(o.rowSize); + + var items = this.contextLayout.attr("items"); + items[1].left = regionSize; + items[2].top = o.header.length * o.headerRowSize; + items[3].left = regionSize; + items[3].top = o.header.length * o.headerRowSize; + this.contextLayout.attr("items", items); + this.contextLayout.resize(); + + this.topLeftGrid.populate(this.header[0]); + this.topRightGrid.populate(this.header[1]); + this.bottomLeftGrid.populate(this.items[0]); + this.bottomRightGrid.populate(this.items[1]); + }, + + _populate: function () { + if (this._width <= 0 || this._height <= 0) { + return; + } + this._populateTable(); + this._populateScrollbar(); + }, + + getRegionSize: function () { + var o = this.options; + var regionSize = o.regionColumnSize[0] || 0; + if (o.isNeedFreeze === false || o.freezeCols.length === 0) { + return 0; + } + if (!regionSize) { + BI.each(o.freezeCols, function (i, col) { + regionSize += o.columnSize[col]; + }); + } + return regionSize; + }, + + setVerticalScroll: function (scrollTop) { + this.bottomLeftGrid.setScrollTop(scrollTop); + this.bottomRightGrid.setScrollTop(scrollTop); + }, + + setLeftHorizontalScroll: function (scrollLeft) { + this.topLeftGrid.setScrollLeft(scrollLeft); + this.bottomLeftGrid.setScrollLeft(scrollLeft); + }, + + setRightHorizontalScroll: function (scrollLeft) { + this.topRightGrid.setScrollLeft(scrollLeft); + this.bottomRightGrid.setScrollLeft(scrollLeft); + }, + + getVerticalScroll: function () { + return this.bottomRightGrid.getScrollTop(); + }, + + getLeftHorizontalScroll: function () { + return this.bottomLeftGrid.getScrollLeft(); + }, + + getRightHorizontalScroll: function () { + return this.bottomRightGrid.getScrollLeft(); + }, + + setWidth: function (width) { + BI.GridTable.superclass.setWidth.apply(this, arguments); + this._width = this.options.width - BI.GridTableScrollbar.SIZE; + }, + + setHeight: function (height) { + BI.GridTable.superclass.setHeight.apply(this, arguments); + this._height = this.options.height - BI.GridTableScrollbar.SIZE; + }, + + setColumnSize: function (columnSize) { + this.options.columnSize = columnSize; + }, + + setRegionColumnSize: function (regionColumnSize) { + this.options.regionColumnSize = regionColumnSize; + }, + + getColumnSize: function () { + return this.options.columnSize; + }, + + getRegionColumnSize: function () { + return this.options.regionColumnSize; + }, + + populate: function (items, header) { + if (items && this.options.items !== items) { + this.options.items = items; + this.items = this._getItems(); + this._restore(); + } + if (header && this.options.header !== header) { + this.options.header = header; + this.header = this._getHeader(); + this._restore(); + } + this._populate(); + }, + + _restore: function () { + this.topLeftGrid.restore(); + this.topRightGrid.restore(); + this.bottomLeftGrid.restore(); + this.bottomRightGrid.restore(); + }, + + restore: function () { + this._restore(); + } +}); +$.shortcut('bi.grid_table', BI.GridTable);/** + * QuickGridTable + * + * Created by GUY on 2016/1/12. + * @class BI.QuickGridTable + * @extends BI.GridTable + */ +BI.QuickGridTable = BI.inherit(BI.GridTable, { + _defaultConfig: function () { + return BI.extend(BI.QuickGridTable.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-quick-grid-table" + }); + }, + + _init: function () { + BI.QuickGridTable.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.topLeftGrid.setOverflowX(false); + this.topLeftGrid.setOverflowY(false); + this.topRightGrid.setOverflowX(false); + this.topRightGrid.setOverflowY(false); + this.bottomLeftGrid.setOverflowX(false); + this.bottomLeftGrid.setOverflowY(false); + this.bottomRightGrid.setOverflowX(false); + this.bottomRightGrid.setOverflowY(false); + this._leftWheelHandler = new BI.WheelHandler( + BI.bind(this._onWheelY, this), + BI.bind(this._shouldHandleX, this), + BI.bind(this._shouldHandleY, this) + ); + this._rightWheelHandler = new BI.WheelHandler( + BI.bind(this._onWheelY, this), + BI.bind(this._shouldHandleX, this), + BI.bind(this._shouldHandleY, this) + ); + this.bottomLeftGrid.element.mousewheel(function (e) { + self._leftWheelHandler.onWheel(e.originalEvent); + }); + this.bottomRightGrid.element.mousewheel(function (e) { + self._rightWheelHandler.onWheel(e.originalEvent); + }); + }, + + _shouldHandleX: function (delta) { + return false; + }, + + _shouldHandleY: function (delta) { + if (delta > 0) { + return this.bottomRightGrid.getScrollTop() < this.bottomRightGrid.getMaxScrollTop(); + } else { + return this.bottomRightGrid.getScrollTop() > 0; + } + }, + + _onWheelY: function (deltaX, deltaY) { + var self = this; + var scrollTop = this.bottomRightGrid.getScrollTop(); + scrollTop += deltaY; + this.bottomLeftGrid.setScrollTop(scrollTop); + this.bottomRightGrid.setScrollTop(scrollTop); + self._populateScrollbar(); + this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + }, + + _populateTable: function () { + var self = this, o = this.options; + var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = [], totalRowSize = o.items.length * o.rowSize; + var freezeColLength = this._getFreezeColLength(); + BI.each(o.columnSize, function (i, size) { + if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { + totalLeftColumnSize += size; + } else { + totalRightColumnSize += size; + } + totalColumnSize += size; + if (i === 0) { + summaryColumnSizeArray[i] = size; + } else { + summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; + } + }); + + var otlw = regionSize; + var otlh = o.header.length * o.headerRowSize; + var otrw = this._width - regionSize; + var otrh = o.header.length * o.headerRowSize; + var oblw = regionSize; + var oblh = this._height - o.header.length * o.headerRowSize; + var obrw = this._width - regionSize; + var obrh = this._height - o.header.length * o.headerRowSize; + + this.topLeft.setWidth(otlw); + this.topLeft.setHeight(otlh); + this.topRight.setWidth(otrw); + this.topRight.setHeight(otrh); + this.bottomLeft.setWidth(oblw); + this.bottomLeft.setHeight(oblh); + this.bottomRight.setWidth(obrw); + this.bottomRight.setHeight(obrh); + + this.topLeftGrid.setWidth(otlw); + this.topLeftGrid.setHeight(otlh); + this.topRightGrid.setWidth(otrw); + this.topRightGrid.setHeight(otrh); + this.bottomLeftGrid.setWidth(oblw); + this.bottomLeftGrid.setHeight(oblh); + this.bottomRightGrid.setWidth(obrw); + this.bottomRightGrid.setHeight(obrh); + + this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); + this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); + this.topRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); + this.topRightGrid.setEstimatedRowSize(o.headerRowSize); + this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); + this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); + this.bottomRightGrid.setEstimatedColumnSize(totalRightColumnSize / (o.columnSize.length - freezeColLength)); + this.bottomRightGrid.setEstimatedRowSize(o.rowSize); + + var items = this.contextLayout.attr("items"); + items[1].left = regionSize; + items[2].top = o.header.length * o.headerRowSize; + items[3].left = regionSize; + items[3].top = o.header.length * o.headerRowSize; + this.contextLayout.attr("items", items); + this.contextLayout.resize(); + + var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; + BI.each(o.header, function (i, cols) { + leftHeader[i] = []; + rightHeader[i] = []; + BI.each(cols, function (j, col) { + var cell = { + type: "bi.grid_table_cell", + cell: col + }; + if (j < freezeColLength) { + leftHeader[i].push(cell); + } else { + rightHeader[i].push(cell); + } + }); + }); + BI.each(o.items, function (i, cols) { + leftItems[i] = []; + rightItems[i] = []; + BI.each(cols, function (j, col) { + var cell = { + type: "bi.grid_table_cell", + cell: col + }; + if (j < freezeColLength) { + leftItems[i].push(cell); + } else { + rightItems[i].push(cell); + } + }); + }); + this.topLeftGrid.populate(leftHeader); + this.topRightGrid.populate(rightHeader); + this.bottomLeftGrid.populate(leftItems); + this.bottomRightGrid.populate(rightItems); + } +}); +$.shortcut('bi.quick_grid_table', BI.QuickGridTable);/** + * + * 表格滚动条 + * + * Created by GUY on 2016/1/12. + * @class BI.GridTableScrollbar + * @extends BI.Widget + */ +BI.GridTableScrollbar = BI.inherit(BI.Widget, { + _const: { + FACE_MARGIN: 4, + FACE_MARGIN_2: 4 * 2, + FACE_SIZE_MIN: 30, + KEYBOARD_SCROLL_AMOUNT: 40 + }, + _defaultConfig: function () { + return BI.extend(BI.GridTableScrollbar.superclass._defaultConfig.apply(this, arguments), { + baseCls: "scrollbar-layout-main public-scrollbar-main", + attributes: { + tabIndex: 0 + }, + contentSize: 0, + defaultPosition: 0, + isOpaque: false, + orientation: "vertical", + position: 0, + size: 0 + }) + }, + + _init: function () { + BI.GridTableScrollbar.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.focused = false; + this.isDragging = false; + this.face = BI.createWidget({ + type: "bi.layout", + cls: "scrollbar-layout-face public-scrollbar-face " + + (this._isHorizontal() ? "scrollbar-layout-face-horizontal" : "scrollbar-layout-face-vertical") + }); + this.contextLayout = BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.face, + left: 0, + top: 0 + }] + }); + var onWheel = o.orientation === 'horizontal' ? this._onWheelX : this._onWheelY; + this._wheelHandler = new BI.WheelHandler( + BI.bind(onWheel, this), + BI.bind(this._shouldHandleX, this), + BI.bind(this._shouldHandleY, this) + ); + this._mouseMoveTracker = new BI.MouseMoveTracker( + BI.bind(this._onMouseMove, this), + BI.bind(this._onMouseMoveEnd, this), + document + ); + this.element.on("mousedown", BI.bind(this._onMouseDown, this)); + this.element.on("mousewheel", function (e) { + self._wheelHandler.onWheel(e.originalEvent); + }); + this.element.on("keydown", BI.bind(this._onKeyDown, this)); + this.element.on("focus", function () { + self.focused = true; + self._populate(); + }); + this.element.on("blur", function () { + self.focused = false; + self._populate(); + }); + if (this._isHorizontal()) { + this.element.addClass("scrollbar-layout-main-horizontal"); + } else { + this.element.addClass("scrollbar-layout-main-vertical"); + } + this._populate(); + }, + + _isHorizontal: function () { + return this.options.orientation === 'horizontal' + }, + + _getScale: function () { + var o = this.options; + var scale = o.size / o.contentSize; + var faceSize = o.size * scale; + + if (faceSize < this._const.FACE_SIZE_MIN) { + scale = (o.size - this._const.FACE_SIZE_MIN) / (o.contentSize - o.size); + } + return scale; + }, + + _getFaceSize: function () { + var o = this.options; + var scale = o.size / o.contentSize; + var faceSize = o.size * scale; + + if (faceSize < this._const.FACE_SIZE_MIN) { + faceSize = this._const.FACE_SIZE_MIN; + } + return faceSize; + }, + + _shouldHandleX: function (delta) { + return this.options.orientation === 'horizontal' ? + this._shouldHandleChange(delta) : + false; + }, + + _shouldHandleY: function (delta) { + return this.options.orientation !== 'horizontal' ? + this._shouldHandleChange(delta) : + false; + }, + + _shouldHandleChange: function (delta) { + return this.options.position + delta !== this.options.position; + }, + + _onWheelY: function (deltaX, deltaY) { + this._onWheel(deltaY); + }, + + _onWheelX: function (deltaX, deltaY) { + this._onWheel(deltaX); + }, + + _onWheel: function (delta) { + var maxPosition = this.options.contentSize - this.options.size; + this.options.position += delta; + if (this.options.position < 0) { + this.options.position = 0; + } else if (this.options.position > maxPosition) { + this.options.position = maxPosition; + } + this._populate(); + this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); + }, + + _onMouseDown: function (e) { + if (e.target !== this.face.element[0]) { + var position = this._isHorizontal() ? e.offsetX : e.offsetY; + position /= this._getScale(); + this.options.position = BI.clamp(position - (this._getFaceSize() * 0.5 / this._getScale()), 0, this.options.contentSize - this.options.size); + this._populate(); + this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); + } else { + this._mouseMoveTracker.captureMouseMoves(e); + } + this.element[0].focus(); + }, + + _onMouseMove: function (deltaX, deltaY) { + var delta = this._isHorizontal() ? deltaX : deltaY; + delta /= this._getScale(); + this.options.position = BI.clamp(this.options.position + delta, 0, this.options.contentSize - this.options.size); + this.isDragging = this._mouseMoveTracker.isDragging(); + this._populate(); + this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); + }, + + _onMouseMoveEnd: function (event) { + this._mouseMoveTracker.releaseMouseMoves(); + if (this.isDragging === true) { + this.isDragging = false; + this._populate(); + } + }, + + _onKeyDown: function (event) { + var Keys = { + BACKSPACE: 8, + TAB: 9, + RETURN: 13, + ALT: 18, + ESC: 27, + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + END: 35, + HOME: 36, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + DELETE: 46, + COMMA: 188, + PERIOD: 190, + A: 65, + Z: 90, + ZERO: 48, + NUMPAD_0: 96, + NUMPAD_9: 105 + }; + var keyCode = event.keyCode; + + if (keyCode === Keys.TAB) { + return; + } + + var distance = 40; + var direction = 0; + + if (this._isHorizontal()) { + switch (keyCode) { + case Keys.HOME: + direction = -1; + distance = this.options.contentSize; + break; + + case Keys.LEFT: + direction = -1; + break; + + case Keys.RIGHT: + direction = 1; + break; + + default: + return; + } + } + + if (!this._isHorizontal()) { + switch (keyCode) { + case Keys.SPACE: + if (event.shiftKey) { + direction = -1; + } else { + direction = 1; + } + break; + + case Keys.HOME: + direction = -1; + distance = this.options.contentSize; + break; + + case Keys.UP: + direction = -1; + break; + + case Keys.DOWN: + direction = 1; + break; + + case Keys.PAGE_UP: + direction = -1; + distance = this.options.size; + break; + + case Keys.PAGE_DOWN: + direction = 1; + distance = this.options.size; + break; + + default: + return; + } + } + + this.options.position = BI.clamp(this.options.position + (distance * direction), 0, this.options.contentSize - this.options.size); + event.preventDefault(); + this._populate(); + this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); + }, + + _populate: function () { + var self = this, o = this.options; + if (o.size < 1 || o.contentSize <= o.size) { + this.setVisible(false); + return; + } + this.setVisible(true); + + var size = o.size; + var isHorizontal = this._isHorizontal(); + var isActive = this.focused || this.isDragging; + + var faceSize = this._getFaceSize(); + var isOpaque = o.isOpaque; + this.element[isOpaque === true ? "addClass" : "removeClass"]("public-scrollbar-main-opaque"); + this.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-main-active"); + + this.face.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-face-active"); + + var position = o.position * this._getScale() + this._const.FACE_MARGIN; + + var items = this.contextLayout.attr("items"); + if (isHorizontal) { + this.setWidth(size); + this.face.setWidth(faceSize - this._const.FACE_MARGIN_2); + items[0].left = position; + items[0].top = 0; + } else { + this.setHeight(size); + this.face.setHeight(faceSize - this._const.FACE_MARGIN_2); + items[0].left = 0; + items[0].top = position; + } + this.contextLayout.attr("items", items); + this.contextLayout.resize(); + }, + + setContentSize: function (contentSize) { + this.options.contentSize = contentSize; + }, + + setPosition: function (position) { + this.options.position = position; + }, + + setSize: function (size) { + this.options.size = size; + }, + + populate: function () { + this._populate(); + } +}); +BI.GridTableScrollbar.SIZE = 10; +BI.GridTableScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; +$.shortcut("bi.grid_table_scrollbar", BI.GridTableScrollbar); + + +BI.GridTableHorizontalScrollbar = BI.inherit(BI.Widget, { + _const: { + FACE_MARGIN: 4, + FACE_MARGIN_2: 4 * 2, + FACE_SIZE_MIN: 30, + KEYBOARD_SCROLL_AMOUNT: 40 + }, + _defaultConfig: function () { + return BI.extend(BI.GridTableHorizontalScrollbar.superclass._defaultConfig.apply(this, arguments), { + attributes: { + tabIndex: 0 + }, + contentSize: 0, + position: 0, + size: 0 + }) + }, + + _init: function () { + BI.GridTableHorizontalScrollbar.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.scrollbar = BI.createWidget({ + type: "bi.grid_table_scrollbar", + orientation: "horizontal", + isOpaque: true, + position: o.position, + contentSize: o.contentSize, + size: o.size + }); + this.scrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function () { + self.fireEvent(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, arguments); + }); + BI.createWidget({ + type: "bi.absolute", + cls: "horizontal-scrollbar", + element: this, + width: o.size, + height: BI.GridTableScrollbar.SIZE, + items: [{ + el: { + type: "bi.absolute", + scrollable: false, + height: BI.GridTableScrollbar.SIZE, + items: [{ + el: this.scrollbar, + left: 0, + top: 0 + }] + }, + top: 0, + left: 0, + right: 0 + }] + }); + }, + + setContentSize: function (contentSize) { + this.options.contentSize = contentSize; + this.scrollbar.setContentSize(contentSize); + }, + + setPosition: function (position) { + this.options.position = position; + this.scrollbar.setPosition(position); + }, + + setSize: function (size) { + this.setWidth(size); + this.options.size = size; + this.scrollbar.setSize(size); + }, + + populate: function () { + this.scrollbar.populate(); + } +}); +BI.GridTableHorizontalScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; +$.shortcut("bi.grid_table_horizontal_scrollbar", BI.GridTableHorizontalScrollbar);/** + * + * 表格 + * + * Created by GUY on 2015/9/22. + * @class BI.TableHeaderCell + * @extends BI.Single + */ +BI.TableHeaderCell = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.TableHeaderCell.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-table-header-cell", + text: "" + }) + }, + + _init: function () { + BI.TableHeaderCell.superclass._init.apply(this, arguments); + BI.createWidget({ + type: "bi.label", + element: this, + textAlign: "center", + height: this.options.height, + text: this.options.text, + value: this.options.value + }) + } +}); + +$.shortcut("bi.table_header_cell", BI.TableHeaderCell);/** + * + * 表格 + * + * 能处理静态宽度以及动态宽度的表, 百分比宽度的表请使用PreviewTable + * + * Created by GUY on 2015/9/22. + * @class BI.Table + * @extends BI.Widget + */ +BI.Table = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.Table.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-table", + logic: { //冻结的页面布局逻辑 + dynamic: false + }, + + isNeedResize: false,//是否需要调整列宽 + isResizeAdapt: true,//是否需要在调整列宽或区域宽度的时候它们自适应变化 + + isNeedFreeze: false,//是否需要冻结单元格 + freezeCols: [], //冻结的列号,从0开始,isNeedFreeze为true时生效 + + isNeedMerge: false,//是否需要合并单元格 + mergeCols: [], //合并的单元格列号 + mergeRule: function (row1, row2) { //合并规则, 默认相等时合并 + return BI.isEqual(row1, row2); + }, + + columnSize: [], + headerRowSize: 25, + footerRowSize: 25, + rowSize: 25, + + regionColumnSize: false, + + header: [], + footer: false, + items: [] //二维数组 + }) + }, + + _calculateWidth: function (width) { + if (!width || width === "0") { + return ""; + } + width = BI.parseFloat(width); + if (width < 0) { + width = 0; + } + return width > 1.01 ? width : (width * 100 + "%"); + }, + + _calculateHeight: function (height) { + return height ? height : ""; + }, + + _isRightFreeze: function () { + return BI.isNotEmptyArray(this.options.freezeCols) && BI.first(this.options.freezeCols) !== 0; + }, + + _createTopLeft: function () { + var o = this.options, isRight = this._isRightFreeze(); + this.topLeftColGroupTds = {}; + this.topLeftBodyTds = {}; + this.topLeftBodyItems = {}; + var table = this._table(); + var colgroup = this._createColGroup(this.columnLeft, this.topLeftColGroupTds); + var body = this.topLeftBody = this._body(); + body.element.append(this._createHeaderCells(this.topLeftItems, this.columnLeft, this.mergeLeft, this.topLeftBodyTds, this.topLeftBodyItems)); + BI.createWidget({ + type: "bi.adaptive", + element: table, + items: [colgroup, body] + }); + if (isRight) { + var w = 0; + BI.each(o.columnSize, function (i, col) { + if (!o.freezeCols.contains(i)) { + w += col; + } + }); + if (BI.isNumeric(w) && w > 1) { + w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; + } + } + return (this.topLeftContainer = BI.createWidget({ + type: "bi.adaptive", + width: this._calculateWidth(w), + items: [table] + })); + }, - var lw = 0, rw = 0; - this.columnLeft = []; - this.columnRight = []; - BI.each(o.columnSize, function (i, size) { - if (o.freezeCols.contains(i)) { - lw += size; - self[isRight ? "columnRight" : "columnLeft"].push(size); - } else { - rw += size; - self[isRight ? "columnLeft" : "columnRight"].push(size); + _createTopRight: function () { + var o = this.options, isRight = this._isRightFreeze(); + this.topRightColGroupTds = {}; + this.topRightBodyTds = {}; + this.topRightBodyItems = {}; + var table = this._table(); + var colgroup = this._createColGroup(this.columnRight, this.topRightColGroupTds); + var body = this.topRightBody = this._body(); + body.element.append(this._createHeaderCells(this.topRightItems, this.columnRight, this.mergeRight, this.topRightBodyTds, this.topRightBodyItems, this.columnLeft.length)); + BI.createWidget({ + type: "bi.adaptive", + element: table, + items: [colgroup, body] + }); + if (!isRight) { + var w = 0; + BI.each(o.columnSize, function (i, col) { + if (!o.freezeCols.contains(i)) { + w += col; + } + }); + if (BI.isNumeric(w)) { + w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; + } + } + return (this.topRightContainer = BI.createWidget({ + type: "bi.adaptive", + width: w || undefined, + items: [table] + })); + }, + + _createBottomLeft: function () { + var o = this.options, isRight = this._isRightFreeze(); + this.bottomLeftColGroupTds = {}; + this.bottomLeftBodyTds = {}; + this.bottomLeftBodyItems = {}; + var table = this._table(); + var colgroup = this._createColGroup(this.columnLeft, this.bottomLeftColGroupTds); + var body = this._createBottomLeftBody(); + BI.createWidget({ + type: "bi.adaptive", + element: table, + items: [colgroup, body] + }); + if (isRight) { + var w = 0; + BI.each(o.columnSize, function (i, col) { + if (!o.freezeCols.contains(i)) { + w += col; } }); - lw = this._calculateWidth(lw); - rw = this._calculateWidth(rw); - - if (BI.isNumeric(lw)) { - lw = BI.parseFloat(lw) + o.freezeCols.length; - } - if (BI.isNumeric(rw)) { - rw = BI.parseFloat(rw) + o.columnSize.length - o.freezeCols.length; - } - this.topLeftContainer.element.width(isRight ? rw : lw); - this.bottomLeftContainer.element.width(isRight ? rw : lw); - this.topRightContainer.element.width(isRight ? lw : rw); - this.bottomRightContainer.element.width(isRight ? lw : rw); - this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; - this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; - if (o.isNeedResize && o.isResizeAdapt) { - var leftWidth = BI.sum(o.freezeCols, function (i, col) { - return o.columnSize[col] > 1 ? o.columnSize[col] + 1 : o.columnSize[col]; - }); - this.partitions.attr("columnSize", isRight ? ['fill', leftWidth] : [leftWidth, 'fill']); - this.partitions.resize(); + if (BI.isNumeric(w) && w > 1) { + w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } - } else { - BI.each(this.colgroupTds, function (i, colgroup) { - var width = colgroup.attr("width") | 0; - if (width !== o.columnSize[i]) { - var w = self._calculateWidth(o.columnSize[i]); - colgroup.attr("width", w).css("width", w); - BI.each(self.bodyTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(self.headerTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(self.footerTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(self.bodyItems, function (j, items) { - if (items[i]) { - if (self.bodyTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (self.bodyTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += self.bodyTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } - } - }); - BI.each(self.headerItems, function (j, items) { - if (items[i]) { - if (self.headerTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (self.headerTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += self.headerTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } - } - }); - BI.each(self.footerItems, function (j, items) { - if (items[i]) { - if (self.footerTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(o.columnSize, function (t, s) { - if (self.footerTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += self.footerTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } - } - }); + } + return (this.bottomLeftContainer = BI.createWidget({ + type: "bi.adaptive", + width: this._calculateWidth(w), + items: [table] + })); + }, + + _createBottomLeftBody: function () { + var body = this.bottomLeftBody = this._body(); + body.element.append(this._createCells(this.bottomLeftItems, this.columnLeft, this.mergeLeft, this.bottomLeftBodyTds, this.bottomLeftBodyItems)); + return body; + }, + + _createBottomRight: function () { + var o = this.options, isRight = this._isRightFreeze(); + this.bottomRightColGroupTds = {}; + this.bottomRightBodyTds = {}; + this.bottomRightBodyItems = {}; + var table = this._table(); + var colgroup = this._createColGroup(this.columnRight, this.bottomRightColGroupTds); + var body = this._createBottomRightBody(); + BI.createWidget({ + type: "bi.adaptive", + element: table, + items: [colgroup, body] + }); + if (!isRight) { + var w = 0; + BI.each(o.columnSize, function (i, col) { + if (!o.freezeCols.contains(i)) { + w += col; } }); - var w = this._calculateWidth(BI.sum(o.columnSize)); - if (w > 1.05) { - w += o.columnSize.length; + if (BI.isNumeric(w) && w > 1) { + w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } - this.tableContainer.element.width(w); } + return (this.bottomRightContainer = BI.createWidget({ + type: "bi.adaptive", + width: this._calculateWidth(w), + items: [table] + })); }, - getColumnSize: function () { - return this.options.columnSize; + _createBottomRightBody: function () { + var body = this.bottomRightBody = this._body(); + body.element.append(this._createCells(this.bottomRightItems, this.columnRight, this.mergeRight, this.bottomRightBodyTds, this.bottomRightBodyItems, this.columnLeft.length)); + return body; }, - getCalculateColumnSize: function () { + _createFreezeTable: function () { var self = this, o = this.options; - var columnSize = []; - if (o.isNeedFreeze === true) { - if (BI.size(this.bottomLeftBodyTds) > 0 || BI.size(this.bottomRightBodyTds) > 0) { - if (!BI.any(this.bottomLeftBodyTds, function (i, tds) { - if (!BI.any(tds, function (i, item) { - if (item.__mergeCols.length > 1) { - return true; - } - })) { - BI.each(tds, function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(tds) - 1) { - width++; - } - columnSize.push(width); - }); - return true; - } - })) { - BI.each(this.bottomLeftBodyTds[0], function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(self.bottomLeftBodyTds[0]) - 1) { - width++; - } - columnSize.push(width); - }); + var isRight = this._isRightFreeze(); + var split = this._split(o.header); + this.topLeftItems = split.left; + this.topRightItems = split.right; + split = this._split(o.items); + this.bottomLeftItems = split.left; + this.bottomRightItems = split.right; + + this.columnLeft = []; + this.columnRight = []; + BI.each(o.columnSize, function (i, size) { + if (o.freezeCols.contains(i)) { + self[isRight ? "columnRight" : "columnLeft"].push(size); + } else { + self[isRight ? "columnLeft" : "columnRight"].push(size); + } + }); + this.mergeLeft = []; + this.mergeRight = []; + BI.each(o.mergeCols, function (i, col) { + if (o.freezeCols.contains(col)) { + self[isRight ? "mergeRight" : "mergeLeft"].push(col); + } else { + self[isRight ? "mergeLeft" : "mergeRight"].push(col); + } + }); + + var topLeft = this._createTopLeft(); + var topRight = this._createTopRight(); + var bottomLeft = this._createBottomLeft(); + var bottomRight = this._createBottomRight(); + + this.scrollTopLeft = BI.createWidget({ + type: "bi.adaptive", + cls: "scroll-top-left", + width: "100%", + height: "100%", + scrollable: false, + items: [topLeft] + }); + this.scrollTopRight = BI.createWidget({ + type: "bi.adaptive", + cls: "scroll-top-right", + width: "100%", + height: "100%", + scrollable: false, + items: [topRight] + }); + this.scrollBottomLeft = BI.createWidget({ + type: "bi.adaptive", + cls: "scroll-bottom-left", + width: "100%", + height: "100%", + scrollable: isRight || null, + scrollx: !isRight, + items: [bottomLeft] + }); + this.scrollBottomRight = BI.createWidget({ + type: "bi.adaptive", + cls: "scroll-bottom-right", + width: "100%", + height: "100%", + scrollable: !isRight || null, + scrollx: isRight, + items: [bottomRight] + }); + this.topLeft = BI.createWidget({ + type: "bi.adaptive", + cls: "top-left", + scrollable: false, + items: [this.scrollTopLeft] + }); + this.topRight = BI.createWidget({ + type: "bi.adaptive", + cls: "top-right", + scrollable: false, + items: [this.scrollTopRight] + }); + this.bottomLeft = BI.createWidget({ + type: "bi.adaptive", + cls: "bottom-left", + // scrollable: false, + items: [this.scrollBottomLeft] + }); + this.bottomRight = BI.createWidget({ + type: "bi.adaptive", + cls: "bottom-right", + scrollable: false, + items: [this.scrollBottomRight] + }); + + var headerHeight = o.header.length * ((o.headerRowSize || o.rowSize) + 1) + 1; + var leftWidth = BI.sum(o.freezeCols, function (i, col) { + return o.columnSize[col] > 1 ? o.columnSize[col] + 1 : o.columnSize[col]; + }); + + if (o.isNeedResize) { + var resizer; + var createResizer = function (size, position) { + var rowSize = self.getCalculateRegionRowSize(); + resizer = BI.createWidget({ + type: "bi.layout", + cls: "bi-resizer", + width: size.width, + height: rowSize[0] + rowSize[1] + }); + BI.createWidget({ + type: "bi.absolute", + element: "body", + items: [{ + el: resizer, + left: position.left, + top: position.top - rowSize[0] + }] + }); + }; + var resizeResizer = function (size, position) { + var rowSize = self.getCalculateRegionRowSize(); + var columnSize = self.getCalculateRegionColumnSize(); + var height = rowSize[0] + rowSize[1]; + var sumSize = columnSize[0] + columnSize[1]; + if (size.width > sumSize / 5 * 4) { + size.width = sumSize / 5 * 4; } - if (!BI.any(this.bottomRightBodyTds, function (i, tds) { - if (!BI.any(tds, function (i, item) { - if (item.__mergeCols.length > 1) { - return true; - } - })) { - BI.each(tds, function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(tds) - 1) { - width++; - } - columnSize.push(width); - }); - return true; - } - })) { - BI.each(this.bottomRightBodyTds[0], function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(self.bottomRightBodyTds[0]) - 1) { - width++; - } - columnSize.push(width); - }); + if (size.width < 10) { + size.width = 10; } - return columnSize; - } - if (!BI.any(this.topLeftBodyTds, function (i, tds) { - if (!BI.any(tds, function (i, item) { - if (item.__mergeCols.length > 1) { - return true; - } - })) { - BI.each(tds, function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(tds) - 1) { - width++; - } - columnSize.push(width); - }); - return true; - } - })) { - BI.each(this.topLeftBodyTds[BI.size(this.topLeftBodyTds) - 1], function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(self.topLeftBodyTds[BI.size(self.topLeftBodyTds) - 1]) - 1) { - width++; - } - columnSize.push(width); + resizer.element.css({ + "left": position.left + "px", + "width": size.width + "px", + "height": height + "px" }); - } - if (!BI.any(this.topRightBodyTds, function (i, tds) { - if (!BI.any(tds, function (i, item) { - if (item.__mergeCols.length > 1) { - return true; + }; + var stopResizer = function () { + resizer && resizer.destroy(); + resizer = null; + }; + var handle; + if (o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { + if (isRight) { + var options = { + handles: "w", + minWidth: 15, + helper: "clone", + start: function (event, ui) { + createResizer(ui.size, ui.position); + self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE); + }, + resize: function (e, ui) { + resizeResizer(ui.size, ui.position); + self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE); + e.stopPropagation(); + //return false; + }, + stop: function (e, ui) { + stopResizer(); + if (o.isResizeAdapt) { + var increment = ui.size.width - (BI.sum(self.columnRight) + self.columnRight.length); + o.columnSize[self.columnLeft.length] += increment; + } else { + self.setRegionColumnSize(["fill", ui.size.width]); } - })) { - BI.each(tds, function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(tds) - 1) { - width++; + self._resize(); + ui.element.css("left", ""); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); + } + }; + self.bottomRight.element.resizable(options); + handle = $(".ui-resizable-handle", this.bottomRight.element).css("top", -1 * headerHeight); + } else { + var options = { + handles: "e", + minWidth: 15, + helper: "clone", + start: function (event, ui) { + createResizer(ui.size, ui.position); + self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE); + }, + resize: function (e, ui) { + resizeResizer(ui.size, ui.position); + self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE); + e.stopPropagation(); + //return false; + }, + stop: function (e, ui) { + stopResizer(); + if (o.isResizeAdapt) { + var increment = ui.size.width - (BI.sum(self.columnLeft) + self.columnLeft.length); + o.columnSize[self.columnLeft.length - 1] += increment; + } else { + self.setRegionColumnSize([ui.size.width, "fill"]); } - columnSize.push(width); - }); - return true; - } - })) { - BI.each(this.topRightBodyTds[BI.size(this.topRightBodyTds) - 1], function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(self.topRightBodyTds[BI.size(self.topRightBodyTds) - 1]) - 1) { - width++; - } - columnSize.push(width); - }); - } - } else { - BI.each(this.headerTds[BI.size(this.headerTds) - 1], function (i, item) { - var width = item.width() / item.__mergeCols.length; - if (i == BI.size(self.headerTds[BI.size(self.headerTds) - 1]) - 1) { - width++; + self._resize(); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); + } + }; + self.bottomLeft.element.resizable(options); + handle = $(".ui-resizable-handle", this.bottomLeft.element).css("top", -1 * headerHeight); } - columnSize.push(width); - }); + } } - return columnSize; - }, - - setHeaderColumnSize: function (columnSize) { - var self = this, o = this.options; - var isRight = this._isRightFreeze(); - if (o.isNeedFreeze) { - var columnLeft = []; - var columnRight = []; - BI.each(columnSize, function (i, size) { - if (o.freezeCols.contains(i)) { - isRight ? columnRight.push(size) : columnLeft.push(size); + this._resize = function () { + if (self.scrollBottomLeft.element.is(":visible")) { + self.scrollBottomLeft.element.css({"overflow-x": "auto"}); + self.scrollBottomRight.element.css({"overflow-x": "auto"}); + self.setColumnSize(o.columnSize); + if (isRight) { + self.scrollBottomLeft.element.css({"overflow-y": "auto"}); } else { - isRight ? columnLeft.push(size) : columnRight.push(size); + self.scrollBottomRight.element.css({"overflow-y": "auto"}); } - }); - var topleft = 0, topright = 1; - var run = function (direction) { - var colgroupTds, bodyTds, bodyItems, sizes; - switch (direction) { - case topleft: - colgroupTds = self.topLeftColGroupTds; - bodyTds = self.topLeftBodyTds; - bodyItems = self.topLeftBodyItems; - sizes = columnLeft; - break; - case topright: - colgroupTds = self.topRightColGroupTds; - bodyTds = self.topRightBodyTds; - bodyItems = self.topRightBodyItems; - sizes = columnRight; - break; + if (self.scrollBottomLeft.element.hasHorizonScroll() || self.scrollBottomRight.element.hasHorizonScroll()) { + self.scrollBottomLeft.element.css("overflow-x", "scroll"); + self.scrollBottomRight.element.css("overflow-x", "scroll"); } - BI.each(colgroupTds, function (i, colgroup) { - var width = colgroup.attr("width") | 0; - if (width !== sizes[i]) { - var w = self._calculateWidth(sizes[i]); - colgroup.attr("width", w).css("width", w); - BI.each(bodyTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(sizes, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].attr("width", wid).css("width", wid); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(bodyItems, function (j, items) { - if (items[i]) { - if (bodyTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(sizes, function (t, s) { - if (bodyTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += bodyTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } - } - }); - } - }) - }; - run(topleft); - run(topright); - - var lw = 0, rw = 0; - BI.each(columnSize, function (i, size) { - if (o.freezeCols.contains(i)) { - lw += size; + if (self.scrollBottomRight.element.hasVerticalScroll()) { + self.scrollTopRight.element.css("overflow-y", "scroll"); } else { - rw += size; + self.scrollTopRight.element.css("overflow-y", "hidden"); } - }); - lw = this._calculateWidth(lw); - rw = this._calculateWidth(rw); + if (self.scrollBottomLeft.element.hasVerticalScroll()) { + self.scrollTopLeft.element.css("overflow-y", "scroll"); + } else { + self.scrollTopLeft.element.css("overflow-y", "hidden"); + } + self.scrollTopLeft.element[0].scrollLeft = self.scrollBottomLeft.element[0].scrollLeft; + self.scrollTopRight.element[0].scrollLeft = self.scrollBottomRight.element[0].scrollLeft; + self.scrollBottomLeft.element[0].scrollTop = self.scrollBottomRight.element[0].scrollTop; + //调整拖拽handle的高度 + if (o.isNeedResize) { + handle && handle.css("height", self.bottomLeft.element.height() + headerHeight); + } + } + }; + + var regionColumnSize = o.regionColumnSize; + if (o.freezeCols.length === 0) { + regionColumnSize = isRight ? ['fill', 0] : [0, 'fill']; + } else if (o.freezeCols.length >= o.columnSize.length) { + regionColumnSize = isRight ? [0, 'fill'] : ['fill', 0]; + } + this.partitions = BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { + rows: 2, + columns: 2, + columnSize: regionColumnSize || (isRight ? ['fill', leftWidth] : [leftWidth, 'fill']), + rowSize: [headerHeight, 'fill'], + items: [[{ + el: this.topLeft + }, { + el: this.topRight + }], [{ + el: this.bottomLeft + }, { + el: this.bottomRight + }]] + })))); - if (BI.isNumeric(lw)) { - lw = BI.parseFloat(lw) + o.freezeCols.length; - } - if (BI.isNumeric(rw)) { - rw = BI.parseFloat(rw) + columnSize.length - o.freezeCols.length; + //var scrollElement = isRight ? scrollBottomLeft.element : scrollBottomRight.element; + //var scrollTopElement = isRight ? scrollTopLeft.element : scrollTopRight.element; + //var otherElement = isRight ? scrollBottomRight.element : scrollBottomLeft.element; + + this._initFreezeScroll(); + BI.nextTick(function () { + if (self.element.is(":visible")) { + self._resize(); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); } - this.topLeftContainer.element.width(isRight ? rw : lw); - this.topRightContainer.element.width(isRight ? lw : rw); - this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; - this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; - if (o.isNeedResize && o.isResizeAdapt) { - var leftWidth = BI.sum(o.freezeCols, function (i, col) { - return columnSize[col] > 1 ? columnSize[col] + 1 : columnSize[col]; - }); - this.partitions.attr("columnSize", isRight ? ['fill', leftWidth] : [leftWidth, 'fill']); - this.partitions.resize(); + }); + BI.Resizers.add(this.getName(), function (e) { + if (BI.isWindow(e.target) && self.element.is(":visible")) { + self._resize(); + self.fireEvent(BI.Table.EVENT_TABLE_RESIZE); } - } else { - BI.each(this.colgroupTds, function (i, colgroup) { - var width = colgroup.attr("width") | 0; - if (width !== columnSize[i]) { - var w = self._calculateWidth(columnSize[i]); - colgroup.attr("width", w).css("width", w); - BI.each(self.headerTds, function (j, items) { - if (items[i]) { - if (items[i].__mergeCols.length > 1) { - var wid = 0; - BI.each(columnSize, function (t, s) { - if (items[i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += items[i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].attr("width", "").css("width", ""); - } - } else { - if (i == BI.size(items) - 1) { - items[i].attr("width", w - 1).css("width", w - 1); - } else { - items[i].attr("width", w).css("width", w); - } - } - } - }); - BI.each(self.headerItems, function (j, items) { - if (items[i]) { - if (self.headerTds[j][i].__mergeCols.length > 1) { - var wid = 0; - BI.each(columnSize, function (t, s) { - if (self.headerTds[j][i].__mergeCols.contains(t)) { - wid += s; - } - }); - wid = self._calculateWidth(wid); - if (wid > 1) { - wid += self.headerTds[j][i].__mergeCols.length - 1; - } - if (BI.isNumeric(wid)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", wid - 1).css("width", wid - 1); - } else { - items[i].element.attr("width", wid).css("width", wid); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } else { - if (BI.isNumeric(w)) { - if (i == BI.size(items) - 1) { - items[i].element.attr("width", w - 1).css("width", w - 1); - } else { - items[i].element.attr("width", w).css("width", w); - } - } else { - items[i].element.attr("width", "").css("width", ""); - } - } + }); + }, + + _initFreezeScroll: function () { + var self = this, o = this.options; + scroll(this.scrollBottomRight.element, this.scrollTopRight.element, this.scrollBottomLeft.element); + scroll(this.scrollBottomLeft.element, this.scrollTopLeft.element, this.scrollBottomRight.element); + + function scroll(scrollElement, scrollTopElement, otherElement) { + var scrolling, scrollingX; + var fn = function (event, delta, deltaX, deltaY) { + var inf = self._getScrollOffsetAndDur(event); + if (deltaY < 0 || deltaY > 0) { + if (scrolling) { + scrollElement[0].scrollTop = scrolling; + } + scrolling = scrollElement[0].scrollTop - delta * inf.offset; + var stopPropagation = false; + var st = scrollElement[0].scrollTop; + scrollElement[0].scrollTop = scrolling; + if (scrollElement[0].scrollTop !== st) { + stopPropagation = true; + } + scrollElement[0].scrollTop = st; + self._animateScrollTo(scrollElement, scrollElement[0].scrollTop, scrolling, inf.dur, "linear", { + onStart: function () { + }, + onUpdate: function (top) { + otherElement[0].scrollTop = top; + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, top); + }, + onComplete: function () { + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrolling); + scrolling = null; } }); + + + //otherElement[0].scrollTop = scrollTop; + //scrollElement[0].scrollTop = scrollTop; + //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); + if (stopPropagation === true) { + event.stopPropagation(); + return false; + } + return; + } + //if (deltaX < 0 || deltaX > 0) { + // if (scrollingX) { + // scrollElement[0].scrollLeft = scrollingX; + // } + // scrollingX = scrollElement[0].scrollLeft + delta * inf.offset; + // var stopPropagation = false; + // var sl = scrollElement[0].scrollLeft; + // scrollElement[0].scrollLeft = scrollingX; + // if (scrollElement[0].scrollLeft !== sl) { + // stopPropagation = true; + // } + // scrollElement[0].scrollLeft = sl; + // self._animateScrollTo(scrollElement, scrollElement[0].scrollLeft, scrollingX, inf.dur, "linear", { + // direction: "left", + // onStart: function () { + // }, + // onUpdate: function (left) { + // scrollTopElement[0].scrollLeft = left; + // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, null, left); + // }, + // onComplete: function () { + // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, null, scrollingX); + // scrollingX = null; + // } + // }); + // + // + // //otherElement[0].scrollTop = scrollTop; + // //scrollElement[0].scrollTop = scrollTop; + // //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); + // if (stopPropagation === true) { + // event.stopPropagation(); + // return false; + // } + //} + }; + scrollElement.mousewheel(fn); + var scrollTop = 0, scrollLeft = 0; + scrollElement.scroll(function (e) { + var change = false; + if (scrollElement.scrollTop() != scrollTop) { + var old = otherElement.scrollTop(); + otherElement.scrollTop(scrollElement.scrollTop()); + scrollTop = scrollElement.scrollTop(); + if (Math.abs(old - otherElement[0].scrollTop) > 0.1) { + e.stopPropagation(); + change = true; + } + } + if (scrollElement.scrollLeft() != scrollLeft) { + var old = scrollTopElement.scrollLeft(); + scrollTopElement.scrollLeft(scrollElement.scrollLeft()); + scrollLeft = scrollElement.scrollLeft(); + if (Math.abs(old - scrollTopElement[0].scrollLeft) > 0.1) { + e.stopPropagation(); + change = true; + } + } + // self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); + if (change === true) { + e.stopPropagation(); + //return false; } }); - var cW = this._calculateWidth(BI.sum(columnSize)); - if (cW > 1.05) { - cW = cW + columnSize.length; - } - this.tableContainer.element.width(cW); } }, - setRegionColumnSize: function (columnSize) { - var self = this, o = this.options; - o.regionColumnSize = columnSize; - if (o.freezeCols.length === 0) { - if (o.isNeedFreeze) { - this.partitions.attr("columnSize", this._isRightFreeze() ? ['fill', 0] : [0, 'fill']); - this.partitions.resize(); - } else { - this.tableContainer.element.width(columnSize[0]); + _animateScrollTo: function (el, from, to, duration, easing, op) { + var self = this; + var onStart = op.onStart, onComplete = op.onComplete, onUpdate = op.onUpdate; + var startTime = BI.getTime(), _delay, progress = 0, _request; + _cancelTween(); + _startTween(); + var diff = to - from; + el._stop = 0; + function _step() { + if (el._stop) { + return; } - } else if (o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { - if (o.isNeedFreeze) { - this.partitions.attr("columnSize", columnSize); - this.partitions.resize(); - } else { - this.tableContainer.element.width(columnSize[0]); + if (!progress) { + onStart.call(); } - } else { - if (o.isNeedFreeze) { - this.partitions.attr("columnSize", this._isRightFreeze() ? [0, 'fill'] : ['fill', 0]); - this.partitions.resize(); + progress = BI.getTime() - startTime; + _tween(); + if (progress >= el.time) { + el.time = (progress > el.time) ? progress + _delay - (progress - el.time) : progress + _delay - 1; + if (el.time < progress + 1) { + el.time = progress + 1; + } + } + if (el.time < duration) { + el._id = _request(_step); } else { - this.tableContainer.element.width(columnSize[0]); + el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](to); + onComplete.call(); } } - }, - - getRegionColumnSize: function () { - return this.options.regionColumnSize; - }, - - getCalculateRegionColumnSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - return [this.scrollBottomLeft.element.width(), this.scrollBottomRight.element.width()]; - } - return [this.scrollBottomRight.element.width()]; - }, - getCalculateRegionRowSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - return [this.scrollTopRight.element.height(), this.scrollBottomRight.element.height()]; + function _tween() { + var top = to; + if (duration > 0) { + el.currVal = _ease(el.time, from, diff, duration, easing); + el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](top = Math.round(el.currVal)); + } else { + el[op.direction == 'left' ? "scrollLeft" : "scrollTop"](to); + } + onUpdate(top); } - return [this.scrollBottomRight.element.height()]; - }, - getClientRegionColumnSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - return [this.scrollBottomLeft.element[0].clientWidth, this.scrollBottomRight.element[0].clientWidth]; + function _startTween() { + _delay = 1000 / 60; + el.time = progress + _delay; + _request = (!requestAnimationFrame()) ? function (f) { + _tween(); + return setTimeout(f, 0.01); + } : requestAnimationFrame(); + el._id = _request(_step); } - return [this.scrollBottomRight.element[0].clientWidth]; - }, - getClientRegionRowSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - return [this.scrollBottomLeft.element[0].clientHeight, this.scrollBottomRight.element[0].clientHeight]; + function requestAnimationFrame() { + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.msRequestAnimationFrame || + window.oRequestAnimationFrame; } - return [this.scrollBottomRight.element[0].clientHeight]; - }, - getScrollRegionColumnSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - return [this.scrollBottomLeft.element[0].scrollWidth, this.scrollBottomRight.element[0].scrollWidth]; + function cancelAnimationFrame() { + return window.cancelAnimationFrame || + window.webkitCancelAnimationFrame || + window.mozCancelAnimationFrame || + window.msCancelAnimationFrame || + window.oCancelAnimationFrame || + window.cancelRequestAnimationFrame || + window.webkitCancelRequestAnimationFrame || + window.mozCancelRequestAnimationFrame || + window.msCancelRequestAnimationFrame || + window.oCancelRequestAnimationFrame } - return [this.scrollBottomRight.element[0].scrollWidth]; - }, - getScrollRegionRowSize: function () { - var o = this.options; - if (o.isNeedFreeze) { - if (o.freezeCols.length < o.columnSize.length) { - return [this.scrollTopRight.element[0].scrollHeight, this.scrollBottomRight.element[0].scrollHeight]; + function _cancelTween() { + if (el._id == null) { + return; + } + if (!cancelAnimationFrame()) { + clearTimeout(el._id); } else { - return [this.scrollTopLeft.element[0].scrollHeight, this.scrollBottomLeft.element[0].scrollHeight]; + cancelAnimationFrame()(el._id); } + el._id = null; } - return [this.scrollBottomRight.element[0].scrollHeight]; - }, - hasVerticalScroll: function () { - var o = this.options; - if (o.isNeedFreeze) { - return this.scrollBottomRight.element.hasVerticalScroll() || this.scrollBottomLeft.element.hasVerticalScroll(); + function _ease(t, b, c, d, type) { + switch (type) { + case "linear": + return c * t / d + b; + break; + case "mcsLinearOut": + t /= d; + t--; + return c * Math.sqrt(1 - t * t) + b; + break; + case "easeInOutSmooth": + t /= d / 2; + if (t < 1) { + return c / 2 * t * t + b; + } + t--; + return -c / 2 * (t * (t - 2) - 1) + b; + break; + case "easeInOutStrong": + t /= d / 2; + if (t < 1) { + return c / 2 * Math.pow(2, 10 * (t - 1)) + b; + } + t--; + return c / 2 * ( -Math.pow(2, -10 * t) + 2 ) + b; + break; + case "easeInOut": + case "mcsEaseInOut": + t /= d / 2; + if (t < 1) { + return c / 2 * t * t * t + b; + } + t -= 2; + return c / 2 * (t * t * t + 2) + b; + break; + case "easeOutSmooth": + t /= d; + t--; + return -c * (t * t * t * t - 1) + b; + break; + case "easeOutStrong": + return c * ( -Math.pow(2, -10 * t / d) + 1 ) + b; + break; + case "easeOut": + case "mcsEaseOut": + default: + var ts = (t /= d) * t, tc = ts * t; + return b + c * (0.499999999999997 * tc * ts + -2.5 * ts * ts + 5.5 * tc + -6.5 * ts + 4 * t); + } } - return this.scrollBottomRight.element.hasVerticalScroll(); }, - setVerticalScroll: function (scrollTop) { - var o = this.options; - if (o.isNeedFreeze) { - if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { - this.scrollBottomRight.element[0].scrollTop = scrollTop; - } - if (this.scrollBottomLeft.element[0].scrollTop !== scrollTop) { - this.scrollBottomLeft.element[0].scrollTop = scrollTop; - } - } else { - if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { - this.scrollBottomRight.element[0].scrollTop = scrollTop; - } + _getScrollOffsetAndDur: function (event) { + var offset = 40, dur = 200; + if (event.originalEvent.wheelDelta) { + offset = Math.abs(event.originalEvent.wheelDelta); + } + if (event.deltaFactor < 2) { + offset = 3; + dur = 17; } + return { + offset: offset, + dur: dur + }; }, - setLeftHorizontalScroll: function (scrollLeft) { - var o = this.options; - if (o.isNeedFreeze) { - if (this.scrollBottomLeft.element[0].scrollLeft !== scrollLeft) { - this.scrollBottomLeft.element[0].scrollLeft = scrollLeft; - } - if (this.scrollTopLeft.element[0].scrollLeft !== scrollLeft) { - this.scrollTopLeft.element[0].scrollLeft = scrollLeft; - } - } else { - if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { - this.scrollBottomRight.element[0].scrollLeft = scrollLeft; - } - } + resize: function () { + this._resize(); }, - setRightHorizontalScroll: function (scrollLeft) { - var o = this.options; - if (o.isNeedFreeze) { - if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { - this.scrollBottomRight.element[0].scrollLeft = scrollLeft; - } - if (this.scrollTopRight.element[0].scrollLeft !== scrollLeft) { - this.scrollTopRight.element[0].scrollLeft = scrollLeft; - } - } else { - if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { - this.scrollBottomRight.element[0].scrollLeft = scrollLeft; + _createCells: function (items, columnSize, mergeCols, TDs, Ws, start, rowSize) { + var self = this, o = this.options, preCol = {}, preRow = {}, preRW = {}, preCW = {}, map = {}; + columnSize = columnSize || o.columnSize; + mergeCols = mergeCols || o.mergeCols; + TDs = TDs || {}; + Ws = Ws || {}; + start = start || 0; + rowSize || (rowSize = o.rowSize); + var frag = document.createDocumentFragment(); + BI.each(items, function (i, rows) { + var tr = $("").addClass((i & 1) === 0 ? "odd" : "even"); + BI.each(rows, function (j, row) { + if (!map[i]) { + map[i] = {}; + } + if (!TDs[i]) { + TDs[i] = {}; + } + if (!Ws[i]) { + Ws[i] = {}; + } + map[i][j] = row; + + if (o.isNeedMerge && mergeCols.contains(j)) { + if (i === 0 && j === 0) { + createOneEl(0, 0); + } else if (j === 0 && i > 0) { + var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); + if (isNeedMergeRow === true) { + mergeRow(i, j); + preRow[i] = preCol[j]; + preRW[i] = preCW[j]; + } else { + createOneEl(i, j); + } + } else if (i === 0 && j > 0) { + var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); + if (isNeedMergeCol === true) { + mergeCol(i, j); + preCol[j] = preRow[j - 1]; + preCW[j] = preRW[j - 1]; + } else { + createOneEl(i, j); + } + } else { + var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); + var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); + if (isNeedMergeCol && isNeedMergeRow) { + return; + } + if (isNeedMergeCol) { + mergeCol(i, j); + } + if (isNeedMergeRow) { + mergeRow(i, j); + } + if (!isNeedMergeCol && !isNeedMergeRow) { + createOneEl(i, j); + } + } + } else { + createOneEl(i, j); + } + }); + function mergeRow(i, j) { + var height = (preCol[j].attr("height") | 0) + rowSize + 1; + preCol[j].attr("height", height).css("height", height); + //preCW[j].element.css("height", height); + var rowspan = ((preCol[j].attr("rowspan") || 1) | 0) + 1; + preCol[j].attr("rowspan", rowspan); + preCol[j].__mergeRows.pushDistinct(i); + TDs[i][j] = preCol[j]; + Ws[i][j] = preCW[j]; } - } - }, - - getVerticalScroll: function () { - var o = this.options; - if (o.isNeedFreeze) { - return this.scrollBottomRight.element[0].scrollTop || this.scrollBottomLeft.element[0].scrollTop; - } - return this.scrollBottomRight.element[0].scrollTop; - }, - - getLeftHorizontalScroll: function () { - var o = this.options; - if (o.isNeedFreeze) { - return this.scrollBottomLeft.element[0].scrollLeft; - } - return this.scrollBottomRight.element[0].scrollLeft; - }, - - getRightHorizontalScroll: function () { - var o = this.options; - if (o.isNeedFreeze) { - return this.scrollBottomRight.element[0].scrollLeft; - } - return this.scrollBottomRight.element[0].scrollLeft; - }, - getColumns: function () { - var o = this.options; - if (o.isNeedFreeze) { - return { - topLeft: this.topLeftBodyItems, - topRight: this.topRightBodyItems, - bottomLeft: this.bottomLeftBodyItems, - bottomRight: this.bottomRightBodyItems - } - } else { - return { - header: this.headerItems, - body: this.bodyItems, - footer: this.footerItems + function mergeCol(i, j) { + if (columnSize[j]) { + var width = preRow[i].attr("width") | 0; + if (width > 1.05 && columnSize[j]) { + width = width + columnSize[j] + 1; + if (j === columnSize.length - 1) { + width--; + } + } else { + width = width + columnSize[j] + } + width = self._calculateWidth(width); + preRow[i].attr("width", width).css("width", width); + preRW[i].element.width(width); + } + var colspan = ((preRow[i].attr("colspan") || 1) | 0) + 1; + preRow[i].attr("colspan", colspan); + preRow[i].__mergeCols.pushDistinct(j); + TDs[i][j] = preRow[i]; + Ws[i][j] = preRW[i]; } - } - }, - populate: function (items, header) { - this.options.items = items || []; - if (header) { - this.options.header = header; - } - this.empty(); - if (this.options.isNeedFreeze) { - this._createFreezeTable(); - } else { - this._createNormalTable(); - } - }, + function createOneEl(r, c) { + var width = self._calculateWidth(columnSize[c]); + if (width > 1.05 && c === columnSize.length - 1) { + width--; + } + var height = self._calculateHeight(rowSize); + var td = $("").attr("height", height) + .attr("width", width).css({"width": width, "height": height, "position": "relative"}) + .addClass((c & 1) === 0 ? "odd-col" : "even-col") + .addClass(r === 0 ? "first-row" : "") + .addClass(c === 0 ? "first-col" : "") + .addClass(c === rows.length - 1 ? "last-col" : ""); + var w = BI.createWidget(map[r][c], { + type: "bi.table_cell", + textAlign: "left", + width: BI.isNumeric(width) ? width : "", + height: BI.isNumeric(height) ? height : "", + _row: r, + _col: c + start + }); + w.element.css("position", "relative"); + td.append(w.element); + tr.append(td); + preCol[c] = td; + preCol[c].__mergeRows = [r]; + preCW[c] = w; + preRow[r] = td; + preRow[r].__mergeCols = [c]; + preRW[r] = w; + TDs[r][c] = td; + Ws[r][c] = w; + } - empty: function () { - BI.Resizers.remove(this.getName()); - BI.Table.superclass.empty.apply(this, arguments); + frag.appendChild(tr[0]); + }); + return frag; }, - destroy: function () { - BI.Table.superclass.destroy.apply(this, arguments); - } -}) -; -BI.Table.EVENT_TABLE_AFTER_INIT = "EVENT_TABLE_AFTER_INIT"; -BI.Table.EVENT_TABLE_RESIZE = "EVENT_TABLE_RESIZE"; -BI.Table.EVENT_TABLE_SCROLL = "EVENT_TABLE_SCROLL"; -BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE = "EVENT_TABLE_BEFORE_COLUMN_RESIZE"; -BI.Table.EVENT_TABLE_COLUMN_RESIZE = "EVENT_TABLE_COLUMN_RESIZE"; -BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE = "EVENT_TABLE_AFTER_COLUMN_RESIZE"; - -BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE = "EVENT_TABLE_BEFORE_REGION_RESIZE"; -BI.Table.EVENT_TABLE_REGION_RESIZE = "EVENT_TABLE_REGION_RESIZE"; -BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE = "EVENT_TABLE_AFTER_REGION_RESIZE"; -$.shortcut("bi.table_view", BI.Table); -/** - * - * 表格单元格 - * - * Created by GUY on 2016/1/12. - * @class BI.ResizableTableCell - * @extends BI.Widget - */ -BI.ResizableTableCell = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ResizableTableCell.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-resizable-table-cell", - cell: {}, - start: BI.emptyFn, - resize: BI.emptyFn, - stop: BI.emptyFn - }) + _createColGroupCells: function (columnSize, store) { + var self = this, o = this.options; + columnSize = columnSize || o.columnSize; + store = store || {}; + var frag = document.createDocumentFragment(); + BI.each(columnSize, function (i, size) { + var width = self._calculateWidth(size); + var col = $("").attr("width", width).css("width", width); + store[i] = col; + frag.appendChild(col[0]); + }); + return frag; }, - _init: function () { - BI.ResizableTableCell.superclass._init.apply(this, arguments); + _createHeaderCells: function (items, columnSize, mergeCols, TDs, Ws, start) { var self = this, o = this.options; - this.cell = BI.createWidget(BI.extend({type: "bi.label"}, o.cell, {width: o.width, height: o.height})); + start || (start = 0); + var frag = this._createCells(items, columnSize, BI.range(o.columnSize.length), TDs, Ws, start, o.headerRowSize || o.rowSize); - var startDrag = false; - var size = 0, offset = 0, defaultSize = o.width; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { - if (mouseMoveTracker.isDragging()) { - startDrag = true; - offset += deltaX; - size = BI.clamp(defaultSize + offset, 15, Number.MAX_VALUE); - self.handler.element.addClass("dragging"); - o.resize(size); - } - }, function () { - if (startDrag === true) { - size = BI.clamp(size, 15, Number.MAX_VALUE); - o.stop(size); - size = 0; - offset = 0; - defaultSize = o.width; - self.handler.element.removeClass("dragging"); - startDrag = false; - } - mouseMoveTracker.releaseMouseMoves(); - }, document); - this.handler = BI.createWidget({ - type: "bi.absolute", - cls: "resizable-table-cell-resizer-container", - width: 6, - items: [{ - el: { - type: "bi.layout", - cls: "resizable-table-cell-resizer-knob", - width: 4 - }, - right: 0, - top: 0, - bottom: 0 - }] - }); - this.handler.element.on("mousedown", function (event) { - defaultSize = o.width; - mouseMoveTracker.captureMouseMoves(event); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.cell, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: this.handler, - right: 0, - top: 0, - bottom: 0 - }] - }) + if (o.isNeedResize === true) { + var tds = TDs[BI.size(TDs) - 1]; + BI.each(tds, function (j, td) { + j = j | 0; + var resizer; + var getHeight = function (size, position) { + var rowSize = self.getCalculateRegionRowSize(); + if (o.isNeedFreeze === true) { + var tableHeight = self.bottomRightContainer.element.outerHeight(); + return size.height + Math.min(rowSize[1], tableHeight); + } else { + var tableHeight = self.tableContainer.element.outerHeight(); + var offset = self.tableContainer.element.offset(); + var offsetTop = position.top - offset.top; + var height = tableHeight - offsetTop; + height = Math.min(height, rowSize[0] - offsetTop); + return height; + } + }; + if (j < BI.size(tds) - 1) { + td.resizable({ + handles: "e", + minWidth: 15, + helper: "clone", + start: function (event, ui) { + var height = getHeight(ui.size, ui.position); + resizer = BI.createWidget({ + type: "bi.layout", + cls: "bi-resizer", + width: ui.size.width, + height: height + }); + + BI.createWidget({ + type: "bi.absolute", + element: "body", + items: [{ + el: resizer, + left: ui.position.left, + top: ui.position.top + }] + }); + self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE); + }, + resize: function (e, ui) { + var height = getHeight(ui.size, ui.position); + resizer.element.css({"width": ui.size.width + "px", "height": height + "px"}); + //o.columnSize[start + j] = ui.size.width; + //self.setColumnSize(o.columnSize); + self.fireEvent(BI.Table.EVENT_TABLE_COLUMN_RESIZE); + e.stopPropagation(); + //return false; + }, + stop: function (e, ui) { + resizer.destroy(); + resizer = null; + o.columnSize[start + j] = ui.size.width - 1; + self.setColumnSize(o.columnSize); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE); + } + }) + } + }) + } + return frag; }, - setWidth: function (width) { - BI.ResizableTableCell.superclass.setWidth.apply(this, arguments); + _createFooterCells: function (items, columnSize, TDs, Ws) { var o = this.options; - this.cell.setWidth(o.width); + var frag = this._createCells(items, columnSize, [], TDs, Ws, 0); + return frag; }, - setHeight: function (height) { - BI.ResizableTableCell.superclass.setHeight.apply(this, arguments); - var o = this.options; - this.cell.setHeight(o.height); - } -}); -$.shortcut("bi.resizable_table_cell", BI.ResizableTableCell);/** - * - * 可调整列宽的grid表格 - * - * Created by GUY on 2016/1/12. - * @class BI.ResizableTable - * @extends BI.Widget - */ -BI.ResizableTable = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ResizableTable.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-resizable-table", - el: { - type: "bi.grid_table" - }, - isNeedFreeze: false, - isNeedResize: true, - isResizeAdapt: false, - headerRowSize: 25, - rowSize: 25, - isNeedMerge: true,//是否需要合并单元格 - mergeCols: [], - mergeRule: BI.emptyFn, - columnSize: [], - freezeCols: [], - header: [], - items: [], - regionColumnSize: [] - }) + _createColGroup: function (columnSize, store, widgets) { + var self = this, o = this.options; + this.colgroup = this._colgroup(); + this.colgroup.element.append(this._createColGroupCells(columnSize, store, widgets)); + return this.colgroup; }, - _init: function () { - BI.ResizableTable.superclass._init.apply(this, arguments); + _createHeader: function () { var self = this, o = this.options; - this.resizer = BI.createWidget({ - type: "bi.layout", - cls: "resizable-table-resizer", - invisible: true, - width: 2 - }); - this.regionResizerHandler = this._createResizerHandler(); - this.table = BI.createWidget(o.el, { - type: "bi.grid_table", - element: this, - width: o.width, - height: o.height, - headerRowSize: o.headerRowSize, - rowSize: o.rowSize, - columnSize: o.columnSize, + if (o.header === false) { + return; + } + this.header = this._header(); + this.header.element.append(this._createHeaderCells(o.header, null, null, this.headerTds, this.headerItems)); + return this.header; + }, - isNeedFreeze: o.isNeedFreeze, - freezeCols: o.freezeCols, - isNeedMerge: o.isNeedMerge, - mergeCols: o.mergeCols, - mergeRule: BI.bind(this._mergeRule, this), + _createFooter: function (columnSize, store, widgets) { + var self = this, o = this.options; + if (o.footer === false) { + return; + } + this.footer = this._footer(); + this.footer.element.append(this._createFooterCells(o.footer, null, this.footerTds, this.footerItems)); + return this.footer; + }, - header: this._formatHeader(o.header), - items: o.items, - regionColumnSize: o.regionColumnSize + _createBody: function () { + var self = this, o = this.options; + this.body = this._body(); + this.body.element.append(this._createCells(o.items, null, null, this.bodyTds, this.bodyItems)); + return this.body; + }, + + _createNormalTable: function () { + var self = this, o = this.options, table = this._table(); + this.colgroupTds = {}; + this.headerTds = {}; + this.footerTds = {}; + this.bodyTds = {}; + + this.headerItems = {}; + this.footerItems = {}; + this.bodyItems = {}; + var colgroup = this._createColGroup(null, this.colgroupTds); + var header = this._createHeader(); + var footer = this._createFooter(); + var body = this._createBody(); + + BI.createWidget({ + type: "bi.adaptive", + element: table, + items: [colgroup, header, footer, body] }); - this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { - self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); + + var w = BI.sum(this.options.columnSize) || undefined; + w = this._calculateWidth(w); + if (BI.isNumeric(w) && w > 1) { + w += o.columnSize.length; + } + this.tableContainer = BI.createWidget({ + type: "bi.adaptive", + width: this._calculateWidth(w), + items: [table] + }); + + this.scrollBottomRight = BI.createWidget({ + type: "bi.adaptive", + width: "100%", + height: "100%", + cls: "scroll-bottom-right", + scrollable: true, + items: [this.tableContainer] }); + BI.createWidget({ - type: "bi.absolute", + type: "bi.adaptive", + cls: "bottom-right", element: this, - items: [{ - el: this.regionResizerHandler, - left: 0, - top: 0, - bottom: 0 - }, { - el: this.resizer, - left: 0, - top: 0 - }] + scrollable: false, + items: [this.scrollBottomRight] + }); + + this._resize = function () { + if (self.element.is(":visible")) { + self.setColumnSize(o.columnSize); + } + }; + + this._initNormalScroll(); + BI.Resizers.add(this.getName(), function (e) { + if (self.element.is(":visible") && BI.isWindow(e.target)) { + self._resize(); + self.fireEvent(BI.Table.EVENT_TABLE_RESIZE); + } + }); + BI.nextTick(function () { + if (self.element.is(":visible")) { + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); + } + }); + }, + + _initNormalScroll: function () { + var self = this; + var scrolling, scrollX; + this.scrollBottomRight.element.mousewheel(function (event, delta, deltaX, deltaY) { + var inf = self._getScrollOffsetAndDur(event); + if (deltaY < 0 || deltaY > 0) { + var ele = self.scrollBottomRight.element; + if (scrolling) { + ele[0].scrollTop = scrolling; + } + + scrolling = ele[0].scrollTop - delta * inf.offset; + var stopPropagation = false; + var st = ele[0].scrollTop; + ele[0].scrollTop = scrolling; + if (ele[0].scrollTop !== st) { + stopPropagation = true; + } + ele[0].scrollTop = st; + self._animateScrollTo(ele, ele[0].scrollTop, scrolling, inf.dur, "linear", { + onStart: function () { + }, + onUpdate: function (top) { + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, top); + }, + onComplete: function () { + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrolling); + scrolling = null; + } + }); + //var scrollTop = self.scrollBottomRight.element[0].scrollTop = self.scrollBottomRight.element[0].scrollTop - delta * offset; + //self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, scrollTop); + if (stopPropagation === true) { + event.stopPropagation(); + return false; + } + } + }); + var scrollTop = 0, scrollLeft = 0; + this.scrollBottomRight.element.scroll(function (e) { + var change = false; + var scrollElement = self.scrollBottomRight.element; + if (scrollElement.scrollTop() != scrollTop) { + if (Math.abs(scrollElement.scrollTop() - scrollTop) > 0.1) { + e.stopPropagation(); + change = true; + } + scrollTop = scrollElement.scrollTop(); + } + if (scrollElement.scrollLeft() != scrollLeft) { + if (Math.abs(scrollElement.scrollLeft() - scrollLeft) > 0.1) { + e.stopPropagation(); + change = true; + } + scrollLeft = scrollElement.scrollLeft(); + } + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); + if (change === true) { + e.stopPropagation(); + //return false; + } + return false; }); - this._populate(); }, - _mergeRule: function (row1, row2) { - var o = this.options; - if (row1.type === "bi.resizable_table_cell") { - row1 = row1.cell; - } - if (row2.type === "bi.resizable_table_cell") { - row2 = row2.cell; + _split: function (items) { + var o = this.options, left = [], right = [], isRight = this._isRightFreeze(); + BI.each(items, function (i, rows) { + left.push([]); + right.push([]); + BI.each(rows, function (j, cell) { + if (o.freezeCols.contains(j)) { + (isRight ? right : left)[i].push(cell); + } else { + (isRight ? left : right)[i].push(cell); + } + }) + }); + return { + left: left, + right: right } - return o.mergeRule(row1, row2); }, - _createResizerHandler: function () { - var self = this, o = this.options; - var regionResizerHandler = BI.createWidget({ - type: "bi.absolute", - cls: "resizable-table-region-resizer", - invisible: true, - width: 6, - items: [{ - el: { - type: "bi.layout", - width: 2, - cls: "resizable-table-region-resizer-knob" - }, - left: 2, - top: 0, - bottom: 0 - }] + _table: function () { + return BI.createWidget({ + type: "bi.layout", + tagName: "table", + cls: "table", + attribute: {"cellspacing": 0, "cellpadding": 0} }); - var size = 0, offset = 0, defaultSize = 0, start = false; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { - if (mouseMoveTracker.isDragging()) { - start = true; - offset += deltaX; - size = BI.clamp(defaultSize + offset, 15, o.width - 15); + }, - self.regionResizerHandler.element.addClass("dragging"); - self._setRegionResizerHandlerPosition(size - 3, 0); - } + _header: function () { + return BI.createWidget({ + type: "bi.layout", + cls: "header", + tagName: "thead" + }); + }, - }, function () { - if (start === true) { - o.regionColumnSize[0] = BI.clamp(size, 15, o.width - 15); - self.table.setRegionColumnSize(o.regionColumnSize); - if (o.isResizeAdapt === true) { - var freezeColumnSize = self._getFreezeColumnSize(); - o.columnSize[self._getFreezeColLength() - 1] += o.regionColumnSize[0] - freezeColumnSize; - self.table.setColumnSize(o.columnSize); - } - self.table.populate(); - self._populate(); - self.regionResizerHandler.element.removeClass("dragging"); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); - start = false; - } - mouseMoveTracker.releaseMouseMoves(); - }, document); - regionResizerHandler.element.on("mousedown", function (event) { - defaultSize = size = self._getRegionSize(); - offset = 0; - self._setResizerPosition(0, 0); - mouseMoveTracker.captureMouseMoves(event); + _footer: function () { + return BI.createWidget({ + type: "bi.layout", + cls: "footer", + tagName: "tfoot" }); - return regionResizerHandler; }, - _setResizerPosition: function (left, top) { - this.resizer.element.css({ - left: left + "px", - top: top + "px" + _body: function () { + return BI.createWidget({ + type: "bi.layout", + tagName: "tbody", + cls: "body" }); }, - _setRegionResizerHandlerPosition: function (left, top) { - this.regionResizerHandler.element.css({ - left: left + "px", - top: top + "px" + _colgroup: function () { + return BI.createWidget({ + type: "bi.layout", + tagName: "colgroup" }); }, - _getRegionSize: function () { - var o = this.options; - var regionSize = o.regionColumnSize[0] || 0; - if (o.isNeedFreeze === false || o.freezeCols.length === 0) { - return 0; - } - if (!regionSize) { - BI.each(o.freezeCols, function (i, col) { - regionSize += o.columnSize[col]; + _init: function () { + BI.Table.superclass._init.apply(this, arguments); + + this.populate(this.options.items); + }, + + setColumnSize: function (columnSize) { + var self = this, o = this.options; + var isRight = this._isRightFreeze(); + o.columnSize = columnSize || []; + if (o.isNeedFreeze) { + var columnLeft = []; + var columnRight = []; + BI.each(o.columnSize, function (i, size) { + if (o.freezeCols.contains(i)) { + isRight ? columnRight.push(size) : columnLeft.push(size); + } else { + isRight ? columnLeft.push(size) : columnRight.push(size); + } + }); + var topleft = 0, topright = 1, bottomleft = 2, bottomright = 3; + var run = function (direction) { + var colgroupTds, bodyTds, bodyItems, sizes; + switch (direction) { + case topleft: + colgroupTds = self.topLeftColGroupTds; + bodyTds = self.topLeftBodyTds; + bodyItems = self.topLeftBodyItems; + sizes = columnLeft; + break; + case topright: + colgroupTds = self.topRightColGroupTds; + bodyTds = self.topRightBodyTds; + bodyItems = self.topRightBodyItems; + sizes = columnRight; + break; + case bottomleft: + colgroupTds = self.bottomLeftColGroupTds; + bodyTds = self.bottomLeftBodyTds; + bodyItems = self.bottomLeftBodyItems; + sizes = columnLeft; + break; + case bottomright: + colgroupTds = self.bottomRightColGroupTds; + bodyTds = self.bottomRightBodyTds; + bodyItems = self.bottomRightBodyItems; + sizes = columnRight; + break; + } + BI.each(colgroupTds, function (i, colgroup) { + var width = colgroup.attr("width") | 0; + if (width !== sizes[i]) { + var w = self._calculateWidth(sizes[i]); + colgroup.attr("width", w).css("width", w); + BI.each(bodyTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(sizes, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].attr("width", wid).css("width", wid); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(bodyItems, function (j, items) { + if (items[i]) { + if (bodyTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(sizes, function (t, s) { + if (bodyTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += bodyTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + } + }) + }; + run(topleft); + run(topright); + run(bottomleft); + run(bottomright); + + var lw = 0, rw = 0; + this.columnLeft = []; + this.columnRight = []; + BI.each(o.columnSize, function (i, size) { + if (o.freezeCols.contains(i)) { + lw += size; + self[isRight ? "columnRight" : "columnLeft"].push(size); + } else { + rw += size; + self[isRight ? "columnLeft" : "columnRight"].push(size); + } }); - } - return regionSize; - }, - - _getRegionRowSize: function () { - var o = this.options; - return [o.header.length * o.headerRowSize, - Math.min(o.height - o.header.length * o.headerRowSize, o.items.length * o.rowSize)]; - }, - - _getFreezeColLength: function () { - return this.options.freezeCols.length; - }, + lw = this._calculateWidth(lw); + rw = this._calculateWidth(rw); - _getFreezeColumnSize: function () { - var columnSize = this.options.columnSize; - var sum = 0; - for (var i = 0, len = this._getFreezeColLength(); i < len; i++) { - sum += columnSize[i]; + if (BI.isNumeric(lw)) { + lw = BI.parseFloat(lw) + o.freezeCols.length; + } + if (BI.isNumeric(rw)) { + rw = BI.parseFloat(rw) + o.columnSize.length - o.freezeCols.length; + } + this.topLeftContainer.element.width(isRight ? rw : lw); + this.bottomLeftContainer.element.width(isRight ? rw : lw); + this.topRightContainer.element.width(isRight ? lw : rw); + this.bottomRightContainer.element.width(isRight ? lw : rw); + this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; + this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; + if (o.isNeedResize && o.isResizeAdapt) { + var leftWidth = BI.sum(o.freezeCols, function (i, col) { + return o.columnSize[col] > 1 ? o.columnSize[col] + 1 : o.columnSize[col]; + }); + this.partitions.attr("columnSize", isRight ? ['fill', leftWidth] : [leftWidth, 'fill']); + this.partitions.resize(); + } + } else { + BI.each(this.colgroupTds, function (i, colgroup) { + var width = colgroup.attr("width") | 0; + if (width !== o.columnSize[i]) { + var w = self._calculateWidth(o.columnSize[i]); + colgroup.attr("width", w).css("width", w); + BI.each(self.bodyTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(self.headerTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(self.footerTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(self.bodyItems, function (j, items) { + if (items[i]) { + if (self.bodyTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (self.bodyTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += self.bodyTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + BI.each(self.headerItems, function (j, items) { + if (items[i]) { + if (self.headerTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (self.headerTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += self.headerTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + BI.each(self.footerItems, function (j, items) { + if (items[i]) { + if (self.footerTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(o.columnSize, function (t, s) { + if (self.footerTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += self.footerTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + } + }); + var w = this._calculateWidth(BI.sum(o.columnSize)); + if (w > 1.05) { + w += o.columnSize.length; + } + this.tableContainer.element.width(w); } - return sum; }, - _getResizerLeft: function (j) { - var left = 0; - var columnSize = this.options.columnSize; - var freezeColLength = this._getFreezeColLength(); - for (var i = (j >= freezeColLength ? freezeColLength : 0); i < j; i++) { - left += columnSize[i] || 0; - } - if (j >= freezeColLength) { - left += this.table.getRegionSize(); - left -= this.table.getRightHorizontalScroll(); - } else { - left -= this.table.getLeftHorizontalScroll(); - } - return left; + getColumnSize: function () { + return this.options.columnSize; }, - _formatHeader: function (header) { + getCalculateColumnSize: function () { var self = this, o = this.options; - var result = []; - var resize = function (j, size) { - self.resizer.setVisible(true); - var height = o.headerRowSize + self._getRegionRowSize()[1]; - self.resizer.setHeight(height); - - self._setResizerPosition(self._getResizerLeft(j) + size, (o.header.length - 1) * o.headerRowSize); - }; - var stop = function (j, size) { - self.resizer.setVisible(false); - o.columnSize[j] = size; - self.table.setColumnSize(o.columnSize); - self.table.populate(); - self._populate(); - self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE); - }; - BI.each(header, function (i, cols) { - if (i === header.length - 1) { - result[i] = []; - BI.each(cols, function (j, col) { - if (j === self._getFreezeColLength() - 1 || j === cols.length - 1) { - result[i][j] = col; - } else { - result[i][j] = { - type: "bi.resizable_table_cell", - cell: col, - resize: BI.bind(resize, null, j), - stop: BI.bind(stop, null, j) - }; - if (o.isNeedMerge) { - var r = i; - while (r > 0 && self._mergeRule(result[r][j], result[r - 1][j])) { - result[r - 1][j] = { - type: "bi.resizable_table_cell", - cell: result[r - 1][j], - resize: BI.bind(resize, null, j), - stop: BI.bind(stop, null, j) - }; - r--; - } + var columnSize = []; + if (o.isNeedFreeze === true) { + if (BI.size(this.bottomLeftBodyTds) > 0 || BI.size(this.bottomRightBodyTds) > 0) { + if (!BI.any(this.bottomLeftBodyTds, function (i, tds) { + if (!BI.any(tds, function (i, item) { + if (item.__mergeCols.length > 1) { + return true; + } + })) { + BI.each(tds, function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(tds) - 1) { + width++; + } + columnSize.push(width); + }); + return true; + } + })) { + BI.each(this.bottomLeftBodyTds[0], function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(self.bottomLeftBodyTds[0]) - 1) { + width++; + } + columnSize.push(width); + }); + } + if (!BI.any(this.bottomRightBodyTds, function (i, tds) { + if (!BI.any(tds, function (i, item) { + if (item.__mergeCols.length > 1) { + return true; + } + })) { + BI.each(tds, function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(tds) - 1) { + width++; + } + columnSize.push(width); + }); + return true; + } + })) { + BI.each(this.bottomRightBodyTds[0], function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(self.bottomRightBodyTds[0]) - 1) { + width++; } + columnSize.push(width); + }); + } + return columnSize; + } + if (!BI.any(this.topLeftBodyTds, function (i, tds) { + if (!BI.any(tds, function (i, item) { + if (item.__mergeCols.length > 1) { + return true; + } + })) { + BI.each(tds, function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(tds) - 1) { + width++; + } + columnSize.push(width); + }); + return true; + } + })) { + BI.each(this.topLeftBodyTds[BI.size(this.topLeftBodyTds) - 1], function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(self.topLeftBodyTds[BI.size(self.topLeftBodyTds) - 1]) - 1) { + width++; } + columnSize.push(width); }); - } else { - result.push(cols); } - }); - return result; - }, - - _populate: function () { - var o = this.options; - var regionSize = this._getRegionSize(); - if (regionSize > 0) { - this.regionResizerHandler.setVisible(true); - this._setRegionResizerHandlerPosition(regionSize - 3, 0); - } else { - this.regionResizerHandler.setVisible(false); - } - }, - - setWidth: function (width) { - BI.ResizableTable.superclass.setWidth.apply(this, arguments); - this.table.setWidth(width) - }, - - setHeight: function (height) { - BI.ResizableTable.superclass.setHeight.apply(this, arguments); - this.table.setHeight(height); - }, - - setVerticalScroll: function (scrollTop) { - this.table.setVerticalScroll(scrollTop); - }, - - setLeftHorizontalScroll: function (scrollLeft) { - this.table.setLeftHorizontalScroll(scrollLeft); - }, - - setRightHorizontalScroll: function (scrollLeft) { - this.table.setRightHorizontalScroll(scrollLeft); - }, - - setColumnSize: function (columnSize) { - this.options.columnSize = columnSize; - this.table.setColumnSize(columnSize); - }, - - getColumnSize: function () { - return this.table.getColumnSize(); - }, - - setRegionColumnSize: function (columnSize) { - this.options.regionColumnSize = columnSize; - this.table.setRegionColumnSize(columnSize); - }, - - getRegionColumnSize: function () { - return this.table.getRegionColumnSize(); - }, - - getVerticalScroll: function () { - return this.table.getVerticalScroll(); - }, - - getLeftHorizontalScroll: function () { - return this.table.getLeftHorizontalScroll(); - }, - - getRightHorizontalScroll: function () { - return this.table.getRightHorizontalScroll(); - }, - - attr: function () { - BI.ResizableTable.superclass.attr.apply(this, arguments); - this.table.attr.apply(this.table, arguments); - }, - - restore: function () { - this.table.restore(); - }, - - populate: function (items, header) { - if (items) { - this.options.items = items; - } - if (header) { - this.options.header = header; - if (this.options.isNeedResize) { - header = this._formatHeader(header); + if (!BI.any(this.topRightBodyTds, function (i, tds) { + if (!BI.any(tds, function (i, item) { + if (item.__mergeCols.length > 1) { + return true; + } + })) { + BI.each(tds, function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(tds) - 1) { + width++; + } + columnSize.push(width); + }); + return true; + } + })) { + BI.each(this.topRightBodyTds[BI.size(this.topRightBodyTds) - 1], function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(self.topRightBodyTds[BI.size(self.topRightBodyTds) - 1]) - 1) { + width++; + } + columnSize.push(width); + }); } + } else { + BI.each(this.headerTds[BI.size(this.headerTds) - 1], function (i, item) { + var width = item.width() / item.__mergeCols.length; + if (i == BI.size(self.headerTds[BI.size(self.headerTds) - 1]) - 1) { + width++; + } + columnSize.push(width); + }); } - this.table.populate(items, header); - this._populate(); - } -}); - -$.shortcut("bi.resizable_table", BI.ResizableTable);/** - * guy - * 异步树 - * @class BI.TreeView - * @extends BI.Pane - */ -BI.TreeView = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.TreeView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree", - paras: {}, - itemsCreator: BI.emptyFn - }) + return columnSize; }, - _init: function () { - BI.TreeView.superclass._init.apply(this, arguments); - this._stop = false; - this.container = BI.createWidget(); + setHeaderColumnSize: function (columnSize) { + var self = this, o = this.options; + var isRight = this._isRightFreeze(); + if (o.isNeedFreeze) { + var columnLeft = []; + var columnRight = []; + BI.each(columnSize, function (i, size) { + if (o.freezeCols.contains(i)) { + isRight ? columnRight.push(size) : columnLeft.push(size); + } else { + isRight ? columnLeft.push(size) : columnRight.push(size); + } + }); + var topleft = 0, topright = 1; + var run = function (direction) { + var colgroupTds, bodyTds, bodyItems, sizes; + switch (direction) { + case topleft: + colgroupTds = self.topLeftColGroupTds; + bodyTds = self.topLeftBodyTds; + bodyItems = self.topLeftBodyItems; + sizes = columnLeft; + break; + case topright: + colgroupTds = self.topRightColGroupTds; + bodyTds = self.topRightBodyTds; + bodyItems = self.topRightBodyItems; + sizes = columnRight; + break; + } + BI.each(colgroupTds, function (i, colgroup) { + var width = colgroup.attr("width") | 0; + if (width !== sizes[i]) { + var w = self._calculateWidth(sizes[i]); + colgroup.attr("width", w).css("width", w); + BI.each(bodyTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(sizes, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].attr("width", wid).css("width", wid); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(bodyItems, function (j, items) { + if (items[i]) { + if (bodyTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(sizes, function (t, s) { + if (bodyTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += bodyTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + } + }) + }; + run(topleft); + run(topright); - this._createTree(); - this.tip = BI.createWidget({ - type: "bi.loading_bar", - invisible: true, - handler: BI.bind(this._loadMore, this) - }); - BI.createWidget({ - type: "bi.vertical", - scrollable: true, - scrolly: false, - element: this, - items: [this.container, this.tip] - }); + var lw = 0, rw = 0; + BI.each(columnSize, function (i, size) { + if (o.freezeCols.contains(i)) { + lw += size; + } else { + rw += size; + } + }); + lw = this._calculateWidth(lw); + rw = this._calculateWidth(rw); + if (BI.isNumeric(lw)) { + lw = BI.parseFloat(lw) + o.freezeCols.length; + } + if (BI.isNumeric(rw)) { + rw = BI.parseFloat(rw) + columnSize.length - o.freezeCols.length; + } + this.topLeftContainer.element.width(isRight ? rw : lw); + this.topRightContainer.element.width(isRight ? lw : rw); + this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; + this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; + if (o.isNeedResize && o.isResizeAdapt) { + var leftWidth = BI.sum(o.freezeCols, function (i, col) { + return columnSize[col] > 1 ? columnSize[col] + 1 : columnSize[col]; + }); + this.partitions.attr("columnSize", isRight ? ['fill', leftWidth] : [leftWidth, 'fill']); + this.partitions.resize(); + } + } else { + BI.each(this.colgroupTds, function (i, colgroup) { + var width = colgroup.attr("width") | 0; + if (width !== columnSize[i]) { + var w = self._calculateWidth(columnSize[i]); + colgroup.attr("width", w).css("width", w); + BI.each(self.headerTds, function (j, items) { + if (items[i]) { + if (items[i].__mergeCols.length > 1) { + var wid = 0; + BI.each(columnSize, function (t, s) { + if (items[i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += items[i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].attr("width", "").css("width", ""); + } + } else { + if (i == BI.size(items) - 1) { + items[i].attr("width", w - 1).css("width", w - 1); + } else { + items[i].attr("width", w).css("width", w); + } + } + } + }); + BI.each(self.headerItems, function (j, items) { + if (items[i]) { + if (self.headerTds[j][i].__mergeCols.length > 1) { + var wid = 0; + BI.each(columnSize, function (t, s) { + if (self.headerTds[j][i].__mergeCols.contains(t)) { + wid += s; + } + }); + wid = self._calculateWidth(wid); + if (wid > 1) { + wid += self.headerTds[j][i].__mergeCols.length - 1; + } + if (BI.isNumeric(wid)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", wid - 1).css("width", wid - 1); + } else { + items[i].element.attr("width", wid).css("width", wid); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } else { + if (BI.isNumeric(w)) { + if (i == BI.size(items) - 1) { + items[i].element.attr("width", w - 1).css("width", w - 1); + } else { + items[i].element.attr("width", w).css("width", w); + } + } else { + items[i].element.attr("width", "").css("width", ""); + } + } + } + }); + } + }); + var cW = this._calculateWidth(BI.sum(columnSize)); + if (cW > 1.05) { + cW = cW + columnSize.length; + } + this.tableContainer.element.width(cW); + } }, - _createTree: function () { - this.id = "bi-tree" + BI.UUID(); - if (this.nodes) { - this.nodes.destroy(); - } - if (this.tree) { - this.tree.destroy(); + setRegionColumnSize: function (columnSize) { + var self = this, o = this.options; + o.regionColumnSize = columnSize; + if (o.freezeCols.length === 0) { + if (o.isNeedFreeze) { + this.partitions.attr("columnSize", this._isRightFreeze() ? ['fill', 0] : [0, 'fill']); + this.partitions.resize(); + } else { + this.tableContainer.element.width(columnSize[0]); + } + } else if (o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { + if (o.isNeedFreeze) { + this.partitions.attr("columnSize", columnSize); + this.partitions.resize(); + } else { + this.tableContainer.element.width(columnSize[0]); + } + } else { + if (o.isNeedFreeze) { + this.partitions.attr("columnSize", this._isRightFreeze() ? [0, 'fill'] : ['fill', 0]); + this.partitions.resize(); + } else { + this.tableContainer.element.width(columnSize[0]); + } } - this.tree = BI.createWidget({ - type: "bi.layout", - element: "
      " - }); - BI.createWidget({ - type: "bi.default", - element: this.container, - items: [this.tree] - }); }, - //选择节点触发方法 - _selectTreeNode: function (treeId, treeNode) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, treeNode, this); - this.fireEvent(BI.TreeView.EVENT_CHANGE, treeNode, this); + getRegionColumnSize: function () { + return this.options.regionColumnSize; }, - //配置属性 - _configSetting: function () { - var paras = this.options.paras; - var self = this; - var setting = { - async: { - enable: true, - url: getUrl, - autoParam: ["id", "name"], - otherParam: BI.cjkEncodeDO(paras) - }, - check: { - enable: true - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true, - dblClickExpand: false - }, - callback: { - beforeExpand: beforeExpand, - onAsyncSuccess: onAsyncSuccess, - onAsyncError: onAsyncError, - beforeCheck: beforeCheck, - onCheck: onCheck, - onExpand: onExpand, - onCollapse: onCollapse, - onClick: onClick - } - }; - var className = "dark", perTime = 100; - - function onClick(event, treeId, treeNode) { - self.nodes.checkNode(treeNode, !treeNode.checked, true, true); + getCalculateRegionColumnSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + return [this.scrollBottomLeft.element.width(), this.scrollBottomRight.element.width()]; } + return [this.scrollBottomRight.element.width()]; + }, - function getUrl(treeId, treeNode) { - var parentNode = self._getParentValues(treeNode); - treeNode.times = treeNode.times || 1; - var param = "id=" + treeNode.id - + "×=" + (treeNode.times++) - + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode)) - + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus())); + getCalculateRegionRowSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + return [this.scrollTopRight.element.height(), this.scrollBottomRight.element.height()]; + } + return [this.scrollBottomRight.element.height()]; + }, - return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; + getClientRegionColumnSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + return [this.scrollBottomLeft.element[0].clientWidth, this.scrollBottomRight.element[0].clientWidth]; } + return [this.scrollBottomRight.element[0].clientWidth]; + }, - function beforeExpand(treeId, treeNode) { - if (!treeNode.isAjaxing) { - if (!treeNode.children) { - treeNode.times = 1; - ajaxGetNodes(treeNode, "refresh"); - } - return true; - } else { - BI.Msg.toast("Please Wait。", "warning"); - return false; - } + getClientRegionRowSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + return [this.scrollBottomLeft.element[0].clientHeight, this.scrollBottomRight.element[0].clientHeight]; } + return [this.scrollBottomRight.element[0].clientHeight]; + }, - function onAsyncSuccess(event, treeId, treeNode, msg) { - treeNode.halfCheck = false; - if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) { - return; - } - var zTree = self.nodes; - var totalCount = treeNode.count || 0; + getScrollRegionColumnSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + return [this.scrollBottomLeft.element[0].scrollWidth, this.scrollBottomRight.element[0].scrollWidth]; + } + return [this.scrollBottomRight.element[0].scrollWidth]; + }, - //尝试去获取下一组节点,若获取值为空数组,表示获取完成 - // TODO by GUY - if (treeNode.children.length > totalCount) { - treeNode.count = treeNode.children.length; - BI.delay(function () { - ajaxGetNodes(treeNode); - }, perTime); + getScrollRegionRowSize: function () { + var o = this.options; + if (o.isNeedFreeze) { + if (o.freezeCols.length < o.columnSize.length) { + return [this.scrollTopRight.element[0].scrollHeight, this.scrollBottomRight.element[0].scrollHeight]; } else { - //treeNode.icon = ""; - zTree.updateNode(treeNode); - zTree.selectNode(treeNode.children[0]); - //className = (className === "dark" ? "":"dark"); + return [this.scrollTopLeft.element[0].scrollHeight, this.scrollBottomLeft.element[0].scrollHeight]; } } + return [this.scrollBottomRight.element[0].scrollHeight]; + }, - function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) { - var zTree = self.nodes; - BI.Msg.toast("Error!", "warning"); - //treeNode.icon = ""; - //zTree.updateNode(treeNode); + hasVerticalScroll: function () { + var o = this.options; + if (o.isNeedFreeze) { + return this.scrollBottomRight.element.hasVerticalScroll() || this.scrollBottomLeft.element.hasVerticalScroll(); } + return this.scrollBottomRight.element.hasVerticalScroll(); + }, - function ajaxGetNodes(treeNode, reloadType) { - var zTree = self.nodes; - if (reloadType == "refresh") { - //treeNode.icon = FR.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; - zTree.updateNode(treeNode); + setVerticalScroll: function (scrollTop) { + var o = this.options; + if (o.isNeedFreeze) { + if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { + this.scrollBottomRight.element[0].scrollTop = scrollTop; } - zTree.reAsyncChildNodes(treeNode, reloadType, true); - } - - function beforeCheck(treeId, treeNode) { - treeNode.halfCheck = false; - if (treeNode.checked === true) { - //将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy - //所有的半选状态都需要取消halfCheck=true的情况 - function track(children) { - BI.each(children, function (i, ch) { - if (ch.halfCheck === true) { - ch.halfCheck = false; - track(ch.children); - } - }) - } - - track(treeNode.children); - var treeObj = self.nodes; - var nodes = treeObj.getSelectedNodes(); - $.each(nodes, function (index, node) { - node.halfCheck = false; - }) + if (this.scrollBottomLeft.element[0].scrollTop !== scrollTop) { + this.scrollBottomLeft.element[0].scrollTop = scrollTop; + } + } else { + if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { + this.scrollBottomRight.element[0].scrollTop = scrollTop; } } + }, - function onCheck(event, treeId, treeNode) { - self._selectTreeNode(treeId, treeNode); + setLeftHorizontalScroll: function (scrollLeft) { + var o = this.options; + if (o.isNeedFreeze) { + if (this.scrollBottomLeft.element[0].scrollLeft !== scrollLeft) { + this.scrollBottomLeft.element[0].scrollLeft = scrollLeft; + } + if (this.scrollTopLeft.element[0].scrollLeft !== scrollLeft) { + this.scrollTopLeft.element[0].scrollLeft = scrollLeft; + } + } else { + if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { + this.scrollBottomRight.element[0].scrollLeft = scrollLeft; + } } + }, - function onExpand(event, treeId, treeNode) { - treeNode.halfCheck = false; + setRightHorizontalScroll: function (scrollLeft) { + var o = this.options; + if (o.isNeedFreeze) { + if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { + this.scrollBottomRight.element[0].scrollLeft = scrollLeft; + } + if (this.scrollTopRight.element[0].scrollLeft !== scrollLeft) { + this.scrollTopRight.element[0].scrollLeft = scrollLeft; + } + } else { + if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { + this.scrollBottomRight.element[0].scrollLeft = scrollLeft; + } } + }, - function onCollapse(event, treeId, treeNode) { + getVerticalScroll: function () { + var o = this.options; + if (o.isNeedFreeze) { + return this.scrollBottomRight.element[0].scrollTop || this.scrollBottomLeft.element[0].scrollTop; } - - return setting; + return this.scrollBottomRight.element[0].scrollTop; }, - _getParentValues: function (treeNode) { - if (!treeNode.getParentNode()) { - return []; + getLeftHorizontalScroll: function () { + var o = this.options; + if (o.isNeedFreeze) { + return this.scrollBottomLeft.element[0].scrollLeft; } - var parentNode = treeNode.getParentNode(); - var result = this._getParentValues(parentNode); - result = result.concat([this._getNodeValue(parentNode)]); - return result; + return this.scrollBottomRight.element[0].scrollLeft; }, - _getNodeValue: function (node) { - //去除标红 - return node.value || node.text.replace(/<[^>]+>/g, ""); + getRightHorizontalScroll: function () { + var o = this.options; + if (o.isNeedFreeze) { + return this.scrollBottomRight.element[0].scrollLeft; + } + return this.scrollBottomRight.element[0].scrollLeft; }, - //获取半选框值 - _getHalfSelectedValues: function (map, node) { - var self = this; - var checkState = node.getCheckStatus(); - //将未选的去掉 - if (checkState.checked === false && checkState.half === false) { - return; + getColumns: function () { + var o = this.options; + if (o.isNeedFreeze) { + return { + topLeft: this.topLeftBodyItems, + topRight: this.topRightBodyItems, + bottomLeft: this.bottomLeftBodyItems, + bottomRight: this.bottomRightBodyItems + } + } else { + return { + header: this.headerItems, + body: this.bodyItems, + footer: this.footerItems + } } - //如果节点已展开,并且是半选 - if (BI.isNotEmptyArray(node.children) && checkState.half === true) { - var children = node.children; - BI.each(children, function (i, ch) { - self._getHalfSelectedValues(map, ch); - }); - return; + }, + + populate: function (items, header) { + this.options.items = items || []; + if (header) { + this.options.header = header; } - var parent = node.parentValues || self._getParentValues(node); - var path = parent.concat(this._getNodeValue(node)); - if (BI.isNotEmptyArray(node.children) || checkState.half === false) { - this._buildTree(map, path); - return; + this.empty(); + if (this.options.isNeedFreeze) { + this._createFreezeTable(); + } else { + this._createNormalTable(); } - var storeValues = BI.deepClone(this.options.paras.selected_values); - var treeNode = this._getTree(storeValues, path); - this._addTreeNode(map, parent, this._getNodeValue(node), treeNode); }, - _getTree: function (map, values) { - var cur = map; - BI.any(values, function (i, value) { - if (cur[value] == null) { - return true; - } - cur = cur[value]; - }); - return cur; + empty: function () { + BI.Resizers.remove(this.getName()); + BI.Table.superclass.empty.apply(this, arguments); }, - _addTreeNode: function (map, values, key, value) { - var cur = map; - BI.each(values, function (i, value) { - if (cur[value] == null) { - cur[value] = {}; - } - cur = cur[value]; - }); - cur[key] = value; + destroy: function () { + BI.Table.superclass.destroy.apply(this, arguments); + } +}) +; +BI.Table.EVENT_TABLE_AFTER_INIT = "EVENT_TABLE_AFTER_INIT"; +BI.Table.EVENT_TABLE_RESIZE = "EVENT_TABLE_RESIZE"; +BI.Table.EVENT_TABLE_SCROLL = "EVENT_TABLE_SCROLL"; +BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE = "EVENT_TABLE_BEFORE_COLUMN_RESIZE"; +BI.Table.EVENT_TABLE_COLUMN_RESIZE = "EVENT_TABLE_COLUMN_RESIZE"; +BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE = "EVENT_TABLE_AFTER_COLUMN_RESIZE"; + +BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE = "EVENT_TABLE_BEFORE_REGION_RESIZE"; +BI.Table.EVENT_TABLE_REGION_RESIZE = "EVENT_TABLE_REGION_RESIZE"; +BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE = "EVENT_TABLE_AFTER_REGION_RESIZE"; +$.shortcut("bi.table_view", BI.Table); +/** + * + * 表格单元格 + * + * Created by GUY on 2016/1/12. + * @class BI.ResizableTableCell + * @extends BI.Widget + */ +BI.ResizableTableCell = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.ResizableTableCell.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-resizable-table-cell", + cell: {}, + start: BI.emptyFn, + resize: BI.emptyFn, + stop: BI.emptyFn + }) }, - //构造树节点 - _buildTree: function (map, values) { - var cur = map; - BI.each(values, function (i, value) { - if (cur[value] == null) { - cur[value] = {}; + _init: function () { + BI.ResizableTableCell.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.cell = BI.createWidget(BI.extend({type: "bi.label"}, o.cell, {width: o.width, height: o.height})); + + var startDrag = false; + var size = 0, offset = 0, defaultSize = o.width; + var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { + if (mouseMoveTracker.isDragging()) { + startDrag = true; + offset += deltaX; + size = BI.clamp(defaultSize + offset, 15, Number.MAX_VALUE); + self.handler.element.addClass("dragging"); + o.resize(size); } - cur = cur[value]; + }, function () { + if (startDrag === true) { + size = BI.clamp(size, 15, Number.MAX_VALUE); + o.stop(size); + size = 0; + offset = 0; + defaultSize = o.width; + self.handler.element.removeClass("dragging"); + startDrag = false; + } + mouseMoveTracker.releaseMouseMoves(); + }, document); + this.handler = BI.createWidget({ + type: "bi.absolute", + cls: "resizable-table-cell-resizer-container", + width: 6, + items: [{ + el: { + type: "bi.layout", + cls: "resizable-table-cell-resizer-knob", + width: 4 + }, + right: 0, + top: 0, + bottom: 0 + }] + }); + this.handler.element.on("mousedown", function (event) { + defaultSize = o.width; + mouseMoveTracker.captureMouseMoves(event); + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.cell, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: this.handler, + right: 0, + top: 0, + bottom: 0 + }] }) }, - //获取选中的值 - _getSelectedValues: function () { - var self = this; - var hashMap = {}; - var rootNoots = this.nodes.getNodes(); - track(rootNoots); - function track(nodes) { - BI.each(nodes, function (i, node) { - var checkState = node.getCheckStatus(); - if (checkState.checked === true || checkState.half === true) { - if (checkState.half === true) { - self._getHalfSelectedValues(hashMap, node); - } else { - var parentValues = node.parentValues || self._getParentValues(node); - var values = parentValues.concat([self._getNodeValue(node)]); - self._buildTree(hashMap, values); - } - } - }) - } - - return hashMap; + setWidth: function (width) { + BI.ResizableTableCell.superclass.setWidth.apply(this, arguments); + var o = this.options; + this.cell.setWidth(o.width); }, - //处理节点 - _dealWidthNodes: function (nodes) { - var self = this, o = this.options; - //处理标红 - if (BI.isKey(o.paras.keyword)) { - var keyword = o.paras.keyword; - var ns = BI.Tree.transformToArrayFormat(nodes); - BI.each(ns, function (i, n) { - n.text = $("
      ").__textKeywordMarked__(n.text, keyword, n.py).html(); - }); - } - return nodes; + setHeight: function (height) { + BI.ResizableTableCell.superclass.setHeight.apply(this, arguments); + var o = this.options; + this.cell.setHeight(o.height); + } +}); +$.shortcut("bi.resizable_table_cell", BI.ResizableTableCell);/** + * + * 可调整列宽的grid表格 + * + * Created by GUY on 2016/1/12. + * @class BI.ResizableTable + * @extends BI.Widget + */ +BI.ResizableTable = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.ResizableTable.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-resizable-table", + el: { + type: "bi.grid_table" + }, + isNeedFreeze: false, + isNeedResize: true, + isResizeAdapt: false, + headerRowSize: 25, + rowSize: 25, + isNeedMerge: true,//是否需要合并单元格 + mergeCols: [], + mergeRule: BI.emptyFn, + columnSize: [], + freezeCols: [], + header: [], + items: [], + regionColumnSize: [] + }) }, - _loadMore: function () { + _init: function () { + BI.ResizableTable.superclass._init.apply(this, arguments); var self = this, o = this.options; - this.tip.setLoading(); - var op = BI.extend({}, o.paras, { - times: ++this.times + this.resizer = BI.createWidget({ + type: "bi.layout", + cls: "resizable-table-resizer", + invisible: true, + width: 2 }); - o.itemsCreator(op, function (res) { - if (self._stop === true) { - return; - } - var hasNext = !!res.hasNext, nodes = res.items || []; + this.regionResizerHandler = this._createResizerHandler(); + this.table = BI.createWidget(o.el, { + type: "bi.grid_table", + element: this, + width: o.width, + height: o.height, + headerRowSize: o.headerRowSize, + rowSize: o.rowSize, + columnSize: o.columnSize, - if (!hasNext) { - self.tip.setEnd(); - } else { - self.tip.setLoaded(); - } - if (nodes.length > 0) { - self.nodes.addNodes(null, self._dealWidthNodes(nodes)); - } - }); - }, + isNeedFreeze: o.isNeedFreeze, + freezeCols: o.freezeCols, + isNeedMerge: o.isNeedMerge, + mergeCols: o.mergeCols, + mergeRule: BI.bind(this._mergeRule, this), - //生成树内部方法 - _initTree: function (setting) { - var self = this, o = this.options; - self.fireEvent(BI.Events.INIT); - this.times = 1; - var tree = this.tree; - tree.empty(); - this.loading(); - this.tip.setVisible(false); - var callback = function (nodes) { - if (self._stop === true) { - return; - } - self.nodes = $.fn.zTree.init(tree.element, setting, nodes); - }; - var op = BI.extend({}, o.paras, { - times: 1, - type: BICst.TREE.TREE_REQ_TYPE.INIT_DATA + header: this._formatHeader(o.header), + items: o.items, + regionColumnSize: o.regionColumnSize }); - - o.itemsCreator(op, function (res) { - if (self._stop === true) { - return; - } - var hasNext = !!res.hasNext, nodes = res.items || []; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes)); - } - self.setTipVisible(nodes.length <= 0); - self.loaded(); - if (!hasNext) { - self.tip.invisible(); - } else { - self.tip.setLoaded(); - } - op.times === 1 && self.fireEvent(BI.Events.AFTERINIT); + this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { + self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.regionResizerHandler, + left: 0, + top: 0, + bottom: 0 + }, { + el: this.resizer, + left: 0, + top: 0 + }] + }); + this._populate(); }, - //构造树结构, - initTree: function (nodes, setting) { - var setting = setting || { - async: { - enable: false - }, - check: { - enable: false - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "" - }, - callback: {} - }; - this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); - }, - - start: function () { - this._stop = false; - }, - - stop: function () { - this._stop = true; + _mergeRule: function (row1, row2) { + var o = this.options; + if (row1.type === "bi.resizable_table_cell") { + row1 = row1.cell; + } + if (row2.type === "bi.resizable_table_cell") { + row2 = row2.cell; + } + return o.mergeRule(row1, row2); }, - //生成树方法 - stroke: function (config) { - delete this.options.keyword; - BI.extend(this.options.paras, config); - var setting = this._configSetting(); - this._createTree(); - this.start(); - this._initTree(setting); - }, + _createResizerHandler: function () { + var self = this, o = this.options; + var regionResizerHandler = BI.createWidget({ + type: "bi.absolute", + cls: "resizable-table-region-resizer", + invisible: true, + width: 6, + items: [{ + el: { + type: "bi.layout", + width: 2, + cls: "resizable-table-region-resizer-knob" + }, + left: 2, + top: 0, + bottom: 0 + }] + }); + var size = 0, offset = 0, defaultSize = 0, start = false; + var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { + if (mouseMoveTracker.isDragging()) { + start = true; + offset += deltaX; + size = BI.clamp(defaultSize + offset, 15, o.width - 15); - populate: function () { - this.stroke.apply(this, arguments); - }, + self.regionResizerHandler.element.addClass("dragging"); + self._setRegionResizerHandlerPosition(size - 3, 0); + } - hasChecked: function () { - var treeObj = this.nodes; - return treeObj.getCheckedNodes(true).length > 0; + }, function () { + if (start === true) { + o.regionColumnSize[0] = BI.clamp(size, 15, o.width - 15); + self.table.setRegionColumnSize(o.regionColumnSize); + if (o.isResizeAdapt === true) { + var freezeColumnSize = self._getFreezeColumnSize(); + o.columnSize[self._getFreezeColLength() - 1] += o.regionColumnSize[0] - freezeColumnSize; + self.table.setColumnSize(o.columnSize); + } + self.table.populate(); + self._populate(); + self.regionResizerHandler.element.removeClass("dragging"); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); + start = false; + } + mouseMoveTracker.releaseMouseMoves(); + }, document); + regionResizerHandler.element.on("mousedown", function (event) { + defaultSize = size = self._getRegionSize(); + offset = 0; + self._setResizerPosition(0, 0); + mouseMoveTracker.captureMouseMoves(event); + }); + return regionResizerHandler; }, - checkAll: function (checked) { - this.nodes && this.nodes.checkAllNodes(checked); + _setResizerPosition: function (left, top) { + this.resizer.element.css({ + left: left + "px", + top: top + "px" + }); }, - expandAll: function (flag) { - this.nodes && this.nodes.expandAll(flag); + _setRegionResizerHandlerPosition: function (left, top) { + this.regionResizerHandler.element.css({ + left: left + "px", + top: top + "px" + }); }, - setValue: function (value, param) { - this.options.paras.selected_values = value || {}; - this.selected_values = BI.deepClone(value) || {}; - this.checkAll(false); - this.updateValue(value, param); - this.refresh(); + _getRegionSize: function () { + var o = this.options; + var regionSize = o.regionColumnSize[0] || 0; + if (o.isNeedFreeze === false || o.freezeCols.length === 0) { + return 0; + } + if (!regionSize) { + BI.each(o.freezeCols, function (i, col) { + regionSize += o.columnSize[col]; + }); + } + return regionSize; }, - updateValue: function (values, param) { - if (!this.nodes) { - return; - } - param || (param = "value"); - var treeObj = this.nodes; - BI.each(values, function (v, op) { - var nodes = treeObj.getNodesByParam(param, v, null); - BI.each(nodes, function (j, node) { - BI.extend(node, {checked: true}, op); - treeObj.updateNode(node); - }) - }); + _getRegionRowSize: function () { + var o = this.options; + return [o.header.length * o.headerRowSize, + Math.min(o.height - o.header.length * o.headerRowSize, o.items.length * o.rowSize)]; }, - refresh: function () { - this.nodes && this.nodes.refresh(); + _getFreezeColLength: function () { + return this.options.freezeCols.length; }, - getValue: function () { - if (!this.nodes) { - return null; + _getFreezeColumnSize: function () { + var columnSize = this.options.columnSize; + var sum = 0; + for (var i = 0, len = this._getFreezeColLength(); i < len; i++) { + sum += columnSize[i]; } - return this._getSelectedValues(); + return sum; }, - empty: function () { - BI.isNotNull(this.nodes) && this.nodes.destroy(); + _getResizerLeft: function (j) { + var left = 0; + var columnSize = this.options.columnSize; + var freezeColLength = this._getFreezeColLength(); + for (var i = (j >= freezeColLength ? freezeColLength : 0); i < j; i++) { + left += columnSize[i] || 0; + } + if (j >= freezeColLength) { + left += this.table.getRegionSize(); + left -= this.table.getRightHorizontalScroll(); + } else { + left -= this.table.getLeftHorizontalScroll(); + } + return left; }, - destroy: function () { - this.stop(); - this.nodes && this.nodes.destroy(); - BI.TreeView.superclass.destroy.apply(this, arguments); - } -}); -BI.extend(BI.TreeView, { - REQ_TYPE_INIT_DATA: 1, - REQ_TYPE_ADJUST_DATA: 2, - REQ_TYPE_CALCULATE_SELECT_DATA: 3, - REQ_TYPE_SELECTED_DATA: 4 -}); - -BI.TreeView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.TreeView.EVENT_INIT = BI.Events.INIT; -BI.TreeView.EVENT_AFTERINIT = BI.Events.AFTERINIT; - -$.shortcut("bi.tree", BI.TreeView);/** - * guy - * 同步树 - * @class BI.SyncTree - * @extends BI.TreeView - */ -BI.SyncTree = BI.inherit(BI.TreeView, { - _defaultConfig: function () { - return BI.extend(BI.SyncTree.superclass._defaultConfig.apply(this, arguments), {}) - }, - _init: function () { - BI.SyncTree.superclass._init.apply(this, arguments); - }, + _formatHeader: function (header) { + var self = this, o = this.options; + var result = []; + var resize = function (j, size) { + self.resizer.setVisible(true); + var height = o.headerRowSize + self._getRegionRowSize()[1]; + self.resizer.setHeight(height); - //配置属性 - _configSetting: function () { - var paras = this.options.paras; - var self = this; - var setting = { - async: { - enable: false, - otherParam: BI.cjkEncodeDO(paras) - }, - check: { - enable: true - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true, - dblClickExpand: false - }, - callback: { - beforeCheck: beforeCheck, - onCheck: onCheck, - beforeExpand: beforeExpand, - onExpand: onExpand, - onCollapse: onCollapse, - onClick: onClick - } + self._setResizerPosition(self._getResizerLeft(j) + size, (o.header.length - 1) * o.headerRowSize); }; - - function onClick(event, treeId, treeNode) { - var zTree = $.fn.zTree.getZTreeObj(treeId); - zTree.checkNode(treeNode, !treeNode.checked, true, true); - } - - function beforeCheck(treeId, treeNode) { - treeNode.halfCheck = false; - if (treeNode.checked === true) { - //将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy - //所有的半选状态都需要取消halfCheck=true的情况 - function track(children) { - BI.each(children, function (i, ch) { - if (ch.halfCheck === true) { - ch.halfCheck = false; - track(ch.children); + var stop = function (j, size) { + self.resizer.setVisible(false); + o.columnSize[j] = size; + self.table.setColumnSize(o.columnSize); + self.table.populate(); + self._populate(); + self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE); + }; + BI.each(header, function (i, cols) { + if (i === header.length - 1) { + result[i] = []; + BI.each(cols, function (j, col) { + if (j === self._getFreezeColLength() - 1 || j === cols.length - 1) { + result[i][j] = col; + } else { + result[i][j] = { + type: "bi.resizable_table_cell", + cell: col, + resize: BI.bind(resize, null, j), + stop: BI.bind(stop, null, j) + }; + if (o.isNeedMerge) { + var r = i; + while (r > 0 && self._mergeRule(result[r][j], result[r - 1][j])) { + result[r - 1][j] = { + type: "bi.resizable_table_cell", + cell: result[r - 1][j], + resize: BI.bind(resize, null, j), + stop: BI.bind(stop, null, j) + }; + r--; + } } - }) - } - - track(treeNode.children); - - var treeObj = $.fn.zTree.getZTreeObj(treeId); - var nodes = treeObj.getSelectedNodes(); - BI.each(nodes, function (index, node) { - node.halfCheck = false; - }) + } + }); + } else { + result.push(cols); } - } + }); + return result; + }, - function beforeExpand(treeId, treeNode) { - self._expandNode(treeId, treeNode); + _populate: function () { + var o = this.options; + var regionSize = this._getRegionSize(); + if (regionSize > 0) { + this.regionResizerHandler.setVisible(true); + this._setRegionResizerHandlerPosition(regionSize - 3, 0); + } else { + this.regionResizerHandler.setVisible(false); } + }, - function onCheck(event, treeId, treeNode) { - self._selectTreeNode(treeId, treeNode); - } + setWidth: function (width) { + BI.ResizableTable.superclass.setWidth.apply(this, arguments); + this.table.setWidth(width) + }, - function onExpand(event, treeId, treeNode) { - treeNode.halfCheck = false; - } + setHeight: function (height) { + BI.ResizableTable.superclass.setHeight.apply(this, arguments); + this.table.setHeight(height); + }, - function onCollapse(event, treeId, treeNode) { - treeNode.halfCheck = false; - } + setVerticalScroll: function (scrollTop) { + this.table.setVerticalScroll(scrollTop); + }, - return setting; + setLeftHorizontalScroll: function (scrollLeft) { + this.table.setLeftHorizontalScroll(scrollLeft); }, - _selectTreeNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parent_values = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); - var name = this._getNodeValue(treeNode) -// var values = parent_values.concat([name]); - if (treeNode.checked === true) { - } else { - var tNode = treeNode; - var pNode = this._getTree(this.selected_values, parent_values); - if (BI.isNotNull(pNode[name])) { - delete pNode[name]; - } - while (tNode != null && BI.isEmpty(pNode)) { - parent_values = parent_values.slice(0, parent_values.length - 1); - tNode = tNode.getParentNode(); - if (tNode != null) { - pNode = this._getTree(this.selected_values, parent_values); - name = this._getNodeValue(tNode); - delete pNode[name]; - } - } - } - BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); + setRightHorizontalScroll: function (scrollLeft) { + this.table.setRightHorizontalScroll(scrollLeft); }, - //展开节点 - _expandNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parentValues = treeNode.parentValues || self._getParentValues(treeNode); - var op = BI.extend({}, o.paras, { - "id": treeNode.id, - "times": 1, - "parent_values": parentValues.concat(this._getNodeValue(treeNode)), - "check_state": treeNode.getCheckStatus() - }); - var complete = function (d) { - var nodes = d.items || []; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes), !!d.hasNext); - } - }; - var times = 1; + setColumnSize: function (columnSize) { + this.options.columnSize = columnSize; + this.table.setColumnSize(columnSize); + }, - function callback(nodes, hasNext) { - self.nodes.addNodes(treeNode, nodes); + getColumnSize: function () { + return this.table.getColumnSize(); + }, + + setRegionColumnSize: function (columnSize) { + this.options.regionColumnSize = columnSize; + this.table.setRegionColumnSize(columnSize); + }, - if (hasNext === true) { - BI.delay(function () { - times++; - op.times = times; - o.itemsCreator(op, complete); - }, 100); - } - } + getRegionColumnSize: function () { + return this.table.getRegionColumnSize(); + }, - if (!treeNode.children) { - o.itemsCreator(op, complete) - } + getVerticalScroll: function () { + return this.table.getVerticalScroll(); }, - _joinTree: function (map, values, isLast) { - var cur = map; - BI.each(values, function (i, value) { - if (i > 0 && BI.isPlainObject(cur) && BI.isEmpty(cur)) { - return; - } - if (isLast === true && i === values.length - 1) { - cur[value] = {}; - return; - } - if (cur[value] == null) { - cur[value] = {}; - } - cur = cur[value]; - }) + getLeftHorizontalScroll: function () { + return this.table.getLeftHorizontalScroll(); }, - _join: function (valueA, valueB) { - var self = this; - var hashMap = valueA || {}; - track([], valueB); - function track(parent, node) { - BI.each(node, function (n, item) { - var next = parent.concat([n]); - self._joinTree(hashMap, next, BI.isPlainObject(item) && BI.isEmpty(item)); - track(next, item); - }) - } + getRightHorizontalScroll: function () { + return this.table.getRightHorizontalScroll(); + }, - return hashMap; + attr: function () { + BI.ResizableTable.superclass.attr.apply(this, arguments); + this.table.attr.apply(this.table, arguments); }, - hasChecked: function () { - return !BI.isEmpty(this.selected_values) || BI.SyncTree.superclass.hasChecked.apply(this, arguments); + restore: function () { + this.table.restore(); }, - getValue: function () { - if (!this.nodes) { - return {}; - } - var checkedValues = this._getSelectedValues(); - if (BI.isEmpty(checkedValues)) { - return this.selected_values; + populate: function (items, header) { + if (items) { + this.options.items = items; } - if (BI.isEmpty(this.selected_values)) { - return checkedValues; + if (header) { + this.options.header = header; + if (this.options.isNeedResize) { + header = this._formatHeader(header); + } } - return this._join(checkedValues, this.selected_values); - }, - - //生成树方法 - stroke: function (config) { - delete this.options.keyword; - BI.extend(this.options.paras, config); - //取消选中时使用 - this.selected_values = BI.deepClone(this.options.paras.selected_values) || {}; - var setting = this._configSetting(); - this._initTree(setting); + this.table.populate(items, header); + this._populate(); } }); -$.shortcut("bi.sync_tree", BI.SyncTree);/** - * guy - * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 - * @class BI.PartTree - * @extends BI.SyncTree +$.shortcut("bi.resizable_table", BI.ResizableTable);/** + * 组件请求数据超时提示 + * Created by Young's on 2017/2/4. */ -BI.PartTree = BI.inherit(BI.SyncTree, { +BI.TimeoutToast = BI.inherit(BI.Tip, { _defaultConfig: function () { - return BI.extend(BI.PartTree.superclass._defaultConfig.apply(this, arguments), {}) + return BI.extend(BI.TimeoutToast.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-timeout-toast" + }); }, _init: function () { - BI.PartTree.superclass._init.apply(this, arguments); + BI.TimeoutToast.superclass._init.apply(this, arguments); + var self = this; + this.requests = []; + this.toast = BI.createWidget({ + type: "bi.vertical_adapt", + element: this, + items: [{ + type: "bi.label", + text: BI.i18nText("BI-Request_Time_Out_Toast_Tip") + }, { + type: "bi.text_button", + cls: "cancel-button", + width: 60, + height: 22, + text: BI.i18nText("BI-Basic_Cancel"), + title: BI.i18nText("BI-Basic_Cancel"), + handler: function () { + self.cancelAllRequests(); + } + }, { + type: "bi.text_button", + cls: "retry-button", + width: 60, + height: 22, + text: BI.i18nText("BI-Basic_Retry"), + title: BI.i18nText("BI-Basic_Retry"), + handler: function () { + self.toast.element.slideUp(500); + self._retryAll(); + } + }, { + type: "bi.icon_button", + cls: "close-font", + width: 20, + height: 20, + title: BI.i18nText("BI-Basic_Close"), + handler: function () { + self.toast.element.slideUp(500); + } + }], + width: 520, + height: 30, + hgap: 2 + }); + + BI.createWidget({ + type: "bi.absolute", + element: $("body"), + items: [{ + el: this.toast, + left: "50%", + top: 0 + }] + }); + this.toast.element.css({"margin-left": -1 * this.toast.element.outerWidth() / 2}); + this.toast.setVisible(false); }, - _loadMore: function () { - var self = this, o = this.options; - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: ++this.times + _retryAll: function () { + var self = this; + var clonedRequests = BI.deepClone(this.requests); + this.requests = []; + BI.each(clonedRequests, function (i, options) { + BI.isFunction(self.callback) && self.callback(options); }); - this.tip.setLoading(); - o.itemsCreator(op, function (d) { - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.last_search_value = d.last_search_value; - if (self._stop === true) { - return; - } - if (!hasNext) { - self.tip.setEnd(); - } else { - self.tip.setLoaded(); - } - if (nodes.length > 0) { - self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + }, + + cancelAllRequests: function () { + this.toast.element.slideUp(500); + BI.each(this.requests, function (i, reqArgs) { + if (BI.isNotNull(reqArgs) && BI.isFunction(reqArgs.complete)) { + reqArgs.complete(); } }); + this.requests = []; }, - _selectTreeNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parent_values = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); - var name = this._getNodeValue(treeNode) -// var values = parent_values.concat([name]); - if (treeNode.checked === true) { - BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); - } else { - o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA, - selected_values: this.selected_values, - not_selected_value: name, - parent_values: parent_values - }), function (new_values) { - if (BI.isEqual(self.selected_values, new_values)) { - var tNode = treeNode; - var pNode = self._getTree(new_values, parent_values); - if (pNode[name]) { - delete pNode[name]; - } - while (tNode != null && BI.isEmpty(pNode)) { - parent_values = parent_values.slice(0, parent_values.length - 1); - tNode = tNode.getParentNode(); - if (tNode != null) { - pNode = self._getTree(new_values, parent_values); - name = self._getNodeValue(tNode); - delete pNode[name]; - } - } - } - self.selected_values = new_values; - BI.SyncTree.superclass._selectTreeNode.apply(self, arguments); - }); - } + setCallback: function (callback) { + this.callback = callback; }, - _getSelectedValues: function () { + addReq: function (options) { var self = this; - var hashMap = {}; - var rootNoots = this.nodes.getNodes(); - track(rootNoots); - function track(nodes) { - BI.each(nodes, function (i, node) { - var checkState = node.getCheckStatus(); - if (checkState.checked === false) { - return true; - } - var parentValues = node.parentValues || self._getParentValues(node); - //把文字中的html去掉,其实就是把文字颜色去掉 - var values = parentValues.concat([self._getNodeValue(node)]); - self._buildTree(hashMap, values); -// if(checkState.checked === true && checkState.half === false && nodes[i].flag === true){ -// continue; -// } - if (BI.isNotEmptyArray(node.children)) { - track(node.children); - return true; - } - if (checkState.half === true) { - self._getHalfSelectedValues(hashMap, node); + if (this.requests.length === 0) { + setTimeout(function () { + if (self.requests.contains(options)) { + self.toast.element.slideDown(500); } - }) + }, 5 * 60 * 1000); //5 min } - - return hashMap; + this.requests.push(options); }, - _initTree: function (setting, keyword) { - var self = this, o = this.options; - this.times = 1; - var tree = this.tree; - tree.empty(); - self.tip.setVisible(false); - this.loading(); - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: this.times - }); - var complete = function (d) { - if (self._stop === true || keyword != o.paras.keyword) { - return; - } - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.last_search_value = d.last_search_value; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes)); - } - self.setTipVisible(nodes.length <= 0); - self.loaded(); - if (!hasNext) { - self.tip.invisible(); - } else { - self.tip.setLoaded(); - } - self.fireEvent(BI.Events.AFTERINIT); - }; - - function callback(nodes) { - if (self._stop === true) { - return; - } - self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + removeReq: function (options) { + BI.remove(this.requests, options); + if (this.requests.length === 0) { + this.toast.element.slideUp(500); } - - BI.delay(function () { - o.itemsCreator(op, complete); - }, 100); - }, - - getValue: function () { - var o = this.options; - var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selected_values: result - }, function (res) { - result = res; - }); - return result; }, - //生成树方法 - stroke: function (config) { - var o = this.options; - delete o.paras.keyword; - BI.extend(o.paras, config); - delete o.paras.last_search_value; - //取消选中时使用 - this.selected_values = BI.deepClone(o.paras.selected_values) || {}; - //delete this.options.paras.selected_values; - var setting = this._configSetting(); - this._initTree(setting, o.paras.keyword); + hasReq: function (options) { + return this.requests.contains(options); } }); - -$.shortcut("bi.part_tree", BI.PartTree);/** +$.shortcut("bi.timeout_toast", BI.TimeoutToast);/** * * 自定义树 * diff --git a/dist/core.js b/dist/core.js index b4e0b2844..61b8b721e 100644 --- a/dist/core.js +++ b/dist/core.js @@ -13698,6 +13698,10 @@ if (!window.BI) { return (string + "").toLocaleLowerCase(); }, + isEndWithBlank: function (string) { + return /(\s|\u00A0)$/.test(string); + }, + isLiteral: function (exp) { var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/ return literalValueRE.test(exp) @@ -19644,7 +19648,7 @@ BI.Cache = { * 控制器 * Controller层超类 * @class BI.Controller - * @extends FR.OB + * @extends BI.OB * @abstract */ BI.Controller = BI.inherit(BI.OB, { @@ -22009,6 +22013,52 @@ BI.ShowListener = BI.inherit(BI.OB, { } }); BI.ShowListener.EVENT_CHANGE = "ShowListener.EVENT_CHANGE";/** + * style加载管理器 + * + * Created by GUY on 2015/9/7. + * @class + */ +BI.StyleLoaderManager = BI.inherit(BI.OB, { + _defaultConfig: function () { + return BI.extend(BI.StyleLoaderManager.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.StyleLoaderManager.superclass._init.apply(this, arguments); + this.stylesManager = {}; + }, + + loadStyle: function (name, styleString) { + var d = document, styles = d.createElement('style'); + d.getElementsByTagName('head')[0].appendChild(styles); + styles.setAttribute('type', 'text/css'); + if (styles.styleSheet) { + styles.styleSheet.cssText = styleString; + } else { + styles.appendChild(document.createTextNode(styleString)); + } + this.stylesManager[name] = styles; + + return this; + }, + + get: function (name) { + return this.stylesManager[name]; + }, + + has: function (name) { + return this.stylesManager[name] != null; + }, + + removeStyle: function (name) { + if (!this.has(name)) { + return this; + } + this.stylesManager[name].parentNode.removeChild(this.stylesManager[name]); + delete this.stylesManager[name]; + return this; + } +});/** * @class BI.Logic * @extends BI.OB */ @@ -23160,6 +23210,66 @@ Function.prototype.after = function (func) { func.apply(this, arguments); return ret; } +};/*! + * jLayout JQuery Plugin v0.11 + * + * Licensed under the revised BSD License. + * Copyright 2008, Bram Stein + * All rights reserved. + */ +if (jQuery) { + (function($){ + // richer:容器在其各个边缘留出的空间 + $.fn.insets = function () { + var p = this.padding(), + b = this.border(); + return { + 'top': p.top, + 'bottom': p.bottom + b.bottom + b.top, + 'left': p.left, + 'right': p.right + b.right + b.left + }; + }; + + // richer:获取 && 设置jQuery元素的边界 + $.fn.bounds = function (value) { + var tmp = {hasIgnoredBounds : true}; + + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + return this; + } + else { + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + return { + 'x': tmp.left, + 'y': tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + 'width': this.outerWidth(), + 'height': this.outerHeight() + }; + } + }; + })(jQuery); };if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") { @@ -23644,51 +23754,6 @@ $.extend(String, { return args[i]; }); } -});/** - * guy - * 状态常量 - */ - -_.extend(BI, { - Status: { - SUCCESS: 1, - WRONG: 2, - START: 3, - END: 4, - WAITING: 5, - READY: 6, - RUNNING: 7, - OUTOFBOUNDS: 8, - NULL: -1 - }, - Direction: { - Top: "top", - Bottom: "bottom", - Left: "left", - Right: "right", - Custom: "custom" - }, - Axis: { - Vertical: "vertical", - Horizontal: "horizontal" - }, - Selection: { - Default: -999, - None: -1, - Single: 0, - Multi: 1, - All: 2 - }, - HorizontalAlign: { - Left: "left", - Right: "right", - Center: "center" - }, - VerticalAlign: { - Middle: "middle", - Top: "top", - Bottom: "bottom" - } });BI.EventListener = { listen: function listen(target, eventType, callback) { if (target.addEventListener) { @@ -23995,7 +24060,70 @@ _.extend(BI, { emptyStr: "", emptyFn: function () { }, - empty: null + empty: null, + KeyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + }, + Status: { + SUCCESS: 1, + WRONG: 2, + START: 3, + END: 4, + WAITING: 5, + READY: 6, + RUNNING: 7, + OUTOFBOUNDS: 8, + NULL: -1 + }, + Direction: { + Top: "top", + Bottom: "bottom", + Left: "left", + Right: "right", + Custom: "custom" + }, + Axis: { + Vertical: "vertical", + Horizontal: "horizontal" + }, + Selection: { + Default: -999, + None: -1, + Single: 0, + Multi: 1, + All: 2 + }, + HorizontalAlign: { + Left: "left", + Right: "right", + Center: "center" + }, + VerticalAlign: { + Middle: "middle", + Top: "top", + Bottom: "bottom" + } });/** * absolute实现的居中布局 * @class BI.AbsoluteCenterLayout @@ -25844,7 +25972,6 @@ BI.CardLayout = BI.inherit(BI.Layout, { .appendTo(this.element); widget.invisible(); this.addWidget(this._getCardName(cardName), widget); - widget._mount(); return widget; }, @@ -25862,7 +25989,10 @@ BI.CardLayout = BI.inherit(BI.Layout, { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.element.hide(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, callback); + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, function () { + el._mount(); + callback && callback(); + }); } }); }, diff --git a/dist/icon/check-box-disable.png b/dist/icon/check-box-disable.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7f451b34e113d727ccef7ed3ab7ba357bab22c GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP*I?#i(^Q|t)xHy|JyUGHcZT7 zn`2X3b$PyheNE@ZBZm%cx_Rfy75+1AoJ}UHSFR99eZAJY{DGLEVE~64uY@Uss%q0D o^&&3iDN|O?pLv3nfsu{DpjGkD){h;pfQB=8y85}Sb4q9e03zf-Y5)KL literal 0 HcmV?d00001 diff --git a/dist/icon/check-box-normal.png b/dist/icon/check-box-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..2974ad7dbc523a7091e1d32ecfbb75c2f07964a9 GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP*Jd_i(^Q|t)xHy|JyUGHgq;R z9bihnv*&-o<@xsYwVjua9NH5Z8+ecZ3}Yo@%lbRJe$S6!2<5)!zERwbSHhG*RkL~0 q^Q*VNclez$Fniqa+^vCunPK8g-yrFEKj#6BXYh3Ob6Mw<&;$S$QbXwg literal 0 HcmV?d00001 diff --git a/src/base/collection/collection.js b/src/base/collection/collection.js index fa991aa87..528913284 100644 --- a/src/base/collection/collection.js +++ b/src/base/collection/collection.js @@ -58,20 +58,14 @@ BI.Collection = BI.inherit(BI.Widget, { this._calculateSizeAndPositionData(); this._populate(); } - }, - - mounted: function () { - var o = this.options; if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); + BI.nextTick(function () { + self.element.scrollTop(o.scrollTop); + self.element.scrollLeft(o.scrollLeft); + }); } }, - destroyed: function () { - this._debounceRelease = null; - }, - _calculateSizeAndPositionData: function () { var o = this.options; var cellMetadata = []; diff --git a/src/base/combination/combo.js b/src/base/combination/combo.js index 75fb6b7a2..6f0a84bb0 100644 --- a/src/base/combination/combo.js +++ b/src/base/combination/combo.js @@ -4,14 +4,17 @@ */ BI.Combo = BI.inherit(BI.Widget, { _defaultConfig: function () { - return BI.extend(BI.Combo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-combo", + var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-combo", trigger: "click", toggle: true, direction: "bottom", //top||bottom||left||right||top,left||top,right||bottom,left||bottom,right isDefaultInit: false, isNeedAdjustHeight: true,//是否需要高度调整 isNeedAdjustWidth: true, + stopEvent: false, + stopPropagation: false, adjustLength: 0,//调整的距离 adjustXOffset: 0, adjustYOffset: 0, @@ -88,6 +91,14 @@ BI.Combo = BI.inherit(BI.Widget, { _initPullDownAction: function () { var self = this, o = this.options; var evs = this.options.trigger.split(","); + var st = function (e) { + if (o.stopEvent) { + e.stopEvent(); + } + if (o.stopPropagation) { + e.stopPropagation(); + } + }; BI.each(evs, function (i, ev) { switch (ev) { case "hover": @@ -107,25 +118,27 @@ BI.Combo = BI.inherit(BI.Widget, { }); break; case "click": - if (ev) { - self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.combo.isEnabled()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } + var debounce = BI.debounce(function (e) { + if (self.combo.element.__isMouseInBounds__(e)) { + if (self.isEnabled() && self.combo.isEnabled()) { + o.toggle ? self._toggle() : self._popupView(); + if (self.isViewVisible()) { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); + self.fireEvent(BI.Combo.EVENT_EXPAND); + } else { + self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); + self.fireEvent(BI.Combo.EVENT_COLLAPSE); } } - }, BI.EVENT_RESPONSE_TIME, true)); - } + } + }, BI.EVENT_RESPONSE_TIME, true); + self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function(e){ + debounce(e); + st(e); + }); break; } - }) + }); }, _initCombo: function () { @@ -292,6 +305,7 @@ BI.Combo = BI.inherit(BI.Widget, { top: p.top }); } + this.position = p; this.popupView.setVisible(isVisible); }, @@ -315,7 +329,7 @@ BI.Combo = BI.inherit(BI.Widget, { BI.Combo.superclass.setEnable.apply(this, arguments); this.combo && this.combo.setEnable(arg); this.popupView && this.popupView.setEnable(arg); - !arg && this._hideView(); + !arg && this.isViewVisible() && this._hideView(); }, setValue: function (v) { @@ -347,6 +361,10 @@ BI.Combo = BI.inherit(BI.Widget, { return this.popupView; }, + getPopupPosition: function () { + return this.position; + }, + doBehavior: function () { this._assertPopupView(); this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); @@ -356,14 +374,14 @@ BI.Combo = BI.inherit(BI.Widget, { this._toggle(); }, - destroyed: function () { + destroy: function () { $(document).unbind("mousedown." + this.getName()) .unbind("mousewheel." + this.getName()) .unbind("mouseenter." + this.getName()) .unbind("mousemove." + this.getName()) .unbind("mouseleave." + this.getName()); - this.popupView && this.popupView.destroy(); BI.Resizers.remove(this.getName()); + BI.Combo.superclass.destroy.apply(this, arguments); } }); BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; diff --git a/src/base/combination/expander.js b/src/base/combination/expander.js index 8e593cee1..a71b09d66 100644 --- a/src/base/combination/expander.js +++ b/src/base/combination/expander.js @@ -35,8 +35,13 @@ BI.Expander = BI.inherit(BI.Widget, { self._hideView(); } if (self.isEnabled() && this.isEnabled()) { - if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { + if (type === BI.Events.EXPAND) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.fireEvent(BI.Expander.EVENT_EXPAND); + } + if(type === BI.Events.COLLAPSE) { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + self.fireEvent(BI.Expander.EVENT_COLLAPSE); } if (type === BI.Events.CLICK) { self.fireEvent(BI.Expander.EVENT_TRIGGER_CHANGE, value, obj); @@ -254,8 +259,8 @@ BI.Expander = BI.inherit(BI.Widget, { return this.popupView && this.popupView.getNodeByValue(value); }, - destroyed: function () { - this.popupView && this.popupView.destroy(); + destroy: function () { + BI.Expander.superclass.destroy.apply(this, arguments); } }); BI.Expander.EVENT_EXPAND = "EVENT_EXPAND"; diff --git a/src/base/combination/group.button.js b/src/base/combination/group.button.js index c48b86304..a1f36155e 100644 --- a/src/base/combination/group.button.js +++ b/src/base/combination/group.button.js @@ -298,6 +298,10 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { } }); return node; + }, + + destroy: function () { + BI.ButtonGroup.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.ButtonGroup, { @@ -309,4 +313,4 @@ BI.extend(BI.ButtonGroup, { }); BI.ButtonGroup.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.button_group", BI.ButtonGroup); +$.shortcut("bi.button_group", BI.ButtonGroup); \ No newline at end of file diff --git a/src/base/combination/loader.js b/src/base/combination/loader.js index 331c2ea9b..434a90f2a 100644 --- a/src/base/combination/loader.js +++ b/src/base/combination/loader.js @@ -252,6 +252,10 @@ BI.Loader = BI.inherit(BI.Widget, { BI.each([this.prev, this.next], function (i, ob) { ob && ob.setVisible(false); }); + }, + + destroy: function () { + BI.Loader.superclass.destroy.apply(this, arguments); } }); BI.Loader.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/combination/map.button.js b/src/base/combination/map.button.js new file mode 100644 index 000000000..8184e7008 --- /dev/null +++ b/src/base/combination/map.button.js @@ -0,0 +1,115 @@ +/** + * value作为key值缓存button, 不支持顺序读写 + * 适合用于频繁增删的一组button + * Created by GUY on 2015/8/10. + * @class BI.ButtonMap + * @extends BI.ButtonTree + */ + +BI.ButtonMap = BI.inherit(BI.ButtonTree, { + _defaultConfig: function () { + return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-button-map" + }) + }, + + _init: function () { + BI.ButtonMap.superclass._init.apply(this, arguments); + }, + + _createBtns: function (items) { + var self = this, o = this.options; + var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); + var keys = BI.map(items, function (i, item) { + item = BI.stripEL(item); + if (!(item.id || item.value)) { + throw new Error("item必须包含id或value属性"); + } + return item.id || item.value; + }); + return BI.object(keys, buttons); + }, + + setValue: function (v) { + var self = this; + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (val, item) { + if (!BI.isFunction(item.setSelected)) { + item.setValue(v); + return; + } + if (v.contains(val)) { + item.setSelected && item.setSelected(true); + } else { + item.setSelected && item.setSelected(false); + } + }); + }, + + setNotSelectedValue: function (v) { + var self = this; + v = BI.isArray(v) ? v : [v]; + BI.each(this.buttons, function (val, item) { + if (!BI.isFunction(item.setSelected)) { + item.setNotSelectedValue(v); + return; + } + if (v.contains(val)) { + item.setSelected && item.setSelected(false); + } else { + item.setSelected && item.setSelected(true); + } + }); + }, + + populate: function (items) { + var self = this; + var args = [].slice.call(arguments); + var linkHashMap = new BI.LinkHashMap(); + var val = function (item) { + return item.id || item.value; + }; + if (!this.buttons) { + this.buttons = {}; + } + //所有已存在的和新添加的 + var willCreated = []; + BI.each(items, function (i, item) { + item = BI.stripEL(item); + if (self.buttons[val(item)]) { + var ob = self.buttons[val(item)]; + args[0] = item.items; + args[2] = item; + ob.populate && ob.populate.apply(ob, args); + } else { + willCreated.push(item); + } + }); + //创建新元素 + args[0] = willCreated; + var newBtns = this._btnsCreator.apply(this, args); + + //整理 + var array = []; + BI.each(items, function (i, item) { + item = BI.stripEL(item); + var button = self.buttons[val(item)] || newBtns[val(item)]; + linkHashMap.add(val(item), button); + array.push(button); + }); + this.buttons = linkHashMap.map; + + BI.DOM.hang(this.buttons); + this.empty(); + + var packages = this._packageItems(items, this._packageBtns(array)); + BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); + }, + + getIndexByValue: function (value) { + throw new Error("不能使用getIndexByValue方法"); + } +}); +BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; + +$.shortcut("bi.button_map", BI.ButtonMap); \ No newline at end of file diff --git a/src/base/combination/navigation.js b/src/base/combination/navigation.js index 4e2f13b48..524821ce3 100644 --- a/src/base/combination/navigation.js +++ b/src/base/combination/navigation.js @@ -127,6 +127,10 @@ BI.Navigation = BI.inherit(BI.Widget, { empty: function(){ this.layout.deleteAllCard(); this.cardMap = {}; + }, + + destroy: function(){ + BI.Navigation.superclass.destroy.apply(this, arguments); } }); BI.Navigation.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/combination/searcher.js b/src/base/combination/searcher.js index 1c441664c..c4dae3418 100644 --- a/src/base/combination/searcher.js +++ b/src/base/combination/searcher.js @@ -90,27 +90,26 @@ BI.Searcher = BI.inherit(BI.Widget, { type: "bi.searcher_view", chooseType: o.chooseType }); - BI.Maskers.create(this.getName(), o.adapter, { - offset: o.masker.offset, + BI.Maskers.create(this.getName(), o.adapter, BI.extend({ container: this, render: this.popupView - }); + }, o.masker)); this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { if (o.isAutoSync) { - var values = o.adapter.getValue(); + var values = o.adapter && o.adapter.getValue(); if (!obj.isSelected()) { - o.adapter.setValue(BI.deepWithout(values, obj.getValue())); + o.adapter && o.adapter.setValue(BI.deepWithout(values, obj.getValue())); } else { switch (o.chooseType) { case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: - o.adapter.setValue([obj.getValue()]); + o.adapter && o.adapter.setValue([obj.getValue()]); break; case BI.ButtonGroup.CHOOSE_TYPE_MULTI: values.push(obj.getValue()); - o.adapter.setValue(values); + o.adapter && o.adapter.setValue(values); break; } } @@ -140,7 +139,9 @@ BI.Searcher = BI.inherit(BI.Widget, { _pauseSearch: function () { var o = this.options, name = this.getName(); this._stop = true; - BI.Maskers.hide(name); + BI.nextTick(function (name) { + BI.Maskers.hide(name); + }, this.getName()); if (BI.Maskers.has(name) && this._isSearching === true) { this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); this.fireEvent(BI.Searcher.EVENT_PAUSE); @@ -181,7 +182,7 @@ BI.Searcher = BI.inherit(BI.Widget, { o.onSearch({ times: 1, keyword: keyword, - selectedValues: o.adapter.getValue() + selectedValues: o.adapter && o.adapter.getValue() }, function (searchResult, matchResult) { if (!self._stop) { var args = [].slice.call(arguments); @@ -190,7 +191,7 @@ BI.Searcher = BI.inherit(BI.Widget, { } BI.Maskers.show(self.getName()); self.popupView.populate.apply(self.popupView, args); - o.isAutoSync && self.popupView.setValue(o.adapter.getValue()); + o.isAutoSync && self.popupView.setValue(o.adapter && o.adapter.getValue()); self.popupView.loaded && self.popupView.loaded(); self.fireEvent(BI.Searcher.EVENT_SEARCHING); } @@ -258,6 +259,10 @@ BI.Searcher = BI.inherit(BI.Widget, { return this.editor.getValue(); }, + getKeywords: function () { + return this.editor.getKeywords(); + }, + getValue: function () { var o = this.options; if (o.isAutoSync) { @@ -283,9 +288,9 @@ BI.Searcher = BI.inherit(BI.Widget, { this.popupView && this.popupView.empty(); }, - destroyed: function () { - this.popupView && this.popupView.destroy(); + destroy: function () { BI.Maskers.remove(this.getName()); + BI.Searcher.superclass.destroy.apply(this, arguments); } }); BI.Searcher.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/combination/switcher.js b/src/base/combination/switcher.js index 1a624481f..d7468578f 100644 --- a/src/base/combination/switcher.js +++ b/src/base/combination/switcher.js @@ -258,8 +258,8 @@ BI.Switcher = BI.inherit(BI.Widget, { this.popupView && this.popupView.empty(); }, - destroyed: function () { - this.popupView && this.popupView.destroy(); + destroy: function () { + BI.Switcher.superclass.destroy.apply(this, arguments); } }); BI.Switcher.EVENT_EXPAND = "EVENT_EXPAND"; diff --git a/src/base/combination/tab.js b/src/base/combination/tab.js index 74c874938..f12d3a150 100644 --- a/src/base/combination/tab.js +++ b/src/base/combination/tab.js @@ -114,9 +114,9 @@ BI.Tab = BI.inherit(BI.Widget, { this.cardMap = {}; }, - destroyed: function () { - this.layout.deleteAllCard(); + destroy: function () { this.cardMap = {}; + BI.Tab.superclass.destroy.apply(this, arguments); } }); BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/combination/tree.button.js b/src/base/combination/tree.button.js index 4b8bda42d..85afc684d 100644 --- a/src/base/combination/tree.button.js +++ b/src/base/combination/tree.button.js @@ -179,120 +179,4 @@ BI.ButtonTree = BI.inherit(BI.ButtonGroup, { }); BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.button_tree", BI.ButtonTree); - -/** - * value作为key值缓存button, 不支持顺序读写 - * 适合用于频繁增删的一组button - * Created by GUY on 2015/8/10. - * @class BI.ButtonMap - * @extends BI.ButtonTree - */ - -BI.ButtonMap = BI.inherit(BI.ButtonTree, { - _defaultConfig: function () { - return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-map" - }) - }, - - _init: function () { - BI.ButtonMap.superclass._init.apply(this, arguments); - }, - - _createBtns: function (items) { - var self = this, o = this.options; - var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); - var keys = BI.map(items, function (i, item) { - item = BI.stripEL(item); - if (!(item.id || item.value)) { - throw new Error("item必须包含id或value属性"); - } - return item.id || item.value; - }); - return BI.object(keys, buttons); - }, - - setValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); - }, - - setNotSelectedValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); - }, - - populate: function (items) { - var self = this; - var args = [].slice.call(arguments); - var linkHashMap = new BI.LinkHashMap(); - var val = function (item) { - return item.id || item.value; - }; - if (!this.buttons) { - this.buttons = {}; - } - //所有已存在的和新添加的 - var willCreated = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - if (self.buttons[val(item)]) { - var ob = self.buttons[val(item)]; - args[0] = item.items; - args[2] = item; - ob.populate && ob.populate.apply(ob, args); - } else { - willCreated.push(item); - } - }); - //创建新元素 - args[0] = willCreated; - var newBtns = this._btnsCreator.apply(this, args); - - //整理 - var array = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - var button = self.buttons[val(item)] || newBtns[val(item)]; - linkHashMap.add(val(item), button); - array.push(button); - }); - this.buttons = linkHashMap.map; - - BI.DOM.hang(this.buttons); - this.empty(); - - var packages = this._packageItems(items, this._packageBtns(array)); - BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); - }, - - getIndexByValue: function (value) { - throw new Error("不能使用getIndexByValue方法"); - } -}); -BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; - -$.shortcut("bi.button_map", BI.ButtonMap); \ No newline at end of file +$.shortcut("bi.button_tree", BI.ButtonTree); \ No newline at end of file diff --git a/src/base/farbtastic/farbtastic.js b/src/base/farbtastic/farbtastic.js index 0fb9cac6f..a243d31ee 100644 --- a/src/base/farbtastic/farbtastic.js +++ b/src/base/farbtastic/farbtastic.js @@ -18,6 +18,8 @@ BI.Farbtastic = BI.inherit(BI.Widget, { _init: function () { BI.Farbtastic.superclass._init.apply(this, arguments); var self = this; + FR.$defaultImport('/com/fr/bi/web/js/third/farbtastic.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/css/base/third/farbtastic/farbtastic.css', 'css'); this.farbtastic = $.farbtastic(this.element, function (v) { self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); diff --git a/src/base/formula/codemirror/addon/formula-hint.js b/src/base/formula/codemirror/addon/formula-hint.js new file mode 100644 index 000000000..f35f859ff --- /dev/null +++ b/src/base/formula/codemirror/addon/formula-hint.js @@ -0,0 +1,88 @@ +(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + var Pos = CodeMirror.Pos; + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, keywords, getToken, options) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur); + if (/\b(?:string)\b/.test(token.type)) { + return; + } + token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; + + if (!/^[\w$_]*$/.test(token.string)) { + token = { + start: cur.ch, end: cur.ch, string: "", state: token.state, + type: token.string == "." ? "property" : null + }; + } else if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + var tprop = token; + // If it is a property, find out what it is a property of. + while (tprop.type == "property") { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string != ".") return; + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (!context) var context = []; + context.push(tprop); + } + return { + list: getCompletions(token, context, keywords, options), + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end) + }; + } + + function getFormulaKeywords() { + return FormulaCollections; + } + + function formulaHint(editor, options) { + return scriptHint(editor, getFormulaKeywords(), + function (e, cur) { + return e.getTokenAt(cur); + }, + options); + }; + CodeMirror.registerHelper("hint", "formula", formulaHint); + + function getCompletions(token, context, keywords, options) { + var found = [], start = token.string; + if (!start) { + return found; + } + function maybeAdd(str) { + if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) { + found.push(str); + } + } + + if (context && context.length) { + context.pop(); + } else { + forEach(keywords, maybeAdd); + } + return found; + } +}); \ No newline at end of file diff --git a/src/base/formula/codemirror/addon/formula-mode.js b/src/base/formula/codemirror/addon/formula-mode.js new file mode 100644 index 000000000..b56509ee7 --- /dev/null +++ b/src/base/formula/codemirror/addon/formula-mode.js @@ -0,0 +1,80 @@ +(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + "use strict"; + + CodeMirror.defineMode('formula', function () { + function wordObj(words) { + var o = {}; + for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; + return o; + } + + var atoms = wordObj(['false', 'true']); + var keywords = wordObj(FormulaCollections); + + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return null; + } + var ch = stream.next(); + + if (ch === '"' || ch === '\'') { + nextUntilUnescaped(stream, ch); + return "string"; + } + if (/[\[\],\(\)]/.test(ch)) { + return 'bracket'; + } + + // richie:暂时不需要解析操作符号 + //if (/[+\-*\/=<>!&|]/.test(ch)) { + // return 'operator'; + //} + //if (/\d|\d./.test(ch)) { + // stream.eatWhile(/\d|\./); + // if (stream.eol() || !/\w/.test(stream.peek())) { + // return 'number'; + // } + //} + + + + stream.eatWhile(/[\w-]/); + var word = stream.current(); + if (atoms.hasOwnProperty(word)) { + return "atom"; + } + if (keywords.hasOwnProperty(word)) { + return "keyword"; + } + return null; + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next === end && !escaped) { + return false; + } + escaped = !escaped && next === "\\"; + } + return escaped; + } + + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase)(stream, state); + } + + return { + startState: function () { + return {tokens: []}; + }, + token: function (stream, state) { + return tokenize(stream, state); + }, + fold: "brace" + }; + }); + CodeMirror.defineMIME("text/fx-formula", "formula"); +}); \ No newline at end of file diff --git a/src/base/formula/codemirror/addon/show-hint.js b/src/base/formula/codemirror/addon/show-hint.js new file mode 100644 index 000000000..1fb9b7f41 --- /dev/null +++ b/src/base/formula/codemirror/addon/show-hint.js @@ -0,0 +1,432 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function (mod) { + mod(CodeMirror); +})(function (CodeMirror) { + "use strict"; + + var HINT_ELEMENT_CLASS = "CodeMirror-hint"; + var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; + + // This is the old interface, kept around for now to stay + // backwards-compatible. + CodeMirror.showHint = function (cm, getHints, options) { + if (!getHints) return cm.showHint(options); + if (options && options.async) getHints.async = true; + var newOpts = {hint: getHints}; + if (options) for (var prop in options) newOpts[prop] = options[prop]; + return cm.showHint(newOpts); + }; + + CodeMirror.defineExtension("showHint", function (options) { + // We want a single cursor position. + if (this.listSelections().length > 1 || this.somethingSelected()) return; + + if (this.state.completionActive) this.state.completionActive.close(); + var completion = this.state.completionActive = new Completion(this, options); + if (!completion.options.hint) return; + + CodeMirror.signal(this, "startCompletion", this); + completion.update(true); + }); + + function Completion(cm, options) { + this.cm = cm; + this.options = this.buildOptions(options); + this.widget = null; + this.debounce = 0; + this.tick = 0; + this.startPos = this.cm.getCursor(); + this.startLen = this.cm.getLine(this.startPos.line).length; + + var self = this; + cm.on("cursorActivity", this.activityFunc = function () { + self.cursorActivity(); + }); + } + + var requestAnimationFrame = window.requestAnimationFrame || function (fn) { + return setTimeout(fn, 1000 / 60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + + Completion.prototype = { + close: function () { + if (!this.active()) return; + this.cm.state.completionActive = null; + this.tick = null; + this.cm.off("cursorActivity", this.activityFunc); + + if (this.widget && this.data) CodeMirror.signal(this.data, "close"); + if (this.widget) this.widget.close(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, + + active: function () { + return this.cm.state.completionActive == this; + }, + + pick: function (data, i) { + var completion = data.list[i]; + if (completion.hint) completion.hint(this.cm, data, completion); + else { + this.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + var to = this.cm.getCursor(); + this.cm.markText(completion.from || data.from, to, {className: "#function", atomic: true}); + this.cm.replaceSelection("() "); + to = this.cm.getCursor(); + to.ch = to.ch - 2; + this.cm.setCursor(to); + this.cm.focus(); + } + CodeMirror.signal(data, "pick", completion); + this.close(); + }, + + cursorActivity: function () { + if (this.debounce) { + cancelAnimationFrame(this.debounce); + this.debounce = 0; + } + + var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); + if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || + pos.ch < this.startPos.ch || this.cm.somethingSelected() || + (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { + this.close(); + } else { + var self = this; + this.debounce = requestAnimationFrame(function () { + self.update(); + }); + if (this.widget) this.widget.disable(); + } + }, + + update: function (first) { + if (this.tick == null) return; + if (this.data) CodeMirror.signal(this.data, "update"); + if (!this.options.hint.async) { + this.finishUpdate(this.options.hint(this.cm, this.options), first); + } else { + var myTick = ++this.tick, self = this; + this.options.hint(this.cm, function (data) { + if (self.tick == myTick) self.finishUpdate(data, first); + }, this.options); + } + }, + + finishUpdate: function (data, first) { + this.data = data; + + var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); + if (this.widget) this.widget.close(); + if (data && data.list.length) { + if (picked && data.list.length == 1) { + this.pick(data, 0); + } else { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + } + } + }, + + buildOptions: function (options) { + var editor = this.cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + return out; + } + }; + + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } + + function buildKeyMap(completion, handle) { + var baseMap = { + Up: function () { + handle.moveFocus(-1); + }, + Down: function () { + handle.moveFocus(1); + }, + PageUp: function () { + handle.moveFocus(-handle.menuSize() + 1, true); + }, + PageDown: function () { + handle.moveFocus(handle.menuSize() - 1, true); + }, + Home: function () { + handle.setFocus(0); + }, + End: function () { + handle.setFocus(handle.length - 1); + }, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + var custom = completion.options.customKeys; + var ourMap = custom ? {} : baseMap; + + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function (cm) { + return val(cm, handle); + }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } + + if (custom) + for (var key in custom) if (custom.hasOwnProperty(key)) + addBinding(key, custom[key]); + var extra = completion.options.extraKeys; + if (extra) + for (var key in extra) if (extra.hasOwnProperty(key)) + addBinding(key, extra[key]); + return ourMap; + } + + function getHintElement(hintsElement, el) { + while (el && el != hintsElement) { + if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; + el = el.parentNode; + } + } + + function Widget(completion, data) { + this.completion = completion; + this.data = data; + this.picked = false; + var widget = this, cm = completion.cm; + + var hints = this.hints = document.createElement("ul"); + hints.className = "CodeMirror-hints"; + this.selectedHint = data.selectedHint || 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + } + + var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + hints.style.left = left + "px"; + hints.style.top = top + "px"; + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. + var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); + var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); + (completion.options.container || document.body).appendChild(hints); + var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + hints.style.top = (top = pos.top - height) + "px"; + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) + "px"; + hints.style.top = (top = pos.bottom - box.top) + "px"; + var cursor = cm.getCursor(); + if (data.from.ch != cursor.ch) { + pos = cm.cursorCoords(cursor); + hints.style.left = (left = pos.left) + "px"; + box = hints.getBoundingClientRect(); + } + } + } + var overlapX = box.right - winW; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX) + "px"; + } + + cm.addKeyMap(this.keyMap = buildKeyMap(completion, { + moveFocus: function (n, avoidWrap) { + widget.changeActive(widget.selectedHint + n, avoidWrap); + }, + setFocus: function (n) { + widget.changeActive(n); + }, + menuSize: function () { + return widget.screenAmount(); + }, + length: completions.length, + close: function () { + completion.close(); + }, + pick: function () { + widget.pick(); + }, + data: data + })); + + if (completion.options.closeOnUnfocus) { + var closingOnBlur; + cm.on("blur", this.onBlur = function () { + closingOnBlur = setTimeout(function () { + completion.close(); + }, 100); + }); + cm.on("focus", this.onFocus = function () { + clearTimeout(closingOnBlur); + }); + } + + var startScroll = cm.getScrollInfo(); + cm.on("scroll", this.onScroll = function () { + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) + "px"; + }); + + CodeMirror.on(hints, "dblclick", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + widget.pick(); + } + }); + + CodeMirror.on(hints, "click", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + if (completion.options.completeOnSingleClick) widget.pick(); + } + }); + + CodeMirror.on(hints, "mousedown", function () { + setTimeout(function () { + cm.focus(); + }, 20); + }); + + CodeMirror.signal(data, "select", completions[0], hints.firstChild); + return true; + } + + Widget.prototype = { + close: function () { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); + + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, + + disable: function () { + this.completion.cm.removeKeyMap(this.keyMap); + var widget = this; + this.keyMap = { + Enter: function () { + widget.picked = true; + } + }; + this.completion.cm.addKeyMap(this.keyMap); + }, + + pick: function () { + this.completion.pick(this.data, this.selectedHint); + }, + + changeActive: function (i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; + if (node.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node.offsetTop - 3; + else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, + + screenAmount: function () { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + } + }; + + CodeMirror.registerHelper("hint", "auto", function (cm, options) { + var helpers = cm.getHelpers(cm.getCursor(), "hint"), words; + if (helpers.length) { + for (var i = 0; i < helpers.length; i++) { + var cur = helpers[i](cm, options); + if (cur && cur.list.length) return cur; + } + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + if (words) return CodeMirror.hint.fromList(cm, {words: words}); + } else if (CodeMirror.hint.anyword) { + return CodeMirror.hint.anyword(cm, options); + } + }); + + CodeMirror.registerHelper("hint", "fromList", function (cm, options) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var found = []; + for (var i = 0; i < options.words.length; i++) { + var word = options.words[i]; + if (word.slice(0, token.string.length) == token.string) + found.push(word); + } + + if (found.length) return { + list: found, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + }); + + CodeMirror.commands.autocomplete = CodeMirror.showHint; + + var defaultOptions = { + hint: CodeMirror.hint.auto, + completeSingle: true, + alignWithWord: true, + closeCharacters: /[\s()\[\]{};:>,]/, + closeOnUnfocus: true, + completeOnSingleClick: true, + container: null, + customKeys: null, + extraKeys: null + }; + + CodeMirror.defineOption("hintOptions", null); +}); \ No newline at end of file diff --git a/src/base/formula/codemirror/codemirror.js b/src/base/formula/codemirror/codemirror.js new file mode 100644 index 000000000..870197680 --- /dev/null +++ b/src/base/formula/codemirror/codemirror.js @@ -0,0 +1,8736 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . + +(function(mod) { + this.CodeMirror = mod(); +})(function() { + "use strict"; + + // BROWSER SNIFFING + + // Kludges for bugs and behavior differences that can't be feature + // detected are enabled based on userAgent etc sniffing. + + var gecko = /gecko\/\d/i.test(navigator.userAgent); + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); + var ie = ie_upto10 || ie_11up; + var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); + var webkit = /WebKit\//.test(navigator.userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); + var chrome = /Chrome\//.test(navigator.userAgent); + var presto = /Opera\//.test(navigator.userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); + var phantom = /PhantomJS/.test(navigator.userAgent); + + var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); + var mac = ios || /Mac/.test(navigator.platform); + var windows = /win/i.test(navigator.platform); + + var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); + if (presto_version) presto_version = Number(presto_version[1]); + if (presto_version && presto_version >= 15) { presto = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); + var captureRightClick = gecko || (ie && ie_version >= 9); + + // Optimize some code when these features are not used. + var sawReadOnlySpans = false, sawCollapsedSpans = false; + + // EDITOR CONSTRUCTOR + + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. + + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); + + this.options = options = options ? copyObj(options) : {}; + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false); + setGuttersForLineNumbers(options); + + var doc = options.value; + if (typeof doc == "string") doc = new Doc(doc, options.mode); + this.doc = doc; + + var input = new CodeMirror.inputStyles[options.inputStyle](this); + var display = this.display = new Display(place, doc, input); + display.wrapper.CodeMirror = this; + updateGutters(this); + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + if (options.autofocus && !mobile) display.input.focus(); + initScrollbars(this); + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + }; + + var cm = this; + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); + + registerEventHandlers(this); + ensureGlobalHandlers(); + + startOperation(this); + this.curOp.forceUpdate = true; + attachDoc(this, doc); + + if ((options.autofocus && !mobile) || cm.hasFocus()) + setTimeout(bind(onFocus, this), 20); + else + onBlur(this); + + for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](this, options[opt], Init); + maybeUpdateLineNumberWidth(this); + if (options.finishInit) options.finishInit(this); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); + endOperation(this); + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + display.lineDiv.style.textRendering = "auto"; + } + + // DISPLAY CONSTRUCTOR + + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc, input) { + var d = this; + this.input = input; + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.scrollbarFiller.setAttribute("cm-not-content", "true"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + d.gutterFiller.setAttribute("cm-not-content", "true"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = elt("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + d.sizerWidth = null; + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; + + if (place) { + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + d.reportedViewFrom = d.reportedViewTo = doc.first; + // Information about the rendered lines. + d.view = []; + d.renderedView = null; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastWrapHeight = d.lastWrapWidth = 0; + d.updateLineNumbers = null; + + d.nativeBarWidth = d.barHeight = d.barWidth = 0; + d.scrollbarsClipped = false; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + // True when shift is held down. + d.shift = false; + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null; + + d.activeTouch = null; + + input.init(d); + } + + // STATE UPDATES + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } + + function resetModeState(cm) { + cm.doc.iter(function(line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap"); + cm.display.sizer.style.minWidth = ""; + cm.display.sizerWidth = null; + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap"); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function(){updateScrollbars(cm);}, 100); + } + + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function(line) { + if (lineIsHidden(cm.doc, line)) return 0; + + var widgetsHeight = 0; + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; + } + + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; + else + return widgetsHeight + th; + }; + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function(line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function(){alignHorizontally(cm);}, 20); + } + + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + updateGutterSpace(cm); + } + + function updateGutterSpace(cm) { + var width = cm.display.gutters.offsetWidth; + cm.display.sizer.style.marginLeft = width + "px"; + } + + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(0, true); + len -= cur.text.length - found.from.ch; + cur = found.to.line; + len += cur.text.length - found.to.ch; + } + return len; + } + + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function(line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(found, 1); + } + } + + // SCROLLBARS + + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth; + var docH = Math.round(cm.doc.height + paddingVert(cm.display)); + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + }; + } + + function NativeScrollbars(place, scroll, cm) { + this.cm = cm; + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + place(vert); place(horiz); + + on(vert, "scroll", function() { + if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); + }); + on(horiz, "scroll", function() { + if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); + }); + + this.checkedOverlay = false; + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; + } + + NativeScrollbars.prototype = copyObj({ + update: function(measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + var sWidth = measure.nativeBarWidth; + + if (needsV) { + this.vert.style.display = "block"; + this.vert.style.bottom = needsH ? sWidth + "px" : "0"; + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; + } else { + this.vert.style.display = ""; + this.vert.firstChild.style.height = "0"; + } + + if (needsH) { + this.horiz.style.display = "block"; + this.horiz.style.right = needsV ? sWidth + "px" : "0"; + this.horiz.style.left = measure.barLeft + "px"; + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); + this.horiz.firstChild.style.width = + (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; + } else { + this.horiz.style.display = ""; + this.horiz.firstChild.style.width = "0"; + } + + if (!this.checkedOverlay && measure.clientHeight > 0) { + if (sWidth == 0) this.overlayHack(); + this.checkedOverlay = true; + } + + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}; + }, + setScrollLeft: function(pos) { + if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; + }, + setScrollTop: function(pos) { + if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; + }, + overlayHack: function() { + var w = mac && !mac_geMountainLion ? "12px" : "18px"; + this.horiz.style.minHeight = this.vert.style.minWidth = w; + var self = this; + var barMouseDown = function(e) { + if (e_target(e) != self.vert && e_target(e) != self.horiz) + operation(self.cm, onMouseDown)(e); + }; + on(this.vert, "mousedown", barMouseDown); + on(this.horiz, "mousedown", barMouseDown); + }, + clear: function() { + var parent = this.horiz.parentNode; + parent.removeChild(this.horiz); + parent.removeChild(this.vert); + } + }, NativeScrollbars.prototype); + + function NullScrollbars() {} + + NullScrollbars.prototype = copyObj({ + update: function() { return {bottom: 0, right: 0}; }, + setScrollLeft: function() {}, + setScrollTop: function() {}, + clear: function() {} + }, NullScrollbars.prototype); + + CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; + + function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear(); + if (cm.display.scrollbars.addClass) + rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function() { + if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0); + }); + node.setAttribute("cm-not-content", "true"); + }, function(pos, axis) { + if (axis == "horizontal") setScrollLeft(cm, pos); + else setScrollTop(cm, pos); + }, cm); + if (cm.display.scrollbars.addClass) + addClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm); + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; + updateScrollbarsInner(cm, measure); + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + updateHeightsInViewport(cm); + updateScrollbarsInner(cm, measureForScrollbars(cm)); + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; + } + } + + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbarsInner(cm, measure) { + var d = cm.display; + var sizes = d.scrollbars.update(measure); + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = sizes.bottom + "px"; + d.scrollbarFiller.style.width = sizes.right + "px"; + } else d.scrollbarFiller.style.display = ""; + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = sizes.bottom + "px"; + d.gutterFiller.style.width = measure.gutterWidth + "px"; + } else d.gutterFiller.style.display = ""; + } + + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewport may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; + if (ensureFrom < from) { + from = ensureFrom; + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); + to = ensureTo; + } + } + return {from: from, to: Math.max(to, from + 1)}; + } + + // LINE NUMBERS + + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter && view[i].gutter) + view[i].gutter.style.left = left; + var align = view[i].alignable; + if (align) for (var j = 0; j < align.length; j++) + align[j].style.left = left; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } + + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + updateGutterSpace(cm); + return true; + } + return false; + } + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } + + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; + } + + // DISPLAY DRAWING + + function DisplayUpdate(cm, viewport, force) { + var display = cm.display; + + this.viewport = viewport; + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport); + this.editorIsHidden = !display.wrapper.offsetWidth; + this.wrapperHeight = display.wrapper.clientHeight; + this.wrapperWidth = display.wrapper.clientWidth; + this.oldDisplayWidth = displayWidth(cm); + this.force = force; + this.dims = getDimensions(cm); + this.events = []; + } + + DisplayUpdate.prototype.signal = function(emitter, type) { + if (hasHandler(emitter, type)) + this.events.push(arguments); + }; + DisplayUpdate.prototype.finish = function() { + for (var i = 0; i < this.events.length; i++) + signal.apply(null, this.events[i]); + }; + + function maybeClipScrollbars(cm) { + var display = cm.display; + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; + display.heightForcer.style.height = scrollGap(cm) + "px"; + display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; + display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; + display.scrollbarsClipped = true; + } + } + + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc; + + if (update.editorIsHidden) { + resetView(cm); + return false; + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + return false; + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm); + update.dims = getDimensions(cm); + } + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, update.visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; + adjustView(cm, from, to); + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; + + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + return false; + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var focused = activeElt(); + if (toUpdate > 4) display.lineDiv.style.display = "none"; + patchDisplay(cm, display.updateLineNumbers, update.dims); + if (toUpdate > 4) display.lineDiv.style.display = ""; + display.renderedView = display.view; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + display.gutters.style.height = 0; + + if (different) { + display.lastWrapHeight = update.wrapperHeight; + display.lastWrapWidth = update.wrapperWidth; + startWorker(cm, 400); + } + + display.updateLineNumbers = null; + + return true; + } + + function postUpdateDisplay(cm, update) { + var viewport = update.viewport; + for (var first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport); + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + break; + } + if (!updateDisplayIfNeeded(cm, update)) break; + updateHeightsInViewport(cm); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + setDocumentHeight(cm, barMeasure); + updateScrollbars(cm, barMeasure); + } + + update.signal(cm, "update", cm); + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; + } + } + + function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport); + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm); + postUpdateDisplay(cm, update); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + setDocumentHeight(cm, barMeasure); + updateScrollbars(cm, barMeasure); + update.finish(); + } + } + + function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px"; + var total = measure.docHeight + cm.display.barHeight; + cm.display.heightForcer.style.top = total + "px"; + cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px"; + } + + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height; + if (cur.hidden) continue; + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + } + var diff = cur.line.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) for (var j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]); + } + } + } + + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) + line.widgets[i].height = line.widgets[i].node.offsetHeight; + } + + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + var gutterLeft = d.gutters.clientLeft; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; + width[cm.options.gutters[i]] = n.clientWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth}; + } + + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none"; + else + node.parentNode.removeChild(node); + return next; + } + + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur); + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; + updateLineForChanges(cm, lineView, lineN, dims); + } + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) cur = rm(cur); + } + + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") updateLineText(cm, lineView); + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); + else if (type == "class") updateLineClasses(lineView); + else if (type == "widget") updateLineWidgets(cm, lineView, dims); + } + lineView.changes = null; + } + + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text); + lineView.node.appendChild(lineView.text); + if (ie && ie_version < 8) lineView.node.style.zIndex = 2; + } + return lineView.node; + } + + function updateLineBackground(lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) cls += " CodeMirror-linebackground"; + if (lineView.background) { + if (cls) lineView.background.className = cls; + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + } + } + + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built; + } + return buildLineContent(cm, lineView); + } + + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) lineView.node = built.pre; + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(lineView); + } else if (cls) { + lineView.text.className = cls; + } + } + + function updateLineClasses(lineView) { + updateLineBackground(lineView); + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass; + else if (lineView.node != lineView.text) + lineView.node.className = ""; + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } + + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; + } + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + + "px; width: " + dims.gutterTotalWidth + "px"); + cm.display.input.setUneditable(gutterWrap); + wrap.insertBefore(gutterWrap, lineView.text); + if (lineView.line.gutterClass) + gutterWrap.className += " " + lineView.line.gutterClass; + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + cm.display.lineNumInnerWidth + "px")); + if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); + } + } + } + + function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) lineView.alignable = null; + for (var node = lineView.node.firstChild, next; node; node = next) { + var next = node.nextSibling; + if (node.className == "CodeMirror-linewidget") + lineView.node.removeChild(node); + } + insertLineWidgets(cm, lineView, dims); + } + + // Build a line's DOM representation from scratch + function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView); + lineView.text = lineView.node = built.pre; + if (built.bgClass) lineView.bgClass = built.bgClass; + if (built.textClass) lineView.textClass = built.textClass; + + updateLineClasses(lineView); + updateLineGutter(cm, lineView, lineN, dims); + insertLineWidgets(cm, lineView, dims); + return lineView.node; + } + + // A lineView may contain multiple logical lines (when merged by + // collapsed spans). The widgets for all of them need to be drawn. + function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); + } + + function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) return; + var wrap = ensureLineWrapped(lineView); + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); + if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); + positionLineWidget(widget, node, lineView, dims); + cm.display.input.setUneditable(node); + if (allowAbove && widget.above) + wrap.insertBefore(node, lineView.gutter || lineView.text); + else + wrap.appendChild(node); + signalLater(widget, "redraw"); + } + } + + function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + (lineView.alignable || (lineView.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; + } + } + + // POSITION OBJECT + + // A Pos instance represents a position within the text. + var Pos = CodeMirror.Pos = function(line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + }; + + // Compare two positions, return 0 if they are the same, a negative + // number when a is less, and a positive number otherwise. + var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; + + function copyPos(x) {return Pos(x.line, x.ch);} + function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } + function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } + + // INPUT HANDLING + + function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } + } + + function isReadOnly(cm) { + return cm.options.readOnly || cm.doc.cantEdit; + } + + // This will be set to an array of strings when copying, so that, + // when pasting, we know what kind of selections the copied text + // was made out of. + var lastCopied = null; + + function applyTextInput(cm, inserted, deleted, sel, origin) { + var doc = cm.doc; + cm.display.shift = false; + if (!sel) sel = doc.sel; + + var paste = cm.state.pasteIncoming || origin == "paste"; + var textLines = splitLines(inserted), multiPaste = null; + // When pasing N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.join("\n") == inserted) + multiPaste = sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines); + else if (textLines.length == sel.ranges.length) + multiPaste = map(textLines, function(l) { return [l]; }); + } + + // Normal behavior is to insert the new text into every selection + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + var from = range.from(), to = range.to(); + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + from = Pos(from.line, from.ch - deleted); + else if (cm.state.overwrite && !paste) // Handle overwrite + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); + } + var updateInput = cm.curOp.updateInput; + var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")}; + makeChange(cm.doc, changeEvent); + signalLater(cm, "inputRead", cm, changeEvent); + } + if (inserted && !paste) + triggerElectric(cm, inserted); + + ensureCursorVisible(cm); + cm.curOp.updateInput = updateInput; + cm.curOp.typing = true; + cm.state.pasteIncoming = cm.state.cutIncoming = false; + } + + function handlePaste(e, cm) { + var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); + if (pasted) { + e.preventDefault(); + runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); }); + return true; + } + } + + function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) return; + var sel = cm.doc.sel; + + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; + var mode = cm.getModeAt(range.head); + var indented = false; + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart"); + break; + } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + indented = indentLine(cm, range.head.line, "smart"); + } + if (indented) signalLater(cm, "electricInput", cm, range.head.line); + } + } + + function copyableRanges(cm) { + var text = [], ranges = []; + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line; + var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; + ranges.push(lineRange); + text.push(cm.getRange(lineRange.anchor, lineRange.head)); + } + return {text: text, ranges: ranges}; + } + + function disableBrowserMagic(field) { + field.setAttribute("autocorrect", "off"); + field.setAttribute("autocapitalize", "off"); + field.setAttribute("spellcheck", "false"); + } + + // TEXTAREA INPUT STYLE + + function TextareaInput(cm) { + this.cm = cm; + // See input.poll and input.reset + this.prevInput = ""; + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false; + // Self-resetting timeout for the poller + this.polling = new Delayed(); + // Tracks when input.reset has punted to just putting a short + // string into the textarea instead of the full selection. + this.inaccurateSelection = false; + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false; + this.composing = null; + }; + + function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) te.style.width = "1000px"; + else te.setAttribute("wrap", "off"); + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) te.style.border = "1px solid black"; + disableBrowserMagic(te); + return div; + } + + TextareaInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = this.cm; + + // Wraps and hides input textarea + var div = this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var te = this.textarea = div.firstChild; + display.wrapper.insertBefore(div, display.wrapper.firstChild); + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) te.style.width = "0px"; + + on(te, "input", function() { + if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; + input.poll(); + }); + + on(te, "paste", function(e) { + if (handlePaste(e, cm)) return true; + + cm.state.pasteIncoming = true; + input.fastPoll(); + }); + + function prepareCopyCut(e) { + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (input.inaccurateSelection) { + input.prevInput = ""; + input.inaccurateSelection = false; + te.value = lastCopied.join("\n"); + selectInput(te); + } + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll); + } else { + input.prevInput = ""; + te.value = ranges.text.join("\n"); + selectInput(te); + } + } + if (e.type == "cut") cm.state.cutIncoming = true; + } + on(te, "cut", prepareCopyCut); + on(te, "copy", prepareCopyCut); + + on(display.scroller, "paste", function(e) { + if (eventInWidget(display, e)) return; + cm.state.pasteIncoming = true; + input.focus(); + }); + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function(e) { + if (!eventInWidget(display, e)) e_preventDefault(e); + }); + + on(te, "compositionstart", function() { + var start = cm.getCursor("from"); + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + }; + }); + on(te, "compositionend", function() { + if (input.composing) { + input.poll(); + input.composing.range.clear(); + input.composing = null; + } + }); + }, + + prepareSelection: function() { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc; + var result = prepareSelection(cm); + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + } + + return result; + }, + + showSelection: function(drawn) { + var cm = this.cm, display = cm.display; + removeChildrenAndAdd(display.cursorDiv, drawn.cursors); + removeChildrenAndAdd(display.selectionDiv, drawn.selection); + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px"; + this.wrapper.style.left = drawn.teLeft + "px"; + } + }, + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + reset: function(typing) { + if (this.contextMenuPending) return; + var minimal, selected, cm = this.cm, doc = cm.doc; + if (cm.somethingSelected()) { + this.prevInput = ""; + var range = doc.sel.primary(); + minimal = hasCopyEvent && + (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + this.textarea.value = content; + if (cm.state.focused) selectInput(this.textarea); + if (ie && ie_version >= 9) this.hasSelection = content; + } else if (!typing) { + this.prevInput = this.textarea.value = ""; + if (ie && ie_version >= 9) this.hasSelection = null; + } + this.inaccurateSelection = minimal; + }, + + getField: function() { return this.textarea; }, + + supportsTouch: function() { return false; }, + + focus: function() { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus(); } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } + }, + + blur: function() { this.textarea.blur(); }, + + resetPosition: function() { + this.wrapper.style.top = this.wrapper.style.left = 0; + }, + + receivedFocus: function() { this.slowPoll(); }, + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + slowPoll: function() { + var input = this; + if (input.pollingFast) return; + input.polling.set(this.cm.options.pollInterval, function() { + input.poll(); + if (input.cm.state.focused) input.slowPoll(); + }); + }, + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + fastPoll: function() { + var missed = false, input = this; + input.pollingFast = true; + function p() { + var changed = input.poll(); + if (!changed && !missed) {missed = true; input.polling.set(60, p);} + else {input.pollingFast = false; input.slowPoll();} + } + input.polling.set(20, p); + }, + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + poll: function() { + var cm = this.cm, input = this.textarea, prevInput = this.prevInput; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput) || + isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq) + return false; + + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false; + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset(); + return false; + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0); + if (first == 0x200b && !prevInput) prevInput = "\u200b"; + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; + + var self = this; + runInOp(cm, function() { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, self.composing ? "*compose" : null); + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; + else self.prevInput = text; + + if (self.composing) { + self.composing.range.clear(); + self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}); + } + }); + return true; + }, + + ensurePolled: function() { + if (this.pollingFast && this.poll()) this.pollingFast = false; + }, + + onKeyPress: function() { + if (ie && ie_version >= 9) this.hasSelection = null; + this.fastPoll(); + }, + + onContextMenu: function(e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea; + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) return; // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); + + var oldCSS = te.style.cssText; + input.wrapper.style.position = "absolute"; + te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + + "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + + "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) + display.input.focus(); + if (webkit) window.scrollTo(null, oldScrollY); + display.input.reset(); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) te.value = input.prevInput = " "; + input.contextMenuPending = true; + display.selForContextMenu = cm.doc.sel; + clearTimeout(display.detectingSelectAll); + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected(); + var extval = "\u200b" + (selected ? te.value : ""); + te.value = "\u21da"; // Used to catch context-menu undo + te.value = extval; + input.prevInput = selected ? "" : "\u200b"; + te.selectionStart = 1; te.selectionEnd = extval.length; + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel; + } + } + function rehide() { + input.contextMenuPending = false; + input.wrapper.style.position = "relative"; + te.style.cssText = oldCSS; + if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); + var i = 0, poll = function() { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); + else display.input.reset(); + }; + display.detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && ie_version >= 9) prepareSelectAllHack(); + if (captureRightClick) { + e_stop(e); + var mouseup = function() { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + }, + + setUneditable: nothing, + + needsContentAttribute: false + }, TextareaInput.prototype); + + // CONTENTEDITABLE INPUT STYLE + + function ContentEditableInput(cm) { + this.cm = cm; + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; + this.polling = new Delayed(); + this.gracePeriod = false; + } + + ContentEditableInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = input.cm; + var div = input.div = display.lineDiv; + div.contentEditable = "true"; + disableBrowserMagic(div); + + on(div, "paste", function(e) { handlePaste(e, cm); }) + + on(div, "compositionstart", function(e) { + var data = e.data; + input.composing = {sel: cm.doc.sel, data: data, startData: data}; + if (!data) return; + var prim = cm.doc.sel.primary(); + var line = cm.getLine(prim.head.line); + var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); + if (found > -1 && found <= prim.head.ch) + input.composing.sel = simpleSelection(Pos(prim.head.line, found), + Pos(prim.head.line, found + data.length)); + }); + on(div, "compositionupdate", function(e) { + input.composing.data = e.data; + }); + on(div, "compositionend", function(e) { + var ours = input.composing; + if (!ours) return; + if (e.data != ours.startData && !/\u200b/.test(e.data)) + ours.data = e.data; + // Need a small delay to prevent other code (input event, + // selection polling) from doing damage when fired right after + // compositionend. + setTimeout(function() { + if (!ours.handled) + input.applyComposition(ours); + if (input.composing == ours) + input.composing = null; + }, 50); + }); + + on(div, "touchstart", function() { + input.forceCompositionEnd(); + }); + + on(div, "input", function() { + if (input.composing) return; + if (!input.pollContent()) + runInOp(input.cm, function() {regChange(cm);}); + }); + + function onCopyCut(e) { + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (e.type == "cut") cm.replaceSelection("", null, "cut"); + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.operation(function() { + cm.setSelections(ranges.ranges, 0, sel_dontScroll); + cm.replaceSelection("", null, "cut"); + }); + } + } + // iOS exposes the clipboard API, but seems to discard content inserted into it + if (e.clipboardData && !ios) { + e.preventDefault(); + e.clipboardData.clearData(); + e.clipboardData.setData("text/plain", lastCopied.join("\n")); + } else { + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild; + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); + te.value = lastCopied.join("\n"); + var hadFocus = document.activeElement; + selectInput(te); + setTimeout(function() { + cm.display.lineSpace.removeChild(kludge); + hadFocus.focus(); + }, 50); + } + } + on(div, "copy", onCopyCut); + on(div, "cut", onCopyCut); + }, + + prepareSelection: function() { + var result = prepareSelection(this.cm, false); + result.focus = this.cm.state.focused; + return result; + }, + + showSelection: function(info) { + if (!info || !this.cm.display.view.length) return; + if (info.focus) this.showPrimarySelection(); + this.showMultipleSelections(info); + }, + + showPrimarySelection: function() { + var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); + var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); + var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && + cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) + return; + + var start = posToDOM(this.cm, prim.from()); + var end = posToDOM(this.cm, prim.to()); + if (!start && !end) return; + + var view = this.cm.display.view; + var old = sel.rangeCount && sel.getRangeAt(0); + if (!start) { + start = {node: view[0].measure.map[2], offset: 0}; + } else if (!end) { // FIXME dangerously hacky + var measure = view[view.length - 1].measure; + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; + } + + try { var rng = range(start.node, start.offset, end.offset, end.node); } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + sel.removeAllRanges(); + sel.addRange(rng); + if (old && sel.anchorNode == null) sel.addRange(old); + else if (gecko) this.startGracePeriod(); + } + this.rememberSelection(); + }, + + startGracePeriod: function() { + var input = this; + clearTimeout(this.gracePeriod); + this.gracePeriod = setTimeout(function() { + input.gracePeriod = false; + if (input.selectionChanged()) + input.cm.operation(function() { input.cm.curOp.selectionChanged = true; }); + }, 20); + }, + + showMultipleSelections: function(info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); + }, + + rememberSelection: function() { + var sel = window.getSelection(); + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; + }, + + selectionInEditor: function() { + var sel = window.getSelection(); + if (!sel.rangeCount) return false; + var node = sel.getRangeAt(0).commonAncestorContainer; + return contains(this.div, node); + }, + + focus: function() { + if (this.cm.options.readOnly != "nocursor") this.div.focus(); + }, + blur: function() { this.div.blur(); }, + getField: function() { return this.div; }, + + supportsTouch: function() { return true; }, + + receivedFocus: function() { + var input = this; + if (this.selectionInEditor()) + this.pollSelection(); + else + runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; }); + + function poll() { + if (input.cm.state.focused) { + input.pollSelection(); + input.polling.set(input.cm.options.pollInterval, poll); + } + } + this.polling.set(this.cm.options.pollInterval, poll); + }, + + selectionChanged: function() { + var sel = window.getSelection(); + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; + }, + + pollSelection: function() { + if (!this.composing && !this.gracePeriod && this.selectionChanged()) { + var sel = window.getSelection(), cm = this.cm; + this.rememberSelection(); + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var head = domToPos(cm, sel.focusNode, sel.focusOffset); + if (anchor && head) runInOp(cm, function() { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); + if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; + }); + } + }, + + pollContent: function() { + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); + var from = sel.from(), to = sel.to(); + if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; + + var fromIndex; + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + var fromLine = lineNo(display.view[0].line); + var fromNode = display.view[0].node; + } else { + var fromLine = lineNo(display.view[fromIndex].line); + var fromNode = display.view[fromIndex - 1].node.nextSibling; + } + var toIndex = findViewIndex(cm, to.line); + if (toIndex == display.view.length - 1) { + var toLine = display.viewTo - 1; + var toNode = display.lineDiv.lastChild; + } else { + var toLine = lineNo(display.view[toIndex + 1].line) - 1; + var toNode = display.view[toIndex + 1].node.previousSibling; + } + + var newText = splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } + else break; + } + + var cutFront = 0, cutEnd = 0; + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + ++cutFront; + var newBot = lst(newText), oldBot = lst(oldText); + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)); + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + ++cutEnd; + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); + newText[0] = newText[0].slice(cutFront); + + var chFrom = Pos(fromLine, cutFront); + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input"); + return true; + } + }, + + ensurePolled: function() { + this.forceCompositionEnd(); + }, + reset: function() { + this.forceCompositionEnd(); + }, + forceCompositionEnd: function() { + if (!this.composing || this.composing.handled) return; + this.applyComposition(this.composing); + this.composing.handled = true; + this.div.blur(); + this.div.focus(); + }, + applyComposition: function(composing) { + if (composing.data && composing.data != composing.startData) + operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); + }, + + setUneditable: function(node) { + node.setAttribute("contenteditable", "false"); + }, + + onKeyPress: function(e) { + e.preventDefault(); + operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); + }, + + onContextMenu: nothing, + resetPosition: nothing, + + needsContentAttribute: true + }, ContentEditableInput.prototype); + + function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line); + if (!view || view.hidden) return null; + var line = getLine(cm.doc, pos.line); + var info = mapFromLineView(view, line, pos.line); + + var order = getOrder(line), side = "left"; + if (order) { + var partPos = getBidiPartAt(order, pos.ch); + side = partPos % 2 ? "right" : "left"; + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); + result.offset = result.collapse == "right" ? result.end : result.start; + return result; + } + + function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } + + function domToPos(cm, node, offset) { + var lineNode; + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset]; + if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); + node = null; offset = 0; + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) return null; + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i]; + if (lineView.node == lineNode) + return locateNodeInLineView(lineView, node, offset); + } + } + + function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false; + if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); + if (node == wrapper) { + bad = true; + node = wrapper.childNodes[offset]; + offset = 0; + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line; + return badPos(Pos(lineNo(line), line.text.length), bad); + } + } + + var textNode = node.nodeType == 3 ? node : null, topNode = node; + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild; + if (offset) offset = textNode.nodeValue.length; + } + while (topNode.parentNode != wrapper) topNode = topNode.parentNode; + var measure = lineView.measure, maps = measure.maps; + + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i]; + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2]; + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); + var ch = map[j] + offset; + if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; + return Pos(line, ch); + } + } + } + } + var found = find(textNode, topNode, offset); + if (found) return badPos(found, bad); + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0); + if (found) + return badPos(Pos(found.line, found.ch - dist), bad); + else + dist += after.textContent.length; + } + for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1); + if (found) + return badPos(Pos(found.line, found.ch + dist), bad); + else + dist += after.textContent.length; + } + } + + function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false; + function recognizeMarker(id) { return function(marker) { return marker.id == id; }; } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text"); + if (cmText != null) { + if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); + text += cmText; + return; + } + var markerID = node.getAttribute("cm-marker"), range; + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); + if (found.length && (range = found[0].find())) + text += getBetween(cm.doc, range.from, range.to).join("\n"); + return; + } + if (node.getAttribute("contenteditable") == "false") return; + for (var i = 0; i < node.childNodes.length; i++) + walk(node.childNodes[i]); + if (/^(pre|div|p)$/i.test(node.nodeName)) + closing = true; + } else if (node.nodeType == 3) { + var val = node.nodeValue; + if (!val) return; + if (closing) { + text += "\n"; + closing = false; + } + text += val; + } + } + for (;;) { + walk(from); + if (from == to) break; + from = from.nextSibling; + } + return text; + } + + CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; + + // SELECTION / CURSOR + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + function Selection(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + } + + Selection.prototype = { + primary: function() { return this.ranges[this.primIndex]; }, + equals: function(other) { + if (other == this) return true; + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; + } + return true; + }, + deepCopy: function() { + for (var out = [], i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); + return new Selection(out, this.primIndex); + }, + somethingSelected: function() { + for (var i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true; + return false; + }, + contains: function(pos, end) { + if (!end) end = pos; + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i; + } + return -1; + } + }; + + function Range(anchor, head) { + this.anchor = anchor; this.head = head; + } + + Range.prototype = { + from: function() { return minPos(this.anchor, this.head); }, + to: function() { return maxPos(this.anchor, this.head); }, + empty: function() { + return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; + } + }; + + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex]; + ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) --primIndex; + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } + } + return new Selection(ranges, primIndex); + } + + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0); + } + + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} + function clipPosArray(doc, array) { + for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); + return out; + } + + // SELECTION UPDATES + + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. + + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(doc, range, head, other) { + if (doc.cm && doc.cm.display.shift || doc.extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head); + } else { + return new Range(other || head, head); + } + } + + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options) { + setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); + } + + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + for (var out = [], i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); + var newSel = normalizeSelection(out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } + + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); + } + + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } + + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); + } + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); + else return sel; + } + + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } + + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } + + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel); + + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm); + } + + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return; + + doc.sel = sel; + + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; + signalCursorActivity(doc.cm); + } + signalLater(doc, "cursorActivity", doc); + } + + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); + } + + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i); + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel; + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, bias, mayClear) { + var flipped = false, curPos = pos; + var dir = bias || 1; + doc.cantEdit = false; + search: for (;;) { + var line = getLine(doc, curPos.line); + if (line.markedSpans) { + for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else {--i; continue;} + } + } + if (!m.atomic) continue; + var newPos = m.find(dir < 0 ? -1 : 1); + if (cmp(newPos, curPos) == 0) { + newPos.ch += dir; + if (newPos.ch < 0) { + if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); + else newPos = null; + } else if (newPos.ch > line.text.length) { + if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); + else newPos = null; + } + if (!newPos) { + if (flipped) { + // Driven in a corner -- no valid cursor position found at all + // -- try again *with* clearing, if we didn't already + if (!mayClear) return skipAtomic(doc, pos, bias, true); + // Otherwise, turn off editing until further notice, and return the start of the doc + doc.cantEdit = true; + return Pos(doc.first, 0); + } + flipped = true; newPos = pos; dir = -dir; + } + } + curPos = newPos; + continue search; + } + } + } + return curPos; + } + } + + // SELECTION DRAWING + + function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()); + } + + function prepareSelection(cm, primary) { + var doc = cm.doc, result = {}; + var curFragment = result.cursors = document.createDocumentFragment(); + var selFragment = result.selection = document.createDocumentFragment(); + + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (primary === false && i == doc.sel.primIndex) continue; + var range = doc.sel.ranges[i]; + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + drawSelectionCursor(cm, range, curFragment); + if (!collapsed) + drawSelectionRange(cm, range, selFragment); + } + return result; + } + + // Draws a cursor for the given range + function drawSelectionCursor(cm, range, output) { + var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine); + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + cursor.style.left = pos.left + "px"; + cursor.style.top = pos.top + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left + "px"; + otherCursor.style.top = pos.other.top + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } + } + + // Draws the given range as a highlighted selection + function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left; + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; + + function add(left, top, width, bottom) { + if (top < 0) top = 0; + top = Math.round(top); + bottom = Math.round(bottom); + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + + "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + + "px; height: " + (bottom - top) + "px")); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } + + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = leftSide; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = rightSide; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < leftSide + 1) left = leftSide; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return {start: start, end: end}; + } + + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top); + } + + output.appendChild(fragment); + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function() { + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + else if (cm.options.cursorBlinkRate < 0) + display.cursorDiv.style.visibility = "hidden"; + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.viewTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + var changedLines = []; + + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { + if (doc.frontier >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles; + var highlighted = highlightLine(cm, line, state, true); + line.styles = highlighted.styles; + var oldCls = line.styleClasses, newCls = highlighted.classes; + if (newCls) line.styleClasses = newCls; + else if (oldCls) line.styleClasses = null; + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) changedLines.push(doc.frontier); + line.stateAfter = copyState(doc.mode, state); + } else { + processLine(cm, line.text, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + if (changedLines.length) runInOp(cm, function() { + for (var i = 0; i < changedLines.length; i++) + regLineChange(cm, changedLines[i], "text"); + }); + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } + + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function(line) { + processLine(cm, line.text, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + if (precise) doc.frontier = pos; + return state; + } + + // POSITION MEASUREMENT + + function paddingTop(display) {return display.lineSpace.offsetTop;} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} + function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH; + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; + if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; + return data; + } + + function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } + function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; + } + function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; + } + + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && displayWidth(cm); + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top); + } + } + heights.push(rect.bottom - rect.top); + } + } + + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return {map: lineView.measure.map, cache: lineView.measure.cache}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; + } + + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view; + } + + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); + } + + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)]; + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext; + } + + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) + view = null; + else if (view && view.changes) + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + if (!view) + view = updateExternalMeasurement(cm, line); + + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + }; + } + + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) ch = -1; + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect(); + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) prepared.cache[key] = found; + } + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom}; + } + + var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; + + function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + var mStart = map[i], mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) collapse = "right"; + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias; + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } + break; + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; + } + + function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); + var node = place.node, start = place.start, end = place.end, collapse = place.collapse; + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { + rect = node.parentNode.getBoundingClientRect(); + } else if (ie && cm.options.lineWrapping) { + var rects = range(node, start, end).getClientRects(); + if (rects.length) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = nullRect; + } else { + rect = range(node, start, end).getBoundingClientRect() || nullRect; + } + if (rect.left || rect.right || start == 0) break; + end = start; + start = start - 1; + collapse = "right"; + } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right"; + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = node.getBoundingClientRect(); + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; + else + rect = nullRect; + } + + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; + var mid = (rtop + rbot) / 2; + var heights = prepared.view.measure.heights; + for (var i = 0; i < heights.length - 1; i++) + if (mid < heights[i]) break; + var top = i ? heights[i - 1] : 0, bot = heights[i]; + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot}; + if (!rect.left && !rect.right) result.bogus = true; + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } + + return result; + } + + // Work around problem with bounding client rects on ranges being + // returned incorrectly when zoomed on IE10 and below. + function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + return rect; + var scaleX = screen.logicalXDPI / screen.deviceXDPI; + var scaleY = screen.logicalYDPI / screen.deviceYDPI; + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY}; + } + + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {}; + } + } + + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]); + } + + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } + + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } + + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"/null (editor), "window", + // or "page". + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } + + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"/null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); + } + + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } + + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0, pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return {left: left, right: left, top: top, bottom: top + lineObj.height}; + } + + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, outside, xRel) { + var pos = Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } + + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; + + var lineObj = getLine(doc, lineN); + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(0, true); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line); + else + return found; + } + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var preparedMeasure = prepareMeasureForLine(cm, lineObj); + + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } + + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; + + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (;;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var xDiff = x - (ch == from ? fromX : toX); + while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, + xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} + else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} + } + } + + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } + + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } + + // OPERATIONS + + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. + + var operationGroup = null; + + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + }; + if (operationGroup) { + operationGroup.ops.push(cm.curOp); + } else { + cm.curOp.ownsGroup = operationGroup = { + ops: [cm.curOp], + delayedCallbacks: [] + }; + } + } + + function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0; + do { + for (; i < callbacks.length; i++) + callbacks[i](); + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j]; + if (op.cursorActivityHandlers) + while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm); + } + } while (i < callbacks.length); + } + + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp, group = op.ownsGroup; + if (!group) return; + + try { fireCallbacksForOps(group); } + finally { + operationGroup = null; + for (var i = 0; i < group.ops.length; i++) + group.ops[i].cm.curOp = null; + endOperations(group); + } + } + + // The DOM updates done when an operation finishes are batched so + // that the minimum number of relayouts are required. + function endOperations(group) { + var ops = group.ops; + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R1(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W1(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R2(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W2(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_finish(ops[i]); + } + + function endOperation_R1(op) { + var cm = op.cm, display = cm.display; + maybeClipScrollbars(cm); + if (op.updateMaxLine) findMaxLine(cm); + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping; + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); + } + + function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); + } + + function endOperation_R2(op) { + var cm = op.cm, display = cm.display; + if (op.updatedDisplay) updateHeightsInViewport(cm); + + op.barMeasure = measureForScrollbars(cm); + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; + cm.display.sizerWidth = op.adjustWidthTo; + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); + } + + if (op.updatedDisplay || op.selectionChanged) + op.preparedSelection = display.input.prepareSelection(); + } + + function endOperation_W2(op) { + var cm = op.cm; + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; + if (op.maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); + cm.display.maxLineChanged = false; + } + + if (op.preparedSelection) + cm.display.input.showSelection(op.preparedSelection); + if (op.updatedDisplay) + setDocumentHeight(cm, op.barMeasure); + if (op.updatedDisplay || op.startHeight != cm.doc.height) + updateScrollbars(cm, op.barMeasure); + + if (op.selectionChanged) restartBlink(cm); + + if (cm.state.focused && op.updateInput) + cm.display.input.reset(op.typing); + if (op.focus && op.focus == activeElt()) ensureFocus(op.cm); + } + + function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc; + + if (op.updatedDisplay) postUpdateDisplay(cm, op.update); + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + display.wheelStartX = display.wheelStartY = null; + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { + doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); + display.scrollbars.setScrollTop(doc.scrollTop); + display.scroller.scrollTop = doc.scrollTop; + } + if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { + doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft)); + display.scrollbars.setScrollLeft(doc.scrollLeft); + display.scroller.scrollLeft = doc.scrollLeft; + alignHorizontally(cm); + } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); + if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); + + if (display.wrapper.offsetHeight) + doc.scrollTop = cm.display.scroller.scrollTop; + + // Fire change events, and delayed event handlers + if (op.changeObjs) + signal(cm, "changes", cm, op.changeObjs); + if (op.update) + op.update.finish(); + } + + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) return f(); + startOperation(cm); + try { return f(); } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function() { + if (cm.curOp) return f.apply(cm, arguments); + startOperation(cm); + try { return f.apply(cm, arguments); } + finally { endOperation(cm); } + }; + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function() { + if (this.curOp) return f.apply(this, arguments); + startOperation(this); + try { return f.apply(this, arguments); } + finally { endOperation(this); } + }; + } + function docMethodOp(f) { + return function() { + var cm = this.cm; + if (!cm || cm.curOp) return f.apply(this, arguments); + startOperation(cm); + try { return f.apply(this, arguments); } + finally { endOperation(cm); } + }; + } + + // VIEW TRACKING + + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } + + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array; + } + + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + if (!lendiff) lendiff = 0; + + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from; + + cm.curOp.viewChanged = true; + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm); + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut = viewCuttingPoint(cm, from, from, -1); + if (cut) { + display.view = display.view.slice(0, cut.index); + display.viewTo = cut.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } + + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff; + else if (from < ext.lineN + ext.size) + display.externalMeasured = null; + } + } + + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null; + + if (line < display.viewFrom || line >= display.viewTo) return; + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) return; + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) arr.push(type); + } + + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } + + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null; + n -= cm.display.viewFrom; + if (n < 0) return null; + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) return i; + } + } + + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + return {index: index, lineN: newN}; + for (var i = 0, n = cm.display.viewFrom; i < index; i++) + n += view[i].size; + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null; + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null; + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return {index: index, lineN: newN}; + } + + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)); + display.viewFrom = from; + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)); + } + display.viewTo = to; + } + + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; + } + return dirty; + } + + // EVENT HANDLERS + + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + on(d.scroller, "dblclick", operation(cm, function(e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = cm.findWordAt(pos); + extendSelection(cm.doc, word.anchor, word.head); + })); + else + on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); + + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = {end: 0}; + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); + prevTouch = d.activeTouch; + prevTouch.end = +new Date; + } + }; + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) return false; + var touch = e.touches[0]; + return touch.radiusX <= 1 && touch.radiusY <= 1; + } + function farAway(touch, other) { + if (other.left == null) return true; + var dx = other.left - touch.left, dy = other.top - touch.top; + return dx * dx + dy * dy > 20 * 20; + } + on(d.scroller, "touchstart", function(e) { + if (!isMouseLikeTouchEvent(e)) { + clearTimeout(touchFinished); + var now = +new Date; + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null}; + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX; + d.activeTouch.top = e.touches[0].pageY; + } + } + }); + on(d.scroller, "touchmove", function() { + if (d.activeTouch) d.activeTouch.moved = true; + }); + on(d.scroller, "touchend", function(e) { + var touch = d.activeTouch; + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range; + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + range = new Range(pos, pos); + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + range = cm.findWordAt(pos); + else // Triple tap + range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); + cm.setSelection(range.anchor, range.head); + cm.focus(); + e_preventDefault(e); + } + finishTouch(); + }); + on(d.scroller, "touchcancel", finishTouch); + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function() { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); + on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + d.dragFunctions = { + simple: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);}, + start: function(e){onDragStart(cm, e);}, + drop: operation(cm, onDrop) + }; + + var inp = d.input.getField(); + on(inp, "keyup", function(e) { onKeyUp.call(cm, e); }); + on(inp, "keydown", operation(cm, onKeyDown)); + on(inp, "keypress", operation(cm, onKeyPress)); + on(inp, "focus", bind(onFocus, cm)); + on(inp, "blur", bind(onBlur, cm)); + } + + function dragDropChanged(cm, value, old) { + var wasOn = old && old != CodeMirror.Init; + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions; + var toggle = value ? on : off; + toggle(cm.display.scroller, "dragstart", funcs.start); + toggle(cm.display.scroller, "dragenter", funcs.simple); + toggle(cm.display.scroller, "dragover", funcs.simple); + toggle(cm.display.scroller, "drop", funcs.drop); + } + } + + // Called when the window resizes + function onResize(cm) { + var d = cm.display; + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + return; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + d.scrollbarsClipped = false; + cm.setSize(); + } + + // MOUSE EVENTS + + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + return true; + } + } + + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; + + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e) { return null; } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); + } + return coords; + } + + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + var cm = this, display = cm.display; + if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return; + display.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function(){display.scroller.draggable = true;}, 100); + } + return; + } + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + window.focus(); + + switch (e_button(e)) { + case 1: + if (start) + leftButtonDown(cm, e, start); + else if (e_target(e) == display.scroller) + e_preventDefault(e); + break; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(function() {display.input.focus();}, 20); + e_preventDefault(e); + break; + case 3: + if (captureRightClick) onContextMenu(cm, e); + else delayBlurEvent(cm); + break; + } + } + + var lastClick, lastDoubleClick; + function leftButtonDown(cm, e, start) { + if (ie) setTimeout(bind(ensureFocus, cm), 0); + else cm.curOp.focus = activeElt(); + + var now = +new Date, type; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { + type = "triple"; + } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { + type = "double"; + lastDoubleClick = {time: now, pos: start}; + } else { + type = "single"; + lastClick = {time: now, pos: start}; + } + + var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; + if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && + type == "single" && (contained = sel.contains(start)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && + (cmp(contained.to(), start) > 0 || start.xRel < 0)) + leftButtonStartDrag(cm, e, start, modifier); + else + leftButtonSelect(cm, e, start, type, modifier); + } + + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, e, start, modifier) { + var display = cm.display, startTime = +new Date; + var dragEnd = operation(cm, function(e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + if (!modifier && +new Date - 200 < startTime) + extendSelection(cm.doc, start); + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + setTimeout(function() {document.body.focus(); display.input.focus();}, 20); + else + display.input.focus(); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + } + + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, e, start, type, addNew) { + var display = cm.display, doc = cm.doc; + e_preventDefault(e); + + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; + if (addNew && !e.shiftKey) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + ourRange = ranges[ourIndex]; + else + ourRange = new Range(start, start); + } else { + ourRange = doc.sel.primary(); + ourIndex = doc.sel.primIndex; + } + + if (e.altKey) { + type = "rect"; + if (!addNew) ourRange = new Range(start, start); + start = posFromMouse(cm, e, true, true); + ourIndex = -1; + } else if (type == "double") { + var word = cm.findWordAt(start); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, word.anchor, word.head); + else + ourRange = word; + } else if (type == "triple") { + var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, line.anchor, line.head); + else + ourRange = line; + } else { + ourRange = extendRange(doc, ourRange, start); + } + + if (!addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + startSel = doc.sel; + } else if (ourIndex == -1) { + ourIndex = ranges.length; + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}); + } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0)); + startSel = doc.sel; + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } + + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return; + lastPos = pos; + + if (type == "rect") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); + } + if (!ranges.length) ranges.push(new Range(start, start)); + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}); + cm.scrollIntoView(pos); + } else { + var oldRange = ourRange; + var anchor = oldRange.anchor, head = pos; + if (type != "single") { + if (type == "double") + var range = cm.findWordAt(pos); + else + var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + } + var ranges = startSel.ranges.slice(0); + ranges[ourIndex] = new Range(clipPos(doc, anchor), head); + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); + } + } + + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, type == "rect"); + if (!cur) return; + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt(); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function() { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } + + function done(e) { + counter = Infinity; + e_preventDefault(e); + display.input.focus(); + off(document, "mousemove", move); + off(document, "mouseup", up); + doc.history.lastSelOrigin = null; + } + + var move = operation(cm, function(e) { + if (!e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + on(document, "mousemove", move); + on(document, "mouseup", up); + } + + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent, signalfn) { + try { var mX = e.clientX, mY = e.clientY; } + catch(e) { return false; } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; + if (prevent) e_preventDefault(e); + + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signalfn(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true, signalLater); + } + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return; + e_preventDefault(e); + if (ie) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || isReadOnly(cm)) return; + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function(file, i) { + var reader = new FileReader; + reader.onload = operation(cm, function() { + text[i] = reader.result; + if (++read == n) { + pos = clipPos(cm.doc, pos); + var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); + } + }); + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(function() {cm.display.input.focus();}, 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey)) + var selected = cm.listSelections(); + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) for (var i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); + cm.replaceSelection(text, "around", "paste"); + cm.display.input.focus(); + } + } + catch(e){} + } + } + + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; + + e.dataTransfer.setData("Text", cm.getSelection()); + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) img.parentNode.removeChild(img); + } + } + + // SCROLL EVENTS + + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplaySimple(cm, {top: val}); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + cm.display.scrollbars.setScrollTop(val); + if (gecko) updateDisplaySimple(cm); + startWorker(cm, 100); + } + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + cm.display.scrollbars.setScrollLeft(val); + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1/3; + + var wheelEventDelta = function(e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + return {x: dx, y: dy}; + }; + CodeMirror.wheelEventPixels = function(e) { + var delta = wheelEventDelta(e); + delta.x *= wheelPixelsPerUnit; + delta.y *= wheelPixelsPerUnit; + return delta; + }; + + function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + if (!(dx && scroll.scrollWidth > scroll.clientWidth || + dy && scroll.scrollHeight > scroll.clientHeight)) return; + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer; + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplaySimple(cm, {top: top, bottom: bot}); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function() { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + // KEY EVENTS + + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled(); + var prevShift = cm.display.shift, done = false; + try { + if (isReadOnly(cm)) cm.state.suppressEdits = true; + if (dropShift) cm.display.shift = false; + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } + + function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); + if (result) return result; + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm); + } + + var stopSeq = new Delayed; + function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq; + if (seq) { + if (isModifierKey(name)) return "handled"; + stopSeq.set(50, function() { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null; + cm.display.input.reset(); + } + }); + name = seq + " " + name; + } + var result = lookupKeyForEditor(cm, name, handle); + + if (result == "multi") + cm.state.keySeq = name; + if (result == "handled") + signalLater(cm, "keyHandled", cm, name, e); + + if (result == "handled" || result == "multi") { + e_preventDefault(e); + restartBlink(cm); + } + + if (seq && !result && /\'$/.test(name)) { + e_preventDefault(e); + return true; + } + return !!result; + } + + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + var name = keyName(e, true); + if (!name) return false; + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);}) + || dispatchKey(cm, name, e, function(b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); }); + } + } + + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, + function(b) { return doHandleBinding(cm, b, true); }); + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + cm.curOp.focus = activeElt(); + if (signalDOMEvent(cm, e)) return; + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut"); + } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + showCrossHair(cm); + } + + function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv; + addClass(lineDiv, "CodeMirror-crosshair"); + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair"); + off(document, "keyup", up); + off(document, "mouseover", up); + } + } + on(document, "keyup", up); + on(document, "mouseover", up); + } + + function onKeyUp(e) { + if (e.keyCode == 16) this.doc.sel.shift = false; + signalDOMEvent(this, e); + } + + function onKeyPress(e) { + var cm = this; + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (handleCharBinding(cm, e, ch)) return; + cm.display.input.onKeyPress(e); + } + + // FOCUS/BLUR EVENTS + + function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true; + setTimeout(function() { + if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false; + onBlur(cm); + } + }, 100); + } + + function onFocus(cm) { + if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; + + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + addClass(cm.display.wrapper, "CodeMirror-focused"); + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset(); + if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730 + } + cm.display.input.receivedFocus(); + } + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.delayingBlurEvent) return; + + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + rmClass(cm.display.wrapper, "CodeMirror-focused"); + } + clearInterval(cm.display.blinker); + setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); + } + + // CONTEXT MENU HANDLING + + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; + cm.display.input.onContextMenu(e); + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false, signal); + } + + // UPDATING + + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + var changeEnd = CodeMirror.changeEnd = function(change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; + + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos; + if (cmp(pos, change.to) <= 0) return changeEnd(change); + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; + return Pos(line, ch); + } + + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(out, doc.sel.primIndex); + } + + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch); + else + return Pos(nw.line + (pos.line - old.line), pos.ch); + } + + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex); + } + + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function() { this.canceled = true; } + }; + if (update) obj.update = function(from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); + + if (obj.canceled) return null; + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; + } + + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); + } else { + makeChangeInner(doc, change); + } + } + + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits) return; + + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + for (var i = 0; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break; + } + if (i == source.length) return; + hist.lastOrigin = hist.lastSelOrigin = null; + + for (;;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}); + return; + } + selAfter = event; + } + else break; + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({changes: antiChanges, generation: hist.generation}); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return; + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + if (distance == 0) return; + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function(range) { + return new Range(Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch)); + }), doc.sel.primIndex); + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance); + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + regLineChange(doc.cm, l, "gutter"); + } + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); + else updateDoc(doc, change, spans); + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function(line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + signalCursorActivity(cm); + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function(line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (change.full) + regChange(cm); + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text"); + else + regChange(cm, from.line, to.line + 1, lendiff); + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }; + if (changeHandler) signalLater(cm, "change", cm, obj); + if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); + } + cm.display.selForContextMenu = null; + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = splitLines(code); + makeChange(doc, {from: from, to: to, text: code, origin: origin}); + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, coords) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) return; + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + + (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + + (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + + coords.left + "px; width: 2px;"); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0; + for (var limit = 0; limit < 5; limit++) { + var changed = false, coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), + Math.min(coords.top, endCoords.top) - margin, + Math.max(coords.left, endCoords.left), + Math.max(coords.bottom, endCoords.bottom) + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) break; + } + return coords; + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = displayHeight(cm), result = {}; + if (y2 - y1 > screen) y2 = y1 + screen; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; + var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); + var tooWide = x2 - x1 > screenw; + if (tooWide) x2 = x1 + screenw; + if (x1 < 10) + result.scrollLeft = 0; + else if (x1 < screenleft) + result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); + else if (x2 > screenw + screenleft - 3) + result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; + return result; + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollPos(cm, left, top) { + if (left != null || top != null) resolveScrollToPos(cm); + if (left != null) + cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; + if (top != null) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(), from = cur, to = cur; + if (!cm.options.lineWrapping) { + from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; + to = Pos(cur.line, cur.ch + 1); + } + cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), + Math.min(from.top, to.top) - range.margin, + Math.max(from.right, to.right), + Math.max(from.bottom, to.bottom) + range.margin); + cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + } + + // API UTILITIES + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) how = "add"; + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) how = "prev"; + else state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) line.stateAfter = null; + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass || indentation > 150) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + return true; + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i, new Range(pos, pos)); + break; + } + } + } + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); + return line; + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break; + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function() { + for (var i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); + ensureCursorVisible(cm); + }); + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "char", "column" (like char, but doesn't + // cross line boundaries), "word" (across next word), or "group" (to + // the start of next group of word or non-word-non-whitespace + // chars). The visually param controls whether, in right-to-left + // text, direction 1 means to move towards the next index in the + // string, or towards the character to the right of the current + // position. The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + var possible = true; + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return (possible = false); + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return (possible = false); + } else ch = next; + return true; + } + + if (unit == "char") moveOnce(); + else if (unit == "column") moveOnce(true); + else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) type = "s"; + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce();} + break; + } + + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), origDir, true); + if (!possible) result.hitSide = true; + return result; + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (;;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + // EDITOR METHODS + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus();}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function(option) {return this.options[option];}, + getDoc: function() {return this.doc;}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: methodOp(function(how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var from = range.from(), to = range.to(); + var start = Math.max(end, from.line); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + indentLine(this, j, how); + var newRanges = this.doc.sel.ranges; + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) ensureCursorVisible(this); + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise); + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true); + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + var type; + if (ch == 0) type = styles[2]; + else for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else { type = styles[mid * 2 + 2]; break; } + } + var cut = type ? type.indexOf("cm-overlay ") : -1; + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0]; + }, + + getHelpers: function(pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) return found; + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]); + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) found.push(val); + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i = 0; i < help._global.length; i++) { + var cur = help._global[i]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val); + } + return found; + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) pos = range.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? range.from() : range.to(); + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function(line, mode) { + var end = false, lineObj; + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + lineObj = getLine(this.doc, line); + } else { + lineObj = line; + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + + (end ? this.doc.height - heightAtLine(lineObj) : 0); + }, + + defaultTextHeight: function() { return textHeight(this.display); }, + defaultCharWidth: function() { return charWidth(this.display); }, + + setGutterMarker: methodOp(function(line, gutterID, value) { + return changeLine(this.doc, line, "gutter", function(line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: methodOp(function(gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function(line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regLineChange(cm, i, "gutter"); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + lineInfo: function(line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets}; + }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + node.setAttribute("cm-ignore-events", "true"); + this.display.input.setUneditable(node); + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd](this); + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: methodOp(function(dir, unit) { + var cm = this; + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); + else + return dir < 0 ? range.from() : range.to(); + }, sel_move); + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete"); + else + deleteNearSelection(this, function(range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; + }); + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: methodOp(function(dir, unit) { + var cm = this, doc = this.doc, goals = []; + var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function(range) { + if (collapse) + return dir < 0 ? range.from() : range.to(); + var headPos = cursorCoords(cm, range.head, "div"); + if (range.goalColumn != null) headPos.left = range.goalColumn; + goals.push(headPos.left); + var pos = findPosV(cm, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); + return pos; + }, sel_move); + if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i]; + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function(ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + addClass(this.display.cursorDiv, "CodeMirror-overwrite"); + else + rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function() { return this.display.input.getField() == activeElt(); }, + + scrollTo: methodOp(function(x, y) { + if (x != null || y != null) resolveScrollToPos(this); + if (x != null) this.curOp.scrollLeft = x; + if (y != null) this.curOp.scrollTop = y; + }), + getScrollInfo: function() { + var scroller = this.display.scroller; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)}; + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null}; + if (margin == null) margin = this.options.cursorScrollMargin; + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null}; + } else if (range.from == null) { + range = {from: range, to: null}; + } + if (!range.to) range.to = range.from; + range.margin = margin || 0; + + if (range.from.line != null) { + resolveScrollToPos(this); + this.curOp.scrollToPos = range; + } else { + var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), + Math.min(range.from.top, range.to.top) - range.margin, + Math.max(range.from.right, range.to.right), + Math.max(range.from.bottom, range.to.bottom) + range.margin); + this.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + }), + + setSize: methodOp(function(width, height) { + var cm = this; + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) cm.display.wrapper.style.width = interpret(width); + if (height != null) cm.display.wrapper.style.height = interpret(height); + if (cm.options.lineWrapping) clearLineMeasurementCache(this); + var lineNo = cm.display.viewFrom; + cm.doc.iter(lineNo, cm.display.viewTo, function(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) + if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } + ++lineNo; + }); + cm.curOp.forceUpdate = true; + signal(cm, "refresh", this); + }), + + operation: function(f){return runInOp(this, f);}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + this.curOp.forceUpdate = true; + clearCaches(this); + this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); + updateGutterSpace(this); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + this.display.input.reset(); + this.scrollTo(doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; + signalLater(this, "swapDoc", this, old); + return old; + }), + + getInputField: function(){return this.display.input.getField();}, + getWrapperElement: function(){return this.display.wrapper;}, + getScrollerElement: function(){return this.display.scroller;}, + getGutterElement: function(){return this.display.gutters;} + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + // Functions to run when options are changed. + var optionHandlers = CodeMirror.optionHandlers = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; + } + + // Passed to option handlers when there is no old value. + var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function(cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function(cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function(cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + if (old != CodeMirror.Init) cm.refresh(); + }); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); + option("electricChars", true); + option("inputStyle", mobile ? "contenteditable" : "textarea", function() { + throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME + }, true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function(cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", function(cm, val, old) { + var next = getKeyMap(val); + var prev = old != CodeMirror.Init && getKeyMap(old); + if (prev && prev.detach) prev.detach(cm, next); + if (next.attach) next.attach(cm, prev || null); + }); + option("extraKeys", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function(cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true); + option("scrollbarStyle", "native", function(cm) { + initScrollbars(cm); + updateScrollbars(cm); + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); + }, true); + option("lineNumbers", false, function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + option("lineWiseCopyCut", true); + + option("readOnly", false, function(cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + cm.display.disabled = true; + } else { + cm.display.disabled = false; + if (!val) cm.display.input.reset(); + } + }); + option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true); + option("dragDrop", true, dragDropChanged); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1, updateSelection, true); + option("singleCursorHeightPerLine", true, updateSelection, true); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function(cm){cm.refresh();}, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function(cm, val) { + if (!val) cm.display.input.resetPosition(); + }); + + option("tabindex", null, function(cm, val) { + cm.display.input.getField().tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; + }; + + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") found = {name: found}; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; + }; + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + CodeMirror.getMode = function(options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; + }; + + // Minimal default mode. + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function(name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function(name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({pred: predicate, val: value}); + }; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because nested + // modes need to do this for their inner modes. + + var copyState = CodeMirror.copyState = function(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + }; + + var startState = CodeMirror.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + }; + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + CodeMirror.innerMode = function(mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state}; + }; + + // STANDARD COMMANDS + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = CodeMirror.commands = { + selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, + singleSelection: function(cm) { + cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); + }, + killLine: function(cm) { + deleteNearSelection(cm, function(range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + return {from: range.head, to: Pos(range.head.line + 1, 0)}; + else + return {from: range.head, to: Pos(range.head.line, len)}; + } else { + return {from: range.from(), to: range.to()}; + } + }); + }, + deleteLine: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; + }); + }, + delLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), to: range.from()}; + }); + }, + delWrappedLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var leftPos = cm.coordsChar({left: 0, top: top}, "div"); + return {from: leftPos, to: range.from()}; + }); + }, + delWrappedLineRight: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + return {from: range.from(), to: rightPos }; + }); + }, + undo: function(cm) {cm.undo();}, + redo: function(cm) {cm.redo();}, + undoSelection: function(cm) {cm.undoSelection();}, + redoSelection: function(cm) {cm.redoSelection();}, + goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, + goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, + goLineStart: function(cm) { + cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, + {origin: "+move", bias: 1}); + }, + goLineStartSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + return lineStartSmart(cm, range.head); + }, {origin: "+move", bias: 1}); + }, + goLineEnd: function(cm) { + cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, + {origin: "+move", bias: -1}); + }, + goLineRight: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + }, sel_move); + }, + goLineLeft: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: 0, top: top}, "div"); + }, sel_move); + }, + goLineLeftSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var pos = cm.coordsChar({left: 0, top: top}, "div"); + if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); + return pos; + }, sel_move); + }, + goLineUp: function(cm) {cm.moveV(-1, "line");}, + goLineDown: function(cm) {cm.moveV(1, "line");}, + goPageUp: function(cm) {cm.moveV(-1, "page");}, + goPageDown: function(cm) {cm.moveV(1, "page");}, + goCharLeft: function(cm) {cm.moveH(-1, "char");}, + goCharRight: function(cm) {cm.moveH(1, "char");}, + goColumnLeft: function(cm) {cm.moveH(-1, "column");}, + goColumnRight: function(cm) {cm.moveH(1, "column");}, + goWordLeft: function(cm) {cm.moveH(-1, "word");}, + goGroupRight: function(cm) {cm.moveH(1, "group");}, + goGroupLeft: function(cm) {cm.moveH(-1, "group");}, + goWordRight: function(cm) {cm.moveH(1, "word");}, + delCharBefore: function(cm) {cm.deleteH(-1, "char");}, + delCharAfter: function(cm) {cm.deleteH(1, "char");}, + delWordBefore: function(cm) {cm.deleteH(-1, "word");}, + delWordAfter: function(cm) {cm.deleteH(1, "word");}, + delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, + delGroupAfter: function(cm) {cm.deleteH(1, "group");}, + indentAuto: function(cm) {cm.indentSelection("smart");}, + indentMore: function(cm) {cm.indentSelection("add");}, + indentLess: function(cm) {cm.indentSelection("subtract");}, + insertTab: function(cm) {cm.replaceSelection("\t");}, + insertSoftTab: function(cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from(); + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); + spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); + } + cm.replaceSelections(spaces); + }, + defaultTab: function(cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.execCommand("insertTab"); + }, + transposeChars: function(cm) { + runInOp(cm, function() { + var ranges = cm.listSelections(), newSel = []; + for (var i = 0; i < ranges.length; i++) { + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (line) { + if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1); + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose"); + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text; + if (prev) + cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); + } + } + newSel.push(new Range(cur, cur)); + } + cm.setSelections(newSel); + }); + }, + newlineAndIndent: function(cm) { + runInOp(cm, function() { + var len = cm.listSelections().length; + for (var i = 0; i < len; i++) { + var range = cm.listSelections()[i]; + cm.replaceRange("\n", range.anchor, range.head, "+input"); + cm.indentLine(range.from().line + 1, null, true); + ensureCursorVisible(cm); + } + }); + }, + toggleOverwrite: function(cm) {cm.toggleOverwrite();} + }; + + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; + var alt, ctrl, shift, cmd; + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; + else if (/^a(lt)?$/i.test(mod)) alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; + else if (/^s(hift)$/i.test(mod)) shift = true; + else throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) name = "Alt-" + name; + if (ctrl) name = "Ctrl-" + name; + if (cmd) name = "Cmd-" + name; + if (shift) name = "Shift-" + name; + return name; + } + + // This is a kludge to keep keymaps mostly working as raw objects + // (backwards compatibility) while at the same time support features + // like normalization and multi-stroke key bindings. It compiles a + // new normalized keymap, and then updates the old object to reflect + // this. + CodeMirror.normalizeKeyMap = function(keymap) { + var copy = {}; + for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname]; + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; + if (value == "...") { delete keymap[keyname]; continue; } + + var keys = map(keyname.split(" "), normalizeKeyName); + for (var i = 0; i < keys.length; i++) { + var val, name; + if (i == keys.length - 1) { + name = keys.join(" "); + val = value; + } else { + name = keys.slice(0, i + 1).join(" "); + val = "..."; + } + var prev = copy[name]; + if (!prev) copy[name] = val; + else if (prev != val) throw new Error("Inconsistent bindings for " + name); + } + delete keymap[keyname]; + } + for (var prop in copy) keymap[prop] = copy[prop]; + return keymap; + }; + + var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) { + map = getKeyMap(map); + var found = map.call ? map.call(key, context) : map[key]; + if (found === false) return "nothing"; + if (found === "...") return "multi"; + if (found != null && handle(found)) return "handled"; + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + return lookupKey(key, map.fallthrough, handle, context); + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context); + if (result) return result; + } + } + }; + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + var isModifierKey = CodeMirror.isModifierKey = function(value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + }; + + // Look up the name of a key as indicated by an event object. + var keyName = CodeMirror.keyName = function(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false; + var base = keyNames[event.keyCode], name = base; + if (name == null || event.altGraphKey) return false; + if (event.altKey && base != "Alt") name = "Alt-" + name; + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; + if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; + return name; + }; + + function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val; + } + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function(textarea, options) { + options = options ? copyObj(options) : {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabIndex) + options.tabindex = textarea.tabIndex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function() { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + options.finishInit = function(cm) { + cm.save = save; + cm.getTextArea = function() { return textarea; }; + cm.toTextArea = function() { + cm.toTextArea = isNaN; // Prevent this from being ran twice + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + }; + + textarea.style.display = "none"; + var cm = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = CodeMirror.StringStream = function(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + var nextMarkerId = 0; + + var TextMarker = CodeMirror.TextMarker = function(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + this.id = ++nextMarkerId; + }; + eventMixin(TextMarker); + + // Clear the marker. + TextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); + else if (cm) { + if (span.to != null) max = lineNo(line); + if (span.from != null) min = lineNo(line); + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(this.lines[i]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm.doc); + } + if (cm) signalLater(cm, "markerCleared", cm, this); + if (withOp) endOperation(cm); + if (this.parent) this.parent.clear(); + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function(side, lineObj) { + if (side == null && this.type == "bookmark") side = 1; + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) return from; + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) return to; + } + } + return from && {from: from, to: to}; + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function() { + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) return; + runInOp(cm, function() { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + updateLineHeight(line, line.height + dHeight); + } + }); + }; + + TextMarker.prototype.attachLine = function(line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function(line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type); + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) copyObj(options, marker, false); + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker; + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); + if (options.insertLeft) marker.widgetNode.insertLeft = true; + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one"); + sawCollapsedSpans = true; + } + + if (marker.addToHistory) + addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function(line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true; + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.collapsed) + regChange(cm, from.line, to.line + 1); + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); + if (marker.atomic) reCheckSelection(cm.doc); + signalLater(cm, "markerAdded", cm, marker); + } + return marker; + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0; i < markers.length; ++i) + markers[i].parent = this; + }; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function(side, lineObj) { + return this.primary.find(side, lineObj); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function(doc) { + if (widget) options.widgetNode = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), + function(m) { return m.parent; }); + } + + function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find(); + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); + marker.markers.push(subMark); + subMark.parent = marker; + } + } + } + + function detachSharedMarkers(markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], linked = [marker.primary.doc];; + linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j]; + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null; + marker.markers.splice(j--, 1); + } + } + } + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } + return nw; + } + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } + return nw; + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + if (change.full) return null; + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first); + if (last && last != first) last = clearEmptySpans(last); + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1); + } + if (!spans.length) return null; + return spans; + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function(line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({from: p.from, to: m.from}); + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({from: m.to, to: p.to}); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) return lenDiff; + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) return -fromCmp; + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) return toCmp; + return b.id - a.id; + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) continue; + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; + if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || + fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) + return true; + } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line; + return line; + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + (lines || (lines = [])).push(line); + } + return lines; + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) return lineN; + return lineNo(vis); + } + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN; + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) return lineN; + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line; + return lineNo(line) + 1; + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.widgetNode) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + // LINE WIDGETS + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = CodeMirror.LineWidget = function(doc, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.doc = doc; + this.node = node; + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollPos(cm, null, diff); + } + + LineWidget.prototype.clear = function() { + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) line.widgets = null; + var height = widgetHeight(this); + updateLineHeight(line, Math.max(0, line.height - height)); + if (cm) runInOp(cm, function() { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + }); + }; + LineWidget.prototype.changed = function() { + var oldH = this.height, cm = this.doc.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + updateLineHeight(line, line.height + diff); + if (cm) runInOp(cm, function() { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + }); + }; + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + var cm = widget.doc.cm; + if (!cm) return 0; + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;"; + if (widget.coverGutter) + parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; + if (widget.noHScroll) + parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); + } + return widget.height = widget.node.offsetHeight; + } + + function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options); + var cm = doc.cm; + if (cm && widget.noHScroll) cm.display.alignWidgets = true; + changeLine(doc, handle, "widget", function(line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, null, widget.height); + cm.curOp.forceUpdate = true; + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + Line.prototype.lineNo = function() { return lineNo(this); }; + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + function extractLineClasses(type, output) { + if (type) for (;;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) break; + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (output[prop] == null) + output[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + output[prop] += " " + lineClass[2]; + } + return type; + } + + function callBlankLine(mode, state) { + if (mode.blankLine) return mode.blankLine(state); + if (!mode.innerMode) return; + var inner = CodeMirror.innerMode(mode, state); + if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); + } + + function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; + var style = mode.token(stream, state); + if (stream.pos > stream.start) return style; + } + throw new Error("Mode " + mode.name + " failed to advance stream."); + } + + // Utility for getTokenAt and getLineTokens + function takeToken(cm, pos, precise, asArray) { + function getObj(copy) { + return {start: stream.start, end: stream.pos, + string: stream.current(), + type: style || null, + state: copy ? copyState(doc.mode, state) : state}; + } + + var doc = cm.doc, mode = doc.mode, style; + pos = clipPos(doc, pos); + var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); + var stream = new StringStream(line.text, cm.options.tabSize), tokens; + if (asArray) tokens = []; + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos; + style = readToken(mode, stream, state); + if (asArray) tokens.push(getObj(true)); + } + return asArray ? tokens : getObj(); + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + var inner = cm.options.addModeClass && [null]; + if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) processLine(cm, text, state, stream.pos); + stream.pos = text.length; + style = null; + } else { + style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); + } + if (inner) { + var mName = inner[0].name; + if (mName) style = "m-" + (style ? mName + " " + style : mName); + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 50000); + f(curStart, curStyle); + } + curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, state, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {}; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function(end, style) { + st.push(end, style); + }, lineClasses, forceToEnd); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function(end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, "cm-overlay " + style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; + } + } + }, lineClasses); + } + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; + } + + function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); + line.styles = result.styles; + if (result.classes) line.styleClasses = result.classes; + else if (line.styleClasses) line.styleClasses = null; + if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; + } + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, state, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize); + stream.start = stream.pos = startAt || 0; + if (text == "") callBlankLine(mode, state); + while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { + readToken(mode, stream, state); + stream.start = stream.pos; + } + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) return null; + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")); + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order; + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) + builder.addToken = buildTokenBadBidi(builder.addToken, order); + builder.map = []; + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); + if (line.styleClasses) { + if (line.styleClasses.bgClass) + builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); + if (line.styleClasses.textClass) + builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); + (lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + // See issue #2901 + if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) + builder.content.className = "cm-tab-wrap-hack"; + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + if (builder.pre.className) + builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); + + return builder; + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + token.setAttribute("aria-label", token.title); + return token; + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) return; + var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text; + var special = builder.cm.state.specialChars, mustWrap = false; + if (!special.test(text)) { + builder.col += text.length; + var content = document.createTextNode(displayText); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie && ie_version < 9) mustWrap = true; + builder.pos += text.length; + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + txt.setAttribute("role", "presentation"); + txt.setAttribute("cm-text", "\t"); + builder.col += tabWidth; + } else { + var txt = builder.cm.options.specialCharPlaceholder(m[0]); + txt.setAttribute("cm-text", m[0]); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt); + builder.pos++; + } + } + if (style || startStyle || endStyle || mustWrap || css) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle, css); + if (title) token.title = title; + return builder.content.appendChild(token); + } + builder.content.appendChild(content); + } + + function splitSpaces(old) { + var out = " "; + for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; + out += " "; + return out; + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function(builder, text, style, startStyle, endStyle, title, css) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (;;) { + // Find the part that overlaps with the start of this text + for (var i = 0; i < order.length; i++) { + var part = order[i]; + if (part.to > start && part.from <= start) break; + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) builder.map.push(builder.pos, builder.pos + size, widget); + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + widget = builder.content.appendChild(document.createElement("span")); + widget.setAttribute("cm-marker", marker.id); + } + if (widget) { + builder.cm.display.input.setUneditable(widget); + builder.content.appendChild(widget); + } + builder.pos += size; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = []; + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m); + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to; + spanEndStyle = ""; + } + if (m.className) spanStyle += " " + m.className; + if (m.css) css = m.css; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return; + if (collapsed.to == pos) collapsed = false; + } + if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder.cm.options); + } + } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore); + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null;} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + function linesFor(start, end) { + for (var i = start, result = []; i < end; ++i) + result.push(new Line(text[i], spansFor(i), estimateHeight)); + return result; + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)); + doc.remove(text.length, doc.size - text.length); + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + var added = linesFor(1, text.length - 1); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + var added = linesFor(1, text.length - 1); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, height = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length; }, + // Remove the n lines at offset 'at'. + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + // Helper used to collapse a small branch into a single leaf. + collapse: function(lines) { + lines.push.apply(lines, this.lines); + }, + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) lines[i].parent = this; + }, + // Used to iterate over a part of the tree. + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size; }, + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function(lines) { + for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); + }, + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + while (child.lines.length > 50) { + var spilled = child.lines.splice(child.lines.length - 25, 25); + var newleaf = new LeafChunk(spilled); + child.height -= newleaf.height; + this.children.splice(i + 1, 0, newleaf); + newleaf.parent = this; + } + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + // When a node has grown, check whether it should be split. + maybeSpill: function() { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function(at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function(text, mode, firstLine) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + + if (typeof text == "string") text = splitLines(text); + updateDoc(this, {from: start, to: start, text: text}); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep, lineFilter) { + var lines = getLines(this, this.first, this.first + this.size, lineFilter); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: splitLines(code), origin: "setValue", full: true}, true); + setSelection(this, simpleSelection(top)); + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, + getLineNumber: function(line) {return lineNo(line);}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(line); + }, + + lineCount: function() {return this.size;}, + firstLine: function() {return this.first;}, + lastLine: function() {return this.first + this.size - 1;}, + + clipPos: function(pos) {return clipPos(this, pos);}, + + getCursor: function(start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") pos = range.head; + else if (start == "anchor") pos = range.anchor; + else if (start == "end" || start == "to" || start === false) pos = range.to(); + else pos = range.from(); + return pos; + }, + listSelections: function() { return this.sel.ranges; }, + somethingSelected: function() {return this.sel.somethingSelected();}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads, options)); + }), + extendSelectionsBy: docMethodOp(function(f, options) { + extendSelections(this, map(this.sel.ranges, f), options); + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) return; + for (var i = 0, out = []; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); + setSelection(this, normalizeSelection(out, primary), options); + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); + }), + + getSelection: function(lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) return lines; + else return lines.join(lineSep || "\n"); + }, + getSelections: function(lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) sel = sel.join(lineSep || "\n"); + parts[i] = sel; + } + return parts; + }, + replaceSelection: function(code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + dup[i] = code; + this.replaceSelections(dup, collapse, origin || "+input"); + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin}; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]); + if (newSel) setSelectionReplaceHistory(this, newSel); + else if (this.cm) ensureCursorVisible(this.cm); + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), + + setExtending: function(val) {this.extend = val;}, + getExtending: function() {return this.extend;}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; + for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; + return {undo: done, redo: undone}; + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration);}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)}; + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (classTest(cls).test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(classTest(cls)); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + removeLineWidget: function(widget) { widget.clear(); }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function(line) { + var spans = line.markedSpans; + if (spans) for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(lineNo == from.line && from.ch > span.to || + span.from == null && lineNo != from.line|| + lineNo == to.line && span.from > to.ch) && + (!filter || filter(span.marker))) + found.push(span.marker.parent || span.marker); + } + ++lineNo; + }); + return found; + }, + getAllMarks: function() { + var markers = []; + this.iter(function(line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first; + this.iter(function(line) { + var sz = line.text.length + 1; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + 1; + }); + return index; + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function(options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + copySharedMarkers(copy, findSharedMarkers(this)); + return copy; + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + detachSharedMarkers(findSharedMarkers(this)); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode;}, + getEditor: function() {return this.cm;} + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments);}; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) findMaxLine(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); + for (var chunk = doc; !chunk.lines;) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function(line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to, lineFilter) { + var out = []; + doc.iter(from, to, function(line) { + var text = line.text; + if(lineFilter){ + text = lineFilter(line); + } + out.push(text); + }); + return out; + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) for (var n = line; n; n = n.parent) n.height += diff; + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0; i < chunk.children.length; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = this.lastSelOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); + return histChange; + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) array.pop(); + else break; + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done); + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done); + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done); + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, ore are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done); + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation}; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) hist.done.shift(); + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = hist.lastSelOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) signal(doc, "historyAdded"); + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel; + else + pushSelectionToHistory(sel, hist.done); + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastSelOp = opId; + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone); + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel); + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue; + } + var changes = event.changes, newChanges = []; + copy.push({changes: newChanges}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue; + } + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT UTILITIES + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + var e_preventDefault = CodeMirror.e_preventDefault = function(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + }; + var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + }; + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; + + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var on = CodeMirror.on = function(emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + }; + + var off = CodeMirror.off = function(emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + for (var i = 0; i < arr.length; ++i) + if (arr[i] == f) { arr.splice(i, 1); break; } + } + }; + + var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); + }; + + var orphanDelayedCallbacks = null; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + function signalLater(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2), list; + if (operationGroup) { + list = operationGroup.delayedCallbacks; + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks; + } else { + list = orphanDelayedCallbacks = []; + setTimeout(fireOrphanDelayed, 0); + } + function bnd(f) {return function(){f.apply(null, args);};}; + for (var i = 0; i < arr.length; ++i) + list.push(bnd(arr[i])); + } + + function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks; + orphanDelayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity; + if (!arr) return; + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); + for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) + set.push(arr[i]); + } + + function hasHandler(emitter, type) { + var arr = emitter._handlers && emitter._handlers[type]; + return arr && arr.length > 0; + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerGap = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; + + // Reused option objects for setSelection & friends + var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; + + function Delayed() {this.id = null;} + Delayed.prototype.set = function(ms, f) { + clearTimeout(this.id); + this.id = setTimeout(f, ms); + }; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + }; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + function findColumn(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) nextTab = string.length; + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col); + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) return pos; + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length-1]; } + + var selectInput = function(node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; + else if (ie) // Suppress mysterious IE10 errors + selectInput = function(node) { try { node.select(); } catch(_e) {} }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + if (array[i] == elt) return i; + return -1; + } + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); + return out; + } + + function nothing() {} + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) copyObj(props, inst); + return inst; + }; + + function copyObj(obj, target, overwrite) { + if (!target) target = {}; + for (var prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop]; + return target; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args);}; + } + + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var isWordCharBasic = CodeMirror.isWordChar = function(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + }; + function isWordChar(ch, helper) { + if (!helper) return isWordCharBasic(ch); + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; + return helper.test(ch); + } + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + var range; + if (document.createRange) range = function(node, start, end, endNode) { + var r = document.createRange(); + r.setEnd(endNode || node, end); + r.setStart(node, start); + return r; + }; + else range = function(node, start, end) { + var r = document.body.createTextRange(); + try { r.moveToElementText(node.parentNode); } + catch(e) { return r; } + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r; + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + var contains = CodeMirror.contains = function(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + child = child.parentNode; + if (parent.contains) + return parent.contains(child); + do { + if (child.nodeType == 11) child = child.host; + if (child == parent) return true; + } while (child = child.parentNode); + }; + + function activeElt() { return document.activeElement; } + // Older versions of IE throws unspecified error when touching + // document.activeElement in some cases (during loading, in iframe) + if (ie && ie_version < 11) activeElt = function() { + try { return document.activeElement; } + catch(e) { return document.body; } + }; + + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } + var rmClass = CodeMirror.rmClass = function(node, cls) { + var current = node.className; + var match = classTest(cls).exec(current); + if (match) { + var after = current.slice(match.index + match[0].length); + node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); + } + }; + var addClass = CodeMirror.addClass = function(node, cls) { + var current = node.className; + if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; + }; + function joinClasses(a, b) { + var as = a.split(" "); + for (var i = 0; i < as.length; i++) + if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; + return b; + } + + // WINDOW-WIDE EVENTS + + // These must be handled carefully, because naively registering a + // handler for each editor will cause the editors to never be + // garbage collected. + + function forEachCodeMirror(f) { + if (!document.body.getElementsByClassName) return; + var byClass = document.body.getElementsByClassName("CodeMirror"); + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror; + if (cm) f(cm); + } + } + + var globalsRegistered = false; + function ensureGlobalHandlers() { + if (globalsRegistered) return; + registerGlobalHandlers(); + globalsRegistered = true; + } + function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer; + on(window, "resize", function() { + if (resizeTimer == null) resizeTimer = setTimeout(function() { + resizeTimer = null; + forEachCodeMirror(onResize); + }, 100); + }); + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function() { + forEachCodeMirror(onBlur); + }); + } + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + node.setAttribute("cm-text", ""); + return node; + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects; + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) + var r1 = range(txt, 1, 2).getBoundingClientRect(); + return badBidiRects = (r1.right - r0.right < 3); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function(string){return string.split(/\r\n?|\n/);}; + + var hasSelection = window.getSelection ? function(te) { + try { return te.selectionStart != te.selectionEnd; } + catch(e) { return false; } + } : function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function() { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function"; + })(); + + var badZoomedRects = null; + function hasBadZoomedRects(measure) { + if (badZoomedRects != null) return badZoomedRects; + var node = removeChildrenAndAdd(measure, elt("span", "x")); + var normal = node.getBoundingClientRect(); + var fromRange = range(node, 0, 1).getBoundingClientRect(); + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; + } + + // KEY NAMES + + var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"}; + CodeMirror.keyNames = keyNames; + (function() { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line = getLine(cm.doc, lineN); + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + lineN = null; + } + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN == null ? lineNo(line) : lineN, ch); + } + function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line); + var line = getLine(cm.doc, start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; + return Pos(start.line, inWS ? 0 : firstNonWS); + } + return start; + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + bidiOther = null; + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) return i; + if ((cur.from == pos || cur.to == pos)) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + if (cur.from != cur.to) bidiOther = found; + return i; + } else { + if (cur.from != cur.to) bidiOther = i; + return found; + } + } + } + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar(line.text.charAt(pos))); + return pos; + } + + // This is needed in order to move 'visually' through bi-directional + // text -- i.e., pressing left should make the cursor go left, even + // when in RTL text. The tricky part is the 'jumps', where RTL and + // LTR text touch each other. This often requires the cursor offset + // to move more than one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (;;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); + else if (0x6ee <= code && code <= 0x8ac) return "r"; + else if (0x2000 <= code && code <= 0x200b) return "w"; + else if (code == 0x200c) return "b"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function(str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + var before = (i ? types[i-1] : outerType) == "L"; + var after = (end < len ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push(new BidiSpan(0, start, i)); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) {} + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, new BidiSpan(2, nstart, j)); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + if (order[0].level == 2) + order.unshift(new BidiSpan(1, order[0].to, order[0].to)); + if (order[0].level != lst(order).level) + order.push(new BidiSpan(order[0].level, len, len)); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "5.4.1"; + + return CodeMirror; +}); \ No newline at end of file diff --git a/src/base/formula/formulaeditor.js b/src/base/formula/formulaeditor.js index d2433ebf9..96228a992 100644 --- a/src/base/formula/formulaeditor.js +++ b/src/base/formula/formulaeditor.js @@ -11,7 +11,8 @@ baseCls: 'bi-formula-editor', watermark: '', value: '', - fieldTextValueMap: {} + fieldTextValueMap: {}, + showHint: true }); }, _init: function () { @@ -25,7 +26,9 @@ }); this.editor.on("change", function (cm, change) { self._checkWaterMark(); - CodeMirror.showHint(cm, CodeMirror.formulaHint, {completeSingle: false}); + if(o.showHint){ + CodeMirror.showHint(cm, CodeMirror.formulaHint, {completeSingle: false}); + } BI.nextTick(function () { self.fireEvent(BI.FormulaEditor.EVENT_CHANGE) }); @@ -99,6 +102,10 @@ this._checkWaterMark(); }, + focus: function() { + this.editor.focus(); + }, + /** * 添加字段 * @param field diff --git a/src/base/foundation/bi.message.js b/src/base/foundation/bi.message.js index 92ad28417..e79e1bae7 100644 --- a/src/base/foundation/bi.message.js +++ b/src/base/foundation/bi.message.js @@ -9,6 +9,15 @@ $.extend(BI, { var messageShow, $mask, $pop; return { + alert: function (title, message, callback) { + this._show(false, title, message, callback); + }, + confirm: function (title, message, callback, min_width) { + this._show(true, title, message, callback); + }, + prompt: function (title, message, value, callback, min_width) { + FR.Msg.prompt(title, message, value, callback, min_width); + }, toast: function (message, level, context) { context = context || $("body"); var toast = BI.createWidget({ @@ -41,16 +50,16 @@ $.extend(BI, { _show: function (hasCancel, title, message, callback) { $mask = $('
      ').css({ position: 'absolute', - 'zIndex': 99999998, + 'zIndex': BI.zIndex_tip - 2, top: 0, left: 0, right: 0, bottom: 0, - opacity: 0.1 + opacity: 0.5 }).appendTo('body'); $pop = $('
      ').css({ position: 'absolute', - 'zIndex': 99999999, + 'zIndex': BI.zIndex_tip - 1, top: 0, left: 0, right: 0, @@ -65,7 +74,7 @@ $.extend(BI, { controlItems.push({ el: { type: 'bi.button', - text: BI.i18nText("BI-Cancel"), + text: BI.i18nText("BI-Basic_Cancel"), height: 30, level: 'ignore', handler: function () { @@ -80,7 +89,7 @@ $.extend(BI, { controlItems.push({ el: { type: 'bi.button', - text: BI.i18nText("BI-OK"), + text: BI.i18nText("BI-Basic_OK"), height: 30, handler: function () { close(); @@ -106,7 +115,7 @@ $.extend(BI, { center: { el: { type: 'bi.label', - text: title || BI.i18nText("BI-Prompt"), + text: title || BI.i18nText("BI-Basic_Prompt"), textAlign: 'left', hgap: 20, height: 50 diff --git a/src/base/grid/grid.js b/src/base/grid/grid.js index 03b5336a2..c95930f6b 100644 --- a/src/base/grid/grid.js +++ b/src/base/grid/grid.js @@ -60,13 +60,11 @@ BI.Grid = BI.inherit(BI.Widget, { if (o.items.length > 0) { this._populate(); } - }, - - mounted: function () { - var o = this.options; if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); + BI.nextTick(function () { + self.element.scrollTop(o.scrollTop); + self.element.scrollLeft(o.scrollLeft); + }); } }, diff --git a/src/base/layer/layer.popup.js b/src/base/layer/layer.popup.js index 634507705..fa7683a75 100644 --- a/src/base/layer/layer.popup.js +++ b/src/base/layer/layer.popup.js @@ -53,7 +53,14 @@ BI.PopupView = BI.inherit(BI.Widget, { "z-index": BI.zIndex_popup, "min-width": o.minWidth + "px", "max-width": o.maxWidth + "px" - }).bind({"click": fn, "mousewheel": fn}); + }).bind({"click": fn}); + + //FIXME IE8下 jquery.mousewheeel.js 第一次执行65行$elem["offsetParent"]()的时候报错:未指明的错误 但是第二次或者调试的时候展开一下$elem内容均能避免上述问题 + try { + this.element.bind("mousewheel", fn); + } catch (e) { + this.element.bind("mousewheel", fn); + } o.stopPropagation && this.element.bind({"mousedown": fn, "mouseup": fn, "mouseover": fn}); o.stopEvent && this.element.bind({"mousedown": stop, "mouseup": stop, "mouseover": stop}); @@ -135,6 +142,10 @@ BI.PopupView = BI.inherit(BI.Widget, { }) }, + getView: function () { + return this.button_group; + }, + populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, @@ -145,9 +156,9 @@ BI.PopupView = BI.inherit(BI.Widget, { }, resetHeight: function (h) { - var tbHeight = 30 * (this.toolbar ? 1 : 0), - tabHeight = 25 * (this.tab ? 1 : 0), - toolHeight = ((this.tool && this.tool.element.outerHeight()) || 25) * ((this.tool && this.tool.isVisible()) ? 1 : 0); + var tbHeight = this.toolbar ? (this.toolbar.attr("height") || 30) : 0, + tabHeight = this.tab ? (this.tab.attr("height") || 25) : 0, + toolHeight = ((this.tool && this.tool.attr("height")) || 25) * ((this.tool && this.tool.isVisible()) ? 1 : 0); this.view.resetHeight ? this.view.resetHeight(h - tbHeight - tabHeight - toolHeight - 2) : this.view.element.css({"max-height": (h - tbHeight - tabHeight - toolHeight - 2) + "px"}) }, diff --git a/src/base/pager/pager.js b/src/base/pager/pager.js index 126cda329..f4128c0fa 100644 --- a/src/base/pager/pager.js +++ b/src/base/pager/pager.js @@ -52,15 +52,6 @@ BI.Pager = BI.inherit(BI.Widget, { this._populate(); }, - populate: function () { - this.currPage = BI.result(this.options, "curr"); - this._populate(); - }, - - refresh: function () { - this._populate(); - }, - _populate: function () { var self = this, o = this.options, view = [], dict = {}; this.empty(); @@ -279,6 +270,17 @@ BI.Pager = BI.inherit(BI.Widget, { default : return val; } + }, + + attr: function (key, value) { + BI.Pager.superclass.attr.apply(this, arguments); + if (key === "curr") { + this.currPage = BI.result(this.options, "curr"); + } + }, + + populate: function () { + this._populate(); } }); BI.Pager.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/pane.js b/src/base/pane.js index 941ab3996..ca5677592 100644 --- a/src/base/pane.js +++ b/src/base/pane.js @@ -56,7 +56,7 @@ BI.Pane = BI.inherit(BI.Widget, { }); } BI.Maskers.show(self.getName()); - } else { + } else if (BI.isNull(this._loading)) { this._loading = BI.createWidget({ type: "bi.layout", cls: "loading-background", diff --git a/src/base/reqloading/loading.request.js b/src/base/reqloading/loading.request.js new file mode 100644 index 000000000..c54d5578f --- /dev/null +++ b/src/base/reqloading/loading.request.js @@ -0,0 +1,192 @@ +/** + * Created by Young's on 2016/8/17. + * 加载面板,一般只用于 requestAsync 中 + */ +BI.RequstLoading = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.RequstLoading.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.RequstLoading.superclass._init.apply(this, arguments); + var self = this, o = this.options; + var mask = BI.Maskers.create(BI.RequstLoading.MASK_ID); + this.callback = o.callback; + this.paneTab = BI.createWidget({ + type: "bi.tab", + cardCreator: BI.bind(this._cardCreator, this), + defaultShowIndex: BI.RequstLoading.ERROR, + width: 400, + height: 300 + }); + var tempIcon = BI.createWidget({ + type: "bi.icon_button", + cls: "data-link-test-fail-icon", + width: 0, + height: 0 + }); + BI.createWidget({ + type: "bi.absolute", + element: $('body'), + items: [{ + el: tempIcon, + bottom: 0 + }] + }); + + BI.createWidget({ + type: "bi.absolute", + element: mask, + cls: "bi-request-loading", + items: [{ + el: { + type: "bi.layout", + cls: "mask-pane" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + }, { + el: { + type: "bi.center_adapt", + items: [this.paneTab] + }, + top: 0, + left: 0, + right: 0, + bottom: 0 + }] + }); + }, + + _cardCreator: function (v) { + var self = this; + var cancel = BI.createWidget({ + type: "bi.button", + text: BI.i18nText("BI-Basic_Cancel"), + title: BI.i18nText("BI-Basic_Cancel"), + level: "ignore", + height: 28, + width: 90, + handler: function () { + BI.Maskers.hide(BI.RequstLoading.MASK_ID); + } + }); + var retry = BI.createWidget({ + type: "bi.button", + text: BI.i18nText("BI-Basic_Retry"), + title: BI.i18nText("BI-Basic_Retry"), + level: "common", + height: 28, + width: 90, + handler: function () { + self.paneTab.setSelect(BI.RequstLoading.LOADING); + self.callback(); + } + }); + switch (v) { + case BI.RequstLoading.LOADING: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "loading-bar-icon", + items: [{ + type: "bi.icon", + width: 208, + height: 15 + }] + }, { + type: "bi.label", + cls: "loading-comment", + text: BI.i18nText("BI-Basic_Loading"), + height: 30 + }], + width: 208, + height: 200, + vgap: 10 + }); + case BI.RequstLoading.LOADING_TIMEOUT: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "loading-bar-icon", + items: [{ + type: "bi.icon", + width: 208, + height: 15 + }] + }, { + type: "bi.label", + cls: "loading-comment", + text: BI.i18nText("BI-Basic_Loading"), + height: 30 + }, { + type: "bi.label", + text: BI.i18nText("BI-Request_Time_Out_Toast_Tip"), + cls: "load-timeout-warning" + }, { + type: "bi.left_right_vertical_adapt", + items: { + left: [cancel], + right: [retry] + }, + height: 30, + llgap: 100, + rrgap: 100 + }], + vgap: 10 + }); + case BI.RequstLoading.ERROR: + return BI.createWidget({ + type: "bi.vertical", + items: [{ + type: "bi.center_adapt", + cls: "data-link-test-fail-icon", + items: [{ + type: "bi.icon", + width: 126, + height: 126 + }] + }, { + type: "bi.label", + text: BI.i18nText("BI-Connection_Lost"), + cls: "load-fail-comment" + }, { + type: "bi.left_right_vertical_adapt", + items: { + left: [cancel], + right: [retry] + }, + height: 30, + llgap: 100, + rrgap: 100 + }], + vgap: 20 + }); + } + }, + + showLoading: function () { + BI.Maskers.show(BI.RequstLoading.MASK_ID); + this.paneTab.setSelect(BI.RequstLoading.LOADING); + }, + + showError: function () { + BI.Maskers.show(BI.RequstLoading.MASK_ID); + this.paneTab.setSelect(BI.RequstLoading.ERROR); + }, + + setCallback: function (callback) { + this.callback = callback; + } +}); +BI.extend(BI.RequstLoading, { + MASK_ID: "___request__loading___", + LOADING: 1, + LOADING_TIMEOUT: 2, + ERROR: 3 +}); +$.shortcut("bi.request_loading", BI.RequstLoading); \ No newline at end of file diff --git a/src/base/single/a/a.js b/src/base/single/a/a.js index db50fe4b8..4f804c30f 100644 --- a/src/base/single/a/a.js +++ b/src/base/single/a/a.js @@ -13,13 +13,14 @@ BI.A = BI.inherit(BI.Text, { baseCls: (conf.baseCls || "") + " bi-a display-block", href: "", target: "_blank", - el: null + el: null, + element: "" }) }, _init: function () { var o = this.options; - this.options.element = $(""); BI.A.superclass._init.apply(this, arguments); + this.element.attr({href: o.href, target: o.target}); if (o.el) { BI.createWidget(o.el, { element: this diff --git a/src/base/single/bar/bar.loading.js b/src/base/single/bar/bar.loading.js index 326cb2579..a02c8665e 100644 --- a/src/base/single/bar/bar.loading.js +++ b/src/base/single/bar/bar.loading.js @@ -5,8 +5,8 @@ */ BI.LoadingBar = BI.inherit(BI.Single, { consts: { - loadedText: '加载更多', - endText: '无更多数据' + loadedText: BI.i18nText("BI-Load_More"), + endText: BI.i18nText("BI-No_More_Data") }, _defaultConfig: function() { var conf = BI.LoadingBar.superclass._defaultConfig.apply(this, arguments); diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js index 1b6214536..41f23794c 100644 --- a/src/base/single/button/button.basic.js +++ b/src/base/single/button/button.basic.js @@ -9,7 +9,7 @@ BI.BasicButton = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.BasicButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-basic-button cursor-pointer", + baseCls: (conf.baseCls || "") + " bi-basic-button" + (conf.invalid ? "" : " cursor-pointer"), value: "", text: "", stopEvent: false, @@ -122,42 +122,36 @@ BI.BasicButton = BI.inherit(BI.Single, { var selected = false; hand.mousedown(function (e) { // if (e.button === 0) { - if (mouseDown === true) { - return; + $(document).bind("mouseup." + self.getName(), function (e) { + // if (e.button === 0) { + if (BI.DOM.isExist(self) && !hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { + self.setSelected(!self.isSelected()); + self._trigger(); } - if (self.isSelected()) { - selected = true; - } else { - clk(e); - } - mouseDown = true; - ev(e); + mouseDown = false; + $(document).unbind("mouseup." + self.getName()); + // } + }); + if (mouseDown === true) { + return; + } + if (self.isSelected()) { + selected = true; + } else { + clk(e); + } + mouseDown = true; + ev(e); // } }); hand.mouseup(function (e) { // if (e.button === 0) { - if (mouseDown === true && selected === true) { - clk(e); - } - mouseDown = false; - selected = false; - // } - }); - var checking = BI.debounce(function () { - if (!BI.DOM.isExist(self)) { - $(document).unbind("mouseup." + self.getName()); + if (BI.DOM.isExist(self) && mouseDown === true && selected === true) { + clk(e); } - }, 3000); - $(document).bind("mouseup." + this.getName(), function (e) { - // if (e.button === 0) { - if (BI.DOM.isExist(self)) { - if (!hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { - self.setSelected(!self.isSelected()); - self._trigger(); - } - mouseDown = false; - checking(); - } + mouseDown = false; + selected = false; + $(document).unbind("mouseup." + self.getName()); // } }); break; @@ -284,8 +278,13 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - destroyed: function () { + empty: function () { $(document).unbind("mouseup." + this.getName()); + BI.BasicButton.superclass.empty.apply(this, arguments); + }, + + destroy: function () { + BI.BasicButton.superclass.destroy.apply(this, arguments); } }); BI.BasicButton.EVENT_CHANGE = "BasicButton.EVENT_CHANGE"; \ No newline at end of file diff --git a/src/base/single/button/buttons/button.icon.js b/src/base/single/button/buttons/button.icon.js index 6e65366e0..4ec092e62 100644 --- a/src/base/single/button/buttons/button.icon.js +++ b/src/base/single/button/buttons/button.icon.js @@ -7,8 +7,7 @@ BI.IconButton = BI.inherit(BI.BasicButton, { _defaultConfig: function () { var conf = BI.IconButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-icon-button horizon-center display-block", + baseCls: (conf.baseCls || "") + " bi-icon-button horizon-center", iconWidth: null, iconHeight: null }) diff --git a/src/base/single/button/buttons/button.image.js b/src/base/single/button/buttons/button.image.js index 7bc567d04..40fe14a96 100644 --- a/src/base/single/button/buttons/button.image.js +++ b/src/base/single/button/buttons/button.image.js @@ -9,8 +9,7 @@ BI.ImageButton = BI.inherit(BI.BasicButton, { _defaultConfig: function () { var conf = BI.ImageButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-image-button display-block", + baseCls: (conf.baseCls || "") + " bi-image-button", src: "", iconWidth: "100%", iconHeight: "100%" diff --git a/src/base/single/button/buttons/button.text.js b/src/base/single/button/buttons/button.text.js index a66f5f36f..ab6e1aa11 100644 --- a/src/base/single/button/buttons/button.text.js +++ b/src/base/single/button/buttons/button.text.js @@ -6,11 +6,10 @@ * 文字button */ BI.TextButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function() { + _defaultConfig: function () { var conf = BI.TextButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend( conf, { - tagName: "a", - baseCls: (conf.baseCls || "") + " bi-text-button display-block", + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-text-button", textAlign: "center", whiteSpace: "nowrap", forceCenter: false, @@ -19,12 +18,12 @@ BI.TextButton = BI.inherit(BI.BasicButton, { hgap: 0, lgap: 0, rgap: 0, - text:"", + text: "", py: "" }) }, - _init:function() { + _init: function () { BI.TextButton.superclass._init.apply(this, arguments); var o = this.options; this.text = BI.createWidget({ @@ -46,18 +45,18 @@ BI.TextButton = BI.inherit(BI.BasicButton, { }); }, - doClick: function(){ + doClick: function () { BI.TextButton.superclass.doClick.apply(this, arguments); - if(this.isValid()) { + if (this.isValid()) { this.fireEvent(BI.TextButton.EVENT_CHANGE, this.getValue(), this); } }, - doRedMark: function(){ + doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, - unRedMark: function(){ + unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, @@ -69,15 +68,19 @@ BI.TextButton = BI.inherit(BI.BasicButton, { this.text.unHighLight.apply(this.text, arguments); }, - setText: function(text){ + setText: function (text) { BI.TextButton.superclass.setText.apply(this, arguments); text = BI.isArray(text) ? text.join(",") : text; this.text.setText(text); }, - setValue: function(text){ + setStyle: function (style) { + this.text.setStyle(style); + }, + + setValue: function (text) { BI.TextButton.superclass.setValue.apply(this, arguments); - if(!this.isReadOnly()) { + if (!this.isReadOnly()) { text = BI.isArray(text) ? text.join(",") : text; this.text.setValue(text); } diff --git a/src/base/single/button/listitem/blankiconicontextitem.js b/src/base/single/button/listitem/blankiconicontextitem.js new file mode 100644 index 000000000..f7d37f44a --- /dev/null +++ b/src/base/single/button/listitem/blankiconicontextitem.js @@ -0,0 +1,119 @@ +/** + * 带有一个占位 + * + * Created by GUY on 2015/9/11. + * @class BI.BlankIconIconTextItem + * @extends BI.BasicButton + */ +BI.BlankIconIconTextItem = BI.inherit(BI.BasicButton, { + _const: { + commonWidth: 25 + }, + + _defaultConfig: function () { + var conf = BI.BlankIconIconTextItem.superclass._defaultConfig.apply(this, arguments); + return BI.extend(conf, { + baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", + logic: { + dynamic: false + }, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0 + }) + }, + _init: function () { + BI.BlankIconIconTextItem.superclass._init.apply(this, arguments); + var o = this.options, c = this._const; + var blank = BI.createWidget({ + type: "bi.layout", + width: o.blankWidth + }) + this.text = BI.createWidget({ + type: "bi.label", + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height + }); + this.icon1 = BI.createWidget({ + type: "bi.icon_button", + cls: o.iconCls1, + forceNotSelected: true, + width: c.commonWidth + }); + this.icon2 = BI.createWidget({ + type: "bi.icon_button", + cls: o.iconCls2, + forceNotSelected: true, + width: c.commonWidth + }); + + BI.createWidget(BI.extend({ + element: this + }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { + items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon1, this.icon2, this.text) + })))); + }, + + doClick: function () { + BI.BlankIconIconTextItem.superclass.doClick.apply(this, arguments); + if (this.isValid()) { + this.fireEvent(BI.BlankIconIconTextItem.EVENT_CHANGE, this.getValue(), this); + } + }, + + setSelected: function (b) { + BI.BlankIconIconTextItem.superclass.setSelected.apply(this, arguments); + this.icon1.setSelected(b); + this.icon2.setSelected(b); + }, + + setValue: function () { + if (!this.isReadOnly()) { + this.text.setValue.apply(this.text, arguments); + } + }, + + getValue: function () { + return this.text.getValue(); + }, + + setText: function () { + this.text.setText.apply(this.text, arguments); + }, + + getText: function () { + return this.text.getText(); + }, + + doRedMark: function () { + this.text.doRedMark.apply(this.text, arguments); + }, + + unRedMark: function () { + this.text.unRedMark.apply(this.text, arguments); + }, + + doHighLight: function () { + this.text.doHighLight.apply(this.text, arguments); + }, + + unHighLight: function () { + this.text.unHighLight.apply(this.text, arguments); + } +}); +BI.BlankIconIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; +$.shortcut("bi.blank_icon_icon_text_item", BI.BlankIconIconTextItem); \ No newline at end of file diff --git a/src/base/single/editor/editor.code.js b/src/base/single/editor/editor.code.js index 54a8b1150..03b55707c 100644 --- a/src/base/single/editor/editor.code.js +++ b/src/base/single/editor/editor.code.js @@ -104,7 +104,7 @@ BI.CodeEditor = BI.inherit(BI.Single, { case "param": var fieldNameLength = i.to - i.from; value = value.substr(0, i.from + num) + "$\{" + value.substr(i.from + num, fieldNameLength) + "\}" + value.substr(i.to + num, value.length); - num += fieldNameLength + 3; + num += 3; break; } }); @@ -113,7 +113,7 @@ BI.CodeEditor = BI.inherit(BI.Single, { }, _analyzeContent: function (v) { - var regx = /\$[\{][^\}]*[\}]|\w*\w|\$\{[^\$\(\)\+\-\*\/)\$,]*\w\}|\$\{[^\$\(\)\+\-\*\/]*\w\}|\$\{[^\$\(\)\+\-\*\/]*[\u4e00-\u9fa5]\}|\w|(.)|\n/g; + var regx = /\$[\{][^\}]*[\}]|(\s+)|\w*\w|\$\{[^\$\(\)\+\-\*\/)\$,]*\w\}|\$\{[^\$\(\)\+\-\*\/]*\w\}|\$\{[^\$\(\)\+\-\*\/]*[\u4e00-\u9fa5]\}|\w|(.)|\n/g; return v.match(regx); }, diff --git a/src/base/single/editor/editor.js b/src/base/single/editor/editor.js index 521c39bb0..70df8c808 100644 --- a/src/base/single/editor/editor.js +++ b/src/base/single/editor/editor.js @@ -50,7 +50,9 @@ BI.Editor = BI.inherit(BI.Single, { type: "bi.label", cls: "bi-water-mark", text: this.options.watermark, + height: this.options.height, forceCenter: true, + height: o.height - 2 * (o.vgap + o.tgap), whiteSpace: "nowrap", textAlign: "left" }); @@ -275,7 +277,7 @@ BI.Editor = BI.inherit(BI.Single, { }, getLastValidValue: function () { - return BI.trim(this.editor.getLastValidValue()); + return this.editor.getLastValidValue(); }, resetLastValidValue: function () { diff --git a/src/base/single/editor/editor.textarea.js b/src/base/single/editor/editor.textarea.js index 44eea9206..b4045ae90 100644 --- a/src/base/single/editor/editor.textarea.js +++ b/src/base/single/editor/editor.textarea.js @@ -37,26 +37,96 @@ BI.TextAreaEditor = BI.inherit(BI.Single, { }] }); + this.content.element.on("input propertychange", function (e) { + self._checkWaterMark(); + self.fireEvent(BI.TextAreaEditor.EVENT_CHANGE); + }); + this.content.element.focus(function () { - self.content.element.addClass("textarea-editor-focus"); - self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); + if (self.isValid()) { + self._focus(); + self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); + } + $(document).bind("mousedown." + self.getName(), function (e) { + if (BI.DOM.isExist(self) && !self.element.__isMouseInBounds__(e)) { + $(document).unbind("mousedown." + self.getName()); + self.content.element.blur(); + } + }); }); this.content.element.blur(function () { - self.content.element.removeClass("textarea-editor-focus"); - self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); + if (self.isValid()) { + self._blur(); + self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); + } + $(document).unbind("mousedown." + self.getName()); }); if (BI.isKey(o.value)) { self.setValue(o.value); } + if (BI.isNotNull(o.style)) { + self.setValue(o.style); + } + this._checkWaterMark(); }, - focus: function () { + _checkWaterMark: function () { + var self = this, o = this.options; + var val = this.getValue(); + if (BI.isNotEmptyString(val)) { + this.watermark && this.watermark.destroy(); + this.watermark = null; + } else { + if (BI.isNotEmptyString(o.watermark)) { + if (!this.watermark) { + this.watermark = BI.createWidget({ + type: "bi.text_button", + cls: "bi-water-mark", + textAlign: "left", + height: 30, + text: o.watermark, + invalid: o.invalid, + disabled: o.disabled + }); + this.watermark.on(BI.TextButton.EVENT_CHANGE, function () { + self.focus(); + }); + BI.createWidget({ + type: 'bi.absolute', + element: this, + items: [{ + el: this.watermark, + left: 0, + top: 0, + right: 0 + }] + }) + } else { + this.watermark.setText(o.watermark); + this.watermark.setValid(!o.invalid); + this.watermark.setEnable(!o.disabled); + } + } + } + }, + + _focus: function () { this.content.element.addClass("textarea-editor-focus"); + this._checkWaterMark(); + }, + + _blur: function () { + this.content.element.removeClass("textarea-editor-focus"); + this._checkWaterMark(); + }, + + focus: function () { + this._focus(); this.content.element.focus(); }, blur: function () { - this.content.element.removeClass("textarea-editor-focus"); + this._blur(); this.content.element.blur(); }, @@ -81,13 +151,16 @@ BI.TextAreaEditor = BI.inherit(BI.Single, { setValid: function (b) { BI.TextAreaEditor.superclass.setValid.apply(this, arguments); this.content.setValid(b); + this.watermark && this.watermark.setValid(b); }, setEnable: function (b) { BI.TextAreaEditor.superclass.setEnable.apply(this, arguments); this.content.setEnable(b); + this.watermark && this.watermark.setEnable(b); } }); +BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.TextAreaEditor.EVENT_BLUR = "EVENT_BLUR"; BI.TextAreaEditor.EVENT_FOCUS = "EVENT_FOCUS"; $.shortcut("bi.textarea_editor", BI.TextAreaEditor); \ No newline at end of file diff --git a/src/base/single/img/img.js b/src/base/single/img/img.js index c89db0a84..9a037ac07 100644 --- a/src/base/single/img/img.js +++ b/src/base/single/img/img.js @@ -10,7 +10,7 @@ BI.Img = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.Img.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-img", + baseCls: (conf.baseCls || "") + " bi-img display-block", src: "", width: "100%", height: "100%" @@ -33,4 +33,4 @@ BI.Img = BI.inherit(BI.Single, { } }); -$.shortcut("bi.img", BI.Img); \ No newline at end of file +$.shortcut("bi.img", BI.Img); diff --git a/src/base/single/input/checkbox.js b/src/base/single/input/checkbox.js index bb76d962b..92b295d67 100644 --- a/src/base/single/input/checkbox.js +++ b/src/base/single/input/checkbox.js @@ -7,7 +7,6 @@ BI.Checkbox = BI.inherit(BI.IconButton, { _defaultConfig: function() { var conf = BI.Checkbox.superclass._defaultConfig.apply(this,arguments); return BI.extend(conf, { - tagName: "a", baseCls: (conf.baseCls || "") + " bi-checkbox check-box-icon", selected: false, handler: BI.emptyFn, diff --git a/src/base/single/input/file.js b/src/base/single/input/file.js index f896131f1..2aa47b878 100644 --- a/src/base/single/input/file.js +++ b/src/base/single/input/file.js @@ -16,8 +16,9 @@ var F = (function (item) { return function (input) { var files = input.files || [input]; - if (!files.item) + if (!files.item) { files.item = item; + } return files; }; })(function (i) { @@ -67,8 +68,9 @@ */ stop: function (e) { if (!e) { - if (self.event) + if (self.event) { event.returnValue = !(event.cancelBubble = true); + } } else { e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; e.preventDefault ? e.preventDefault() : e.returnValue = false; @@ -82,7 +84,7 @@ var multipart = function (boundary, name, file) { return "--".concat( boundary, CRLF, - 'Content-Disposition: form-data; name="', name, '"; filename="', BI.cjkEncode(file.fileName), '"', CRLF, + 'Content-Disposition: form-data; name="', name, '"; filename="', FR.cjkEncode(file.fileName), '"', CRLF, "Content-Type: application/octet-stream", CRLF, CRLF, file.getAsBinary(), CRLF, @@ -99,11 +101,12 @@ sendFile; // FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work) - if (xhr.upload || xhr.sendAsBinary) + if (xhr.upload || xhr.sendAsBinary) { sendFile = function (handler, maxSize, width, height) { if (-1 < maxSize && maxSize < handler.file.fileSize) { - if (isFunction(handler.onerror)) + if (isFunction(handler.onerror)) { handler.onerror(); + } return; } for (var @@ -116,28 +119,32 @@ i = 0; i < length; i++ - ) + ) { upload.addEventListener( split[i].substring(2), (function (event) { return function (rpe) { - if (isFunction(handler[event])) + if (isFunction(handler[event])) { handler[event](rpe, xhr); + } }; })(split[i]), false ); + } upload.addEventListener( "load", function (rpe) { if (handler.onreadystatechange === false) { - if (isFunction(handler.onload)) + if (isFunction(handler.onload)) { handler.onload(rpe, xhr); + } } else { setTimeout(function () { if (xhr.readyState === 4) { - if (isFunction(handler.onload)) + if (isFunction(handler.onload)) { handler.onload(rpe, xhr); + } } else { setTimeout(arguments.callee, 15); } @@ -146,13 +153,14 @@ }, false ); - xhr.open("post", handler.url + '&filename=' + BI.cjkEncode(handler.file.fileName), true); + xhr.open("post", handler.url + '&filename=' + FR.cjkEncode(handler.file.fileName), true); if (!xhr.upload) { var rpe = {loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true}; rpe.interval = setInterval(function () { rpe.loaded += 1024 / 4; - if (rpe.total <= rpe.loaded) + if (rpe.total <= rpe.loaded) { rpe.loaded = rpe.total; + } upload.onprogress(rpe); }, 100); xhr.onabort = function () { @@ -176,8 +184,8 @@ upload.onprogress(rpe); if (199 < xhr.status && xhr.status < 400) { upload["onload"]({}); - var attachO = BI.jsonDecode(xhr.responseText); - attachO.filename = BI.cjkDecode(handler.file.fileName); + var attachO = FR.jsonDecode(xhr.responseText); + attachO.filename = FR.cjkDecode(handler.file.fileName); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } @@ -193,11 +201,11 @@ xhr.onreadystatechange = function () { switch (xhr.readyState) { case 4: - var attachO = BI.jsonDecode(xhr.responseText); + var attachO = FR.jsonDecode(xhr.responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } - attachO.filename = BI.cjkDecode(handler.file.fileName); + attachO.filename = handler.file.fileName; if (handler.maxlength == 1) { handler.attach_array[0] = attachO; // handler.attach_array.push(attachO); @@ -222,8 +230,9 @@ } return handler; }; + } // Internet Explorer, Opera, others - else + else { sendFile = function (handler, maxSize, width, height) { var url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"), rpe = { @@ -242,13 +251,13 @@ //rpe.loaded = rpe.total; try { var responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; - var attachO = BI.jsonDecode(responseText); + var attachO = FR.jsonDecode(responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } //attachO.fileSize = responseText.length; - attachO.filename = BI.cjkDecode(handler.file.fileName); + attachO.filename = FR.cjkDecode(handler.file.fileName); if (handler.maxlength == 1) { handler.attach_array[0] = attachO; } else { @@ -272,13 +281,13 @@ iframe.setAttribute("name", iframe.id = target); iframe.setAttribute("src", url); } - ; iframe.style.position = "absolute"; iframe.style.left = iframe.style.top = "-10000px"; iframe.onload = onload; iframe.onerror = function (event) { - if (isFunction(handler.onerror)) + if (isFunction(handler.onerror)) { handler.onerror(rpe, event || window.event); + } }; iframe.onreadystatechange = function () { if (/loaded|complete/i.test(iframe.readyState)) { @@ -287,8 +296,9 @@ //wei : todo,将附件信息放到handler.attach } else if (isFunction(handler.onloadprogress)) { - if (rpe.loaded < rpe.total) + if (rpe.loaded < rpe.total) { ++rpe.loaded; + } handler.onloadprogress(rpe, { readyState: { loading: 2, @@ -299,13 +309,14 @@ }); } }; - form.setAttribute("action", handler.url + '&width=' + width + '&height=' + height); + form.setAttribute("action", handler.url); form.setAttribute("target", iframe.id); form.setAttribute("method", "post"); form.appendChild(handler.file); form.style.display = "none"; - if (isFunction(handler.onloadstart)) + if (isFunction(handler.onloadstart)) { handler.onloadstart(rpe, {}); + } with (document.body || document.documentElement) { appendChild(iframe); appendChild(form); @@ -314,6 +325,7 @@ ; return handler; }; + } xhr = null; return sendFile; })(Object.prototype.toString); @@ -359,7 +371,6 @@ handler.iframe.parentNode.removeChild(handler.iframe); handler.iframe = null; } - ; setTimeout(function () { handler.file = handler.files[handler.current]; sendFile(handler, maxSize, width, height).onload = callee; @@ -463,7 +474,7 @@ // enable again the submit button/element }, 1000); }; - _wrap.url = o.url ? o.url : BI.servletURL + _wrap.url = o.url ? o.url : FR.servletURL + '?op=fr_attach&cmd=ah_upload'; _wrap.fileType = o.accept; //文件类型限制 _wrap.attach_array = []; @@ -484,14 +495,14 @@ size = item.fileSize || item.size; if (wrap.fileType && -1 === wrap.fileType.indexOf("*." + ext)) { //文件类型不支持 - BI.Msg.toast("文件类型不支持"); + BI.Msg.toast(BI.i18nText("BI-Upload_File_Type_Error")); self.fireEvent(BI.File.EVENT_ERROR, { errorType: 0, file: item }); } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { //文件大小不支持 - BI.Msg.toast("文件大小不支持"); + BI.Msg.toast(BI.i18nText("BI-Upload_File_Size_Error")); self.fireEvent(BI.File.EVENT_ERROR, { errorType: 1, file: item @@ -516,7 +527,9 @@ var self = this, o = this.options; // be sure input accept multiple files var input = this.element[0]; - this.element.attr("multiple", "multiple"); + if (o.multiple === true) { + this.element.attr("multiple", "multiple"); + } input.value = ""; // wrap Object @@ -542,8 +555,9 @@ // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} upload: function (handler) { if (handler) { - for (var key in handler) + for (var key in handler) { this[key] = handler[key]; + } } sendFiles(this, this.maxSize); return this; diff --git a/src/base/single/input/input.js b/src/base/single/input/input.js index f362632b2..eb8cd2756 100644 --- a/src/base/single/input/input.js +++ b/src/base/single/input/input.js @@ -20,21 +20,28 @@ BI.Input = BI.inherit(BI.Single, { _init: function () { BI.Input.superclass._init.apply(this, arguments); var self = this; + var ctrlKey = false; + var inputEventValid = false; var _keydown = BI.debounce(function (keyCode) { - self.onKeyDown(keyCode); + self.onKeyDown(keyCode, ctrlKey); self._keydown_ = false; }, 300); var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, true); this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, true); this.element .keydown(function (e) { + inputEventValid = false; + ctrlKey = e.ctrlKey; self.fireEvent(BI.Input.EVENT_QUICK_DOWN); }) .keyup(function (e) { - self._keydown_ = true; - _keydown(e.keyCode); + if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { + self._keydown_ = true; + _keydown(e.keyCode); + } }) .on("input propertychange", function (e) { + inputEventValid = true; self._keydown_ = true; _keydown(e.keyCode); }) @@ -97,29 +104,10 @@ BI.Input = BI.inherit(BI.Single, { this._click(); }, - onKeyDown: function (keyCode) { + onKeyDown: function (keyCode, ctrlKey) { if (!this.isValid() || BI.trim(this._lastValidValue) !== BI.trim(this.getValue())) { this._checkValidationOnValueChange(); } - if (keyCode == BI.keyCode.ENTER) { - if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { - this.blur(); - this.fireEvent(BI.Input.EVENT_ENTER); - } else { - this.fireEvent(BI.Input.EVENT_RESTRICT); - } - } - if (keyCode == BI.keyCode.SPACE) { - this.fireEvent(BI.Input.EVENT_SPACE); - } - if (keyCode == BI.keyCode.BACKSPACE && this._lastValue == "") { - this.fireEvent(BI.Input.EVENT_REMOVE); - } - if (keyCode == BI.keyCode.BACKSPACE || keyCode == BI.keyCode.DELETE) { - this.fireEvent(BI.Input.EVENT_BACKSPACE); - } - this.fireEvent(BI.Input.EVENT_KEY_DOWN); - if (this.isValid() && BI.trim(this.getValue()) !== "") { if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") || (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { @@ -129,13 +117,35 @@ BI.Input = BI.inherit(BI.Single, { this.fireEvent(BI.Input.EVENT_START); } } + if (ctrlKey === true && keyCode === 86) {//ctrlKey+V + this._valueChange(); + } else { + if (keyCode == BI.KeyCode.ENTER) { + if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { + this.blur(); + this.fireEvent(BI.Input.EVENT_ENTER); + } else { + this.fireEvent(BI.Input.EVENT_RESTRICT); + } + } + if (keyCode == BI.KeyCode.SPACE) { + this.fireEvent(BI.Input.EVENT_SPACE); + } + if (keyCode == BI.KeyCode.BACKSPACE && this._lastValue == "") { + this.fireEvent(BI.Input.EVENT_REMOVE); + } + if (keyCode == BI.KeyCode.BACKSPACE || keyCode == BI.KeyCode.DELETE) { + this.fireEvent(BI.Input.EVENT_BACKSPACE); + } + } + this.fireEvent(BI.Input.EVENT_KEY_DOWN); - if (/(\s|\u00A0)$/.test(this.getValue())) { + if (BI.isEndWithBlank(this.getValue())) { this._pause = true; this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); this.fireEvent(BI.Input.EVENT_PAUSE); this._defaultState(); - } else if ((keyCode === BI.keyCode.BACKSPACE || keyCode === BI.keyCode.DELETE) && + } else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && BI.trim(this.getValue()) === "" && (this._lastValue !== null && BI.trim(this._lastValue) !== "")) { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); this.fireEvent(BI.Input.EVENT_STOP); diff --git a/src/base/single/input/radio.js b/src/base/single/input/radio.js index 583f5ee41..5b95e0ca9 100644 --- a/src/base/single/input/radio.js +++ b/src/base/single/input/radio.js @@ -7,7 +7,6 @@ BI.Radio = BI.inherit(BI.IconButton, { _defaultConfig: function() { var conf = BI.Radio.superclass._defaultConfig.apply(this,arguments); return BI.extend(conf, { - tagName: "a", baseCls: (conf.baseCls || "") + " bi-radio radio-icon", selected: false, handler: BI.emptyFn, diff --git a/src/base/single/label/label.js b/src/base/single/label/label.js index 48cc0cc6e..ab4fc8bf1 100644 --- a/src/base/single/label/label.js +++ b/src/base/single/label/label.js @@ -58,7 +58,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.adaptive", height: o.height, - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [ { @@ -76,7 +76,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.textWidth; BI.createWidget({ type: "bi.center_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [ { @@ -90,7 +90,7 @@ BI.Label = BI.inherit(BI.Single, { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.center_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -108,7 +108,7 @@ BI.Label = BI.inherit(BI.Single, { }); BI.createWidget({ type: "bi.absolute", - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), @@ -123,7 +123,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.width - 2 * o.hgap; BI.createWidget({ type: "bi.center_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)) @@ -135,7 +135,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.textWidth; BI.createWidget({ type: "bi.center_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [ { @@ -155,7 +155,7 @@ BI.Label = BI.inherit(BI.Single, { rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [this.text] }); @@ -169,7 +169,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.adaptive", height: o.height, - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), @@ -198,7 +198,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.layout", element: this.text, - scrollable: true + scrollable: o.whiteSpace === "normal" }); return; } @@ -225,7 +225,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.layout", element: this.text, - scrollable: true + scrollable: o.whiteSpace === "normal" }) }, @@ -238,7 +238,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.adaptive", height: o.height, - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [ { @@ -256,7 +256,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.textWidth; BI.createWidget({ type: "bi.vertical_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -276,7 +276,7 @@ BI.Label = BI.inherit(BI.Single, { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.vertical_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -294,7 +294,7 @@ BI.Label = BI.inherit(BI.Single, { }); BI.createWidget({ type: "bi.absolute", - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), @@ -309,7 +309,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.width - 2 * o.hgap - o.lgap - o.rgap; BI.createWidget({ type: "bi.vertical_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -327,7 +327,7 @@ BI.Label = BI.inherit(BI.Single, { json.width = o.textWidth; BI.createWidget({ type: "bi.vertical_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -347,7 +347,7 @@ BI.Label = BI.inherit(BI.Single, { this.text = BI.createWidget(json) this.text = BI.createWidget({ type: "bi.vertical_adapt", - scrollable: true, + scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, @@ -367,7 +367,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.adaptive", height: o.height, - scrollable: true, + scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), @@ -396,7 +396,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.layout", element: this.text, - scrollable: true + scrollable: o.whiteSpace === "normal" }); return; } @@ -423,7 +423,7 @@ BI.Label = BI.inherit(BI.Single, { BI.createWidget({ type: "bi.layout", element: this.text, - scrollable: true + scrollable: o.whiteSpace === "normal" }) }, @@ -452,6 +452,10 @@ BI.Label = BI.inherit(BI.Single, { return this.options.text; }, + setStyle: function (css) { + this.text.setStyle(css) + }, + setValue: function (v) { BI.Label.superclass.setValue.apply(this, arguments); if (!this.isReadOnly()) { diff --git a/src/base/single/text.js b/src/base/single/text.js index c92d934b2..b4bcdfd48 100644 --- a/src/base/single/text.js +++ b/src/base/single/text.js @@ -99,6 +99,10 @@ BI.Text = BI.inherit(BI.Single, { } }, + setStyle: function (css) { + this.text.element.css(css) + }, + setText: function (text) { BI.Text.superclass.setText.apply(this, arguments); this.options.text = text; diff --git a/src/base/timeouttoast/widget.timeouttoast.js b/src/base/timeouttoast/widget.timeouttoast.js new file mode 100644 index 000000000..b9ebf121b --- /dev/null +++ b/src/base/timeouttoast/widget.timeouttoast.js @@ -0,0 +1,117 @@ +/** + * 组件请求数据超时提示 + * Created by Young's on 2017/2/4. + */ +BI.TimeoutToast = BI.inherit(BI.Tip, { + _defaultConfig: function () { + return BI.extend(BI.TimeoutToast.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-timeout-toast" + }); + }, + + _init: function () { + BI.TimeoutToast.superclass._init.apply(this, arguments); + var self = this; + this.requests = []; + this.toast = BI.createWidget({ + type: "bi.vertical_adapt", + element: this, + items: [{ + type: "bi.label", + text: BI.i18nText("BI-Request_Time_Out_Toast_Tip") + }, { + type: "bi.text_button", + cls: "cancel-button", + width: 60, + height: 22, + text: BI.i18nText("BI-Basic_Cancel"), + title: BI.i18nText("BI-Basic_Cancel"), + handler: function () { + self.cancelAllRequests(); + } + }, { + type: "bi.text_button", + cls: "retry-button", + width: 60, + height: 22, + text: BI.i18nText("BI-Basic_Retry"), + title: BI.i18nText("BI-Basic_Retry"), + handler: function () { + self.toast.element.slideUp(500); + self._retryAll(); + } + }, { + type: "bi.icon_button", + cls: "close-font", + width: 20, + height: 20, + title: BI.i18nText("BI-Basic_Close"), + handler: function () { + self.toast.element.slideUp(500); + } + }], + width: 520, + height: 30, + hgap: 2 + }); + + BI.createWidget({ + type: "bi.absolute", + element: $("body"), + items: [{ + el: this.toast, + left: "50%", + top: 0 + }] + }); + this.toast.element.css({"margin-left": -1 * this.toast.element.outerWidth() / 2}); + this.toast.setVisible(false); + }, + + _retryAll: function () { + var self = this; + var clonedRequests = BI.deepClone(this.requests); + this.requests = []; + BI.each(clonedRequests, function (i, options) { + BI.isFunction(self.callback) && self.callback(options); + }); + }, + + cancelAllRequests: function () { + this.toast.element.slideUp(500); + BI.each(this.requests, function (i, reqArgs) { + if (BI.isNotNull(reqArgs) && BI.isFunction(reqArgs.complete)) { + reqArgs.complete(); + } + }); + this.requests = []; + }, + + setCallback: function (callback) { + this.callback = callback; + }, + + addReq: function (options) { + var self = this; + if (this.requests.length === 0) { + setTimeout(function () { + if (self.requests.contains(options)) { + self.toast.element.slideDown(500); + } + }, 5 * 60 * 1000); //5 min + } + this.requests.push(options); + }, + + removeReq: function (options) { + BI.remove(this.requests, options); + if (this.requests.length === 0) { + this.toast.element.slideUp(500); + } + }, + + hasReq: function (options) { + return this.requests.contains(options); + } +}); +$.shortcut("bi.timeout_toast", BI.TimeoutToast); \ No newline at end of file diff --git a/src/base/tree/3parttree.js b/src/base/tree/parttree.js similarity index 100% rename from src/base/tree/3parttree.js rename to src/base/tree/parttree.js diff --git a/src/base/tree/2synctree.js b/src/base/tree/synctree.js similarity index 87% rename from src/base/tree/2synctree.js rename to src/base/tree/synctree.js index 5f0e4becb..52486fa83 100644 --- a/src/base/tree/2synctree.js +++ b/src/base/tree/synctree.js @@ -19,7 +19,7 @@ BI.SyncTree = BI.inherit(BI.TreeView, { var setting = { async: { enable: false, - otherParam: BI.cjkEncodeDO(paras) + otherParam: FR.cjkEncodeDO(paras) }, check: { enable: true @@ -157,36 +157,24 @@ BI.SyncTree = BI.inherit(BI.TreeView, { } }, - _joinTree: function (map, values, isLast) { - var cur = map; - BI.each(values, function (i, value) { - if (i > 0 && BI.isPlainObject(cur) && BI.isEmpty(cur)) { - return; - } - if (isLast === true && i === values.length - 1) { - cur[value] = {}; - return; - } - if (cur[value] == null) { - cur[value] = {}; - } - cur = cur[value]; - }) - }, - _join: function (valueA, valueB) { var self = this; - var hashMap = valueA || {}; - track([], valueB); - function track(parent, node) { + var map = {}; + track([], valueA, valueB); + track([], valueB, valueA); + function track(parent, node, compare) { BI.each(node, function (n, item) { - var next = parent.concat([n]); - self._joinTree(hashMap, next, BI.isPlainObject(item) && BI.isEmpty(item)); - track(next, item); + if (BI.isNull(compare[n])) { + self._addTreeNode(map, parent, n, item); + } else if (BI.isEmpty(compare[n])) { + self._addTreeNode(map, parent, n, {}); + } else { + track(parent.concat([n]), node[n], compare[n]); + } }) } - return hashMap; + return map; }, hasChecked: function () { diff --git a/src/base/tree/1treeview.js b/src/base/tree/treeview.js similarity index 95% rename from src/base/tree/1treeview.js rename to src/base/tree/treeview.js index be25bed80..c65c5e730 100644 --- a/src/base/tree/1treeview.js +++ b/src/base/tree/treeview.js @@ -14,6 +14,9 @@ BI.TreeView = BI.inherit(BI.Pane, { }, _init: function () { BI.TreeView.superclass._init.apply(this, arguments); + FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.core-3.5.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.excheck-3.5.js', 'js'); + FR.$defaultImport('/com/fr/bi/web/css/base/third/ztree/zTreeStyle.css', 'css'); this._stop = false; this.container = BI.createWidget(); @@ -68,7 +71,7 @@ BI.TreeView = BI.inherit(BI.Pane, { enable: true, url: getUrl, autoParam: ["id", "name"], - otherParam: BI.cjkEncodeDO(paras) + otherParam: FR.cjkEncodeDO(paras) }, check: { enable: true @@ -110,10 +113,10 @@ BI.TreeView = BI.inherit(BI.Pane, { treeNode.times = treeNode.times || 1; var param = "id=" + treeNode.id + "×=" + (treeNode.times++) - + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode)) - + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus())); + + "&parent_values= " + window.encodeURIComponent(FR.jsonEncode(parentNode)) + + "&check_state=" + window.encodeURIComponent(FR.jsonEncode(treeNode.getCheckStatus())); - return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; + return FR.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; } function beforeExpand(treeId, treeNode) { @@ -310,7 +313,7 @@ BI.TreeView = BI.inherit(BI.Pane, { //处理标红 if (BI.isKey(o.paras.keyword)) { var keyword = o.paras.keyword; - var ns = BI.Tree.transformToArrayFormat(nodes); + var ns = BI.Tree.arrayFormat(nodes); BI.each(ns, function (i, n) { n.text = $("
      ").__textKeywordMarked__(n.text, keyword, n.py).html(); }); @@ -443,13 +446,17 @@ BI.TreeView = BI.inherit(BI.Pane, { }, setValue: function (value, param) { - this.options.paras.selected_values = value || {}; - this.selected_values = BI.deepClone(value) || {}; + this.setSelectedValue(value); this.checkAll(false); this.updateValue(value, param); this.refresh(); }, + setSelectedValue: function (value) { + this.options.paras.selected_values = value || {}; + this.selected_values = BI.deepClone(value) || {}; + }, + updateValue: function (values, param) { if (!this.nodes) { return; diff --git a/src/core/base.js b/src/core/base.js index 9d3da4835..0ea04ee91 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -33,7 +33,7 @@ if (!window.BI) { //Utility _.extend(BI, { i18nText: function (key) { - var localeText = key; + var localeText = FR.i18n[key]; if (!localeText) { localeText = key; } @@ -50,7 +50,7 @@ if (!window.BI) { assert: function (v, is) { if (this.isFunction(is)) { if (!is(v)) { - throw new Error(v + "值不合法"); + throw new Error(v + " error"); } else { return true; } @@ -59,7 +59,7 @@ if (!window.BI) { is = [is]; } if (!this.deepContains(is, v)) { - throw new Error(v + "值不合法"); + throw new Error(v + " error"); } }, @@ -81,9 +81,33 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, + createWidget: function (item, options) { + var el; + options || (options = {}); + if (BI.isEmpty(item) && BI.isEmpty(options)) { + return BI.Plugin.getObject("bi.layout", BI.createWidget({ + type: "bi.layout" + })); + } + if (BI.isWidget(item)) { + return item; + } + if (item && (item.type || options.type)) { + el = BI.extend({}, options, item); + return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); + } + if (item && item.el && (item.el.type || options.type)) { + el = BI.extend({}, options, item.el); + return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); + } + if (item && BI.isWidget(item.el)) { + return item.el; + } + }, + createWidgets: function (items, options) { if (!BI.isArray(items)) { - throw new Error("无法根据items创建组件?") + throw new Error("cannot create Widgets") } return BI.map(BI.flatten(items), function (i, item) { return BI.createWidget(item, BI.deepClone(options)); @@ -254,7 +278,9 @@ if (!window.BI) { backAny: function (obj, predicate, context) { predicate = BI.iteratee(predicate, context); for (var index = obj.length - 1; index >= 0; index--) { - if (predicate(index, obj[index], obj)) return true; + if (predicate(index, obj[index], obj)) { + return true; + } } return false; }, @@ -262,7 +288,9 @@ if (!window.BI) { backEvery: function (obj, predicate, context) { predicate = BI.iteratee(predicate, context); for (var index = obj.length - 1; index >= 0; index--) { - if (!predicate(index, obj[index], obj)) return false; + if (!predicate(index, obj[index], obj)) { + return false; + } } return true; }, @@ -388,7 +416,9 @@ if (!window.BI) { }, uniq: function (array, isSorted, iteratee, context) { - if (array == null) return []; + if (array == null) { + return []; + } if (!_.isBoolean(isSorted)) { context = iteratee; iteratee = isSorted; @@ -455,11 +485,7 @@ if (!window.BI) { }, isWidthOrHeight: function (w) { - if (typeof w == 'number') { - return w >= 0; - } else if (typeof w == 'string') { - return /^\d{1,3}%$/.exec(w) || w == 'auto' || /^\d+px$/.exec(w); - } + return FR.isWidthOrHeight(w); }, isNotNull: function (obj) { @@ -550,11 +576,15 @@ if (!window.BI) { isDeepMatch: function (object, attrs) { var keys = BI.keys(attrs), length = keys.length; - if (object == null) return !length; + if (object == null) { + return !length; + } var obj = Object(object); for (var i = 0; i < length; i++) { var key = keys[i]; - if (!BI.isEqual(attrs[key], obj[key]) || !(key in obj)) return false; + if (!BI.isEqual(attrs[key], obj[key]) || !(key in obj)) { + return false; + } } return true; }, @@ -580,20 +610,24 @@ if (!window.BI) { }, deepRemove: function (obj, target) { + var done = false; var i; if (BI.isArray(obj)) { for (i = 0; i < obj.length; i++) { if (BI.isEqual(target, obj[i])) { obj.splice(i--, 1); + done = true; } } } else { BI.each(obj, function (i, v) { if (BI.isEqual(target, obj[i])) { delete obj[i]; + done = true; } }); } + return done; }, deepWithout: function (obj, target) { @@ -616,8 +650,14 @@ if (!window.BI) { } }, - deepUniq: function () { - + deepUnique: function (array) { + var result = []; + BI.each(array, function (i, item) { + if (!BI.deepContains(result, item)) { + result.push(item); + } + }); + return result; }, //比较两个对象得出不一样的key值 @@ -668,31 +708,54 @@ if (!window.BI) { var copies = callbacks.slice(0); callbacks = []; for (var i = 0; i < copies.length; i++) { - copies[i].func.apply(null, copies[i].args); + copies[i](); } } + if (typeof Promise !== 'undefined') { + var p = Promise.resolve(); + timerFunc = function () { + p.then(nextTickHandler); + } + } else + /* istanbul ignore if */ if (typeof MutationObserver !== 'undefined') { var counter = 1; var observer = new MutationObserver(nextTickHandler); - var textNode = document.createTextNode(counter); + var textNode = document.createTextNode(counter + ""); observer.observe(textNode, { characterData: true }); timerFunc = function () { counter = (counter + 1) % 2; - textNode.data = counter; + textNode.data = counter + ""; } } else { - timerFunc = setTimeout + timerFunc = function () { + setTimeout(nextTickHandler, 0) + } } - return function (cb) { + return function queueNextTick(cb) { + var _resolve; var args = [].slice.call(arguments, 1); - callbacks.push({func: cb, args: args}); - if (pending) return; - pending = true; - timerFunc(nextTickHandler, 0); + callbacks.push(function () { + if (cb) { + cb.apply(null, args); + } + if (_resolve) { + _resolve.apply(null, args); + } + }); + if (!pending) { + pending = true; + timerFunc(); + } + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve) { + _resolve = resolve + }) + } } })() }); @@ -726,7 +789,7 @@ if (!window.BI) { try { return parseInt(number, radix); } catch (e) { - throw new Error("转成int类型失败"); + throw new Error(number + "parse int error"); return NaN; } }, @@ -735,7 +798,7 @@ if (!window.BI) { try { return parseFloat(number); } catch (e) { - throw new Error("转成float类型失败"); + throw new Error(number + "parse float error"); return NaN; } }, @@ -797,9 +860,9 @@ if (!window.BI) { var sum = 0; BI.each(array, function (i, item) { if (iteratee) { - sum += new Number(iteratee.apply(context, [i, item])); + sum += Number(iteratee.apply(context, [i, item])); } else { - sum += new Number(item); + sum += Number(item); } }); return sum; @@ -825,6 +888,10 @@ if (!window.BI) { return (string + "").toLocaleLowerCase(); }, + isEndWithBlank: function (string) { + return /(\s|\u00A0)$/.test(string); + }, + isLiteral: function (exp) { var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/ return literalValueRE.test(exp) @@ -858,6 +925,10 @@ if (!window.BI) { return BI.isString(str) && BI.isEmpty(str); }, + contentFormat: function () { + return FR.contentFormat.apply(FR, arguments); + }, + /** * 对字符串进行加密 {@link #decrypt} * @static @@ -971,23 +1042,23 @@ if (!window.BI) { //浏览器相关方法 _.extend(BI, { isIE: function () { - return $.browser.msie; + return /(msie|trident)/i.test(navigator.userAgent.toLowerCase()); }, isChrome: function () { - return $.browser.chrome; + return /chrome/i.test(navigator.userAgent.toLowerCase()); }, isFireFox: function () { - return $.browser.mozilla; + return /firefox/i.test(navigator.userAgent.toLowerCase()); }, isOpera: function () { - return $.browser.opera; + return /opera/i.test(navigator.userAgent.toLowerCase()); }, isSafari: function () { - return $.browser.safari; + return /safari/i.test(navigator.userAgent.toLowerCase()); }, isKhtml: function () { @@ -1021,6 +1092,124 @@ if (!window.BI) { //BI请求 _.extend(BI, { + ajax: (function () { + var loading, timeoutToast; + return function (option) { + option || (option = {}); + option.data = BI.extend({}, Data.SharingPool.cat("urlParameters"), option.data); + //encode + encodeBIParam(option.data); + + var async = true; + if (BI.isNotNull(option.async)) { + async = option.async; + } + + if (BI.isNull(loading)) { + loading = BI.createWidget({ + type: "bi.request_loading" + }); + } + + if (BI.isNull(timeoutToast)) { + timeoutToast = BI.createWidget({ + type: "bi.timeout_toast" + }); + timeoutToast.setCallback(function (op) { + decodeBIParam(op.data); + BI.ajax(op); + }); + } + timeoutToast.addReq(option); + + FR.ajax({ + url: option.url, + type: "POST", + data: option.data, + async: async, + error: function () { + if (!timeoutToast.hasReq(option)) { + return; + } + timeoutToast.removeReq(option); + //失败 取消、重新加载 + loading.setCallback(function () { + decodeBIParam(option.data); + BI.ajax(option); + }); + loading.showError(); + }, + complete: function (res, status) { + if (!timeoutToast.hasReq(option)) { + return; + } + timeoutToast.removeReq(option); + //登录超时 + if (BI.isNotNull(res.responseText) && + res.responseText.indexOf("fs-login-content") > -1 && + res.responseText.indexOf("fs-login-input-password-confirm") === -1) { + if (BI.Popovers.isVisible(BI.LoginTimeOut.POPOVER_ID)) { + return; + } + if (BI.isNotNull(BI.Popovers.get(BI.LoginTimeOut.POPOVER_ID))) { + BI.Popovers.open(BI.LoginTimeOut.POPOVER_ID); + return; + } + var loginTimeout = BI.createWidget({ + type: "bi.login_timeout" + }); + loginTimeout.on(BI.LoginTimeOut.EVENT_LOGIN, function () { + decodeBIParam(option.data); + BI.ajax(option); + BI.Popovers.remove(BI.LoginTimeOut.POPOVER_ID); + }); + BI.Popovers.create(BI.LoginTimeOut.POPOVER_ID, loginTimeout, { + width: 600, + height: 400 + }).open(BI.LoginTimeOut.POPOVER_ID); + } else if (BI.isNotNull(res.responseText) && + res.responseText.indexOf("script") > -1 && + res.responseText.indexOf("Session Timeout...") > -1) { + //登录失效 + loading.setCallback(function () { + location.reload(); + }); + loading.showError(); + + } else if (status === "success" && BI.isFunction(option.success)) { + option.success(FR.jsonDecode(res.responseText)); + } + if (BI.isFunction(option.complete)) { + option.complete(FR.jsonDecode(res.responseText), status); + } + } + }); + + return function cancel() { + timeoutToast.removeReq(option); + }; + + function encodeBIParam(data) { + for (var key in data) { + if (_.isObject(data[key])) { + data[key] = window.encodeURIComponent(FR.jsonEncode(data[key])); + } else { + data[key] = window.encodeURIComponent(data[key]); + } + } + } + + function decodeBIParam(data) { + for (var key in data) { + data[key] = window.decodeURIComponent(data[key]); + if (_.isObject(data[key])) { + data[key] = FR.jsonDecode(data[key]); + } + } + } + } + })(), + /** * 异步ajax请求 * @param {String} op op参数 @@ -1030,38 +1219,29 @@ if (!window.BI) { * @param {Function} complete 回调 */ requestAsync: function (op, cmd, data, callback, complete) { - // if (BI.isNull(BI.REQUEST_LOADING)) { - // BI.REQUEST_LOADING = BI.createWidget({ - // type: "bi.request_loading" - // }); - // } data = data || {}; if (!BI.isKey(op)) { op = 'fr_bi_dezi'; } - if (op === "fr_bi_dezi") { + if (op === "fr_bi_dezi" || op === "fr_bi_configure") { data.sessionID = Data.SharingPool.get("sessionID"); } var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); - (BI.ajax || FR.ajax)({ + return (BI.ajax)({ url: url, type: 'POST', data: data, error: function () { // BI.Msg.toast(BI.i18nText("BI-Ajax_Error")); - //失败 取消、重新加载 - // BI.REQUEST_LOADING.setCallback(function () { - // BI.requestAsync(op, cmd, data, callback, complete); - // }); - // BI.REQUEST_LOADING.showError(); }, - complete: function (res, status) { - if (BI.isFunction(callback) && status === 'success') { - callback(BI.jsonDecode(res.responseText)); - BI.Maskers.hide(BI.RequstLoading.MASK_ID); + success: function (res) { + if (BI.isFunction(callback)) { + callback(res); } + }, + complete: function (res, status) { if (BI.isFunction(complete)) { - complete(); + complete(res); } } }); @@ -1084,7 +1264,7 @@ if (!window.BI) { } var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); var result = {}; - (BI.ajax || FR.ajax)({ + (BI.ajax)({ url: url, type: 'POST', async: false, @@ -1094,7 +1274,7 @@ if (!window.BI) { }, complete: function (res, status) { if (status === 'success') { - result = BI.jsonDecode(res.responseText); + result = res; } } }); diff --git a/src/core/controller.js b/src/core/controller.js index c192ec542..91b5e4aee 100644 --- a/src/core/controller.js +++ b/src/core/controller.js @@ -3,7 +3,7 @@ * 控制器 * Controller层超类 * @class BI.Controller - * @extends FR.OB + * @extends BI.OB * @abstract */ BI.Controller = BI.inherit(BI.OB, { diff --git a/src/core/loader/loader.style.js b/src/core/loader/loader.style.js new file mode 100644 index 000000000..fbf027ce1 --- /dev/null +++ b/src/core/loader/loader.style.js @@ -0,0 +1,47 @@ +/** + * style加载管理器 + * + * Created by GUY on 2015/9/7. + * @class + */ +BI.StyleLoaderManager = BI.inherit(BI.OB, { + _defaultConfig: function () { + return BI.extend(BI.StyleLoaderManager.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.StyleLoaderManager.superclass._init.apply(this, arguments); + this.stylesManager = {}; + }, + + loadStyle: function (name, styleString) { + var d = document, styles = d.createElement('style'); + d.getElementsByTagName('head')[0].appendChild(styles); + styles.setAttribute('type', 'text/css'); + if (styles.styleSheet) { + styles.styleSheet.cssText = styleString; + } else { + styles.appendChild(document.createTextNode(styleString)); + } + this.stylesManager[name] = styles; + + return this; + }, + + get: function (name) { + return this.stylesManager[name]; + }, + + has: function (name) { + return this.stylesManager[name] != null; + }, + + removeStyle: function (name) { + if (!this.has(name)) { + return this; + } + this.stylesManager[name].parentNode.removeChild(this.stylesManager[name]); + delete this.stylesManager[name]; + return this; + } +}); \ No newline at end of file diff --git a/src/core/var.js b/src/core/var.js index 91c1e6338..e2f9947dd 100644 --- a/src/core/var.js +++ b/src/core/var.js @@ -15,7 +15,7 @@ _.extend(BI, { emptyFn: function () { }, empty: null, - keyCode: { + KeyCode: { BACKSPACE: 8, COMMA: 188, DELETE: 46, diff --git a/src/core/wrapper/layout/layout.card.js b/src/core/wrapper/layout/layout.card.js index a1aa6b3d0..910866da1 100644 --- a/src/core/wrapper/layout/layout.card.js +++ b/src/core/wrapper/layout/layout.card.js @@ -83,7 +83,6 @@ BI.CardLayout = BI.inherit(BI.Layout, { .appendTo(this.element); widget.invisible(); this.addWidget(this._getCardName(cardName), widget); - widget._mount(); return widget; }, @@ -101,7 +100,10 @@ BI.CardLayout = BI.inherit(BI.Layout, { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.element.hide(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, callback); + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, function () { + el._mount(); + callback && callback(); + }); } }); }, diff --git a/src/css/base/base.css b/src/css/base/base.css new file mode 100644 index 000000000..f3ec3f450 --- /dev/null +++ b/src/css/base/base.css @@ -0,0 +1,21 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +@font-face { + font-family: 'bbr'; + src: url('/resources/fonts/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('/resources/fonts/iconfont.woff') format('woff'), /* chrome、firefox */ url('/resources/fonts/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('/resources/fonts/iconfont.svg#svgFontName') format('svg'); + + /* iOS 4.1- */ +} +.b-font { + font-family: "bi"; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} +.bi-base-request-fail-mask .mask-pane { + background: #ffffff; + opacity: 0.8; + filter: alpha(opacity=80); +} diff --git a/src/css/base/chart/chart.combine.css b/src/css/base/chart/chart.combine.css new file mode 100644 index 000000000..1c94930a0 --- /dev/null +++ b/src/css/base/chart/chart.combine.css @@ -0,0 +1,11 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-combine-chart .bi-linkage-list { + background-color: #ffffff; + border: 1px solid #eaeaea; + z-index: 1000000000; +} +.bi-combine-chart .bi-linkage-list .bi-linkage-list-item:hover { + background-color: #f4f4f4; +} diff --git a/src/css/base/combo/popup.bubble.css b/src/css/base/combo/popup.bubble.css new file mode 100644 index 000000000..2423ffe25 --- /dev/null +++ b/src/css/base/combo/popup.bubble.css @@ -0,0 +1,11 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-bubble-popup-view { + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); +} +.bi-bubble-popup-view .bubble-popup-line { + background-color: #009de3; +} diff --git a/src/css/base/dom.css b/src/css/base/dom.css new file mode 100644 index 000000000..4429e3625 --- /dev/null +++ b/src/css/base/dom.css @@ -0,0 +1,9 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +/************hing light*****************/ +.bi-z-index-mask { + background-color: #1a1a1a; + opacity: 0.5; + filter: alpha(opacity=50); +} diff --git a/src/css/base/logintimeout/login.timeout.css b/src/css/base/logintimeout/login.timeout.css new file mode 100644 index 000000000..321da08dd --- /dev/null +++ b/src/css/base/logintimeout/login.timeout.css @@ -0,0 +1,32 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-login-timeout-center .input-wrapper { + border-bottom: 1px solid #eaeaea; +} +.bi-login-timeout-center .input-wrapper .login-input { + font-size: 16px; +} +.bi-login-timeout-center .input-wrapper .error-mask { + background: #1a1a1a; + opacity: 0.25; + filter: alpha(opacity=25); + color: #ffffff; + font-size: 16px; +} +.bi-login-timeout-center .login-button { + background: #009de3; + -webkit-border-radius: 25px; + -moz-border-radius: 25px; + border-radius: 25px; + font-size: 22px; + color: #ffffff; +} +.bi-login-timeout-center .login-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +.bi-login-timeout-south .keep-state { + font-size: 14px; + color: #808080; +} diff --git a/src/css/base/pager/pager.all.count.css b/src/css/base/pager/pager.all.count.css new file mode 100644 index 000000000..61dead711 --- /dev/null +++ b/src/css/base/pager/pager.all.count.css @@ -0,0 +1,9 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-all-count-pager .all-pager-prev { + font-size: 16px; +} +.bi-all-count-pager .all-pager-next { + font-size: 16px; +} diff --git a/src/css/base/pager/pager.direction.css b/src/css/base/pager/pager.direction.css index 4323bd17a..1984a00e9 100644 --- a/src/css/base/pager/pager.direction.css +++ b/src/css/base/pager/pager.direction.css @@ -3,9 +3,7 @@ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-direction-pager .direction-pager-prev { font-size: 16px; - background: #f4f4f4; } .bi-direction-pager .direction-pager-next { font-size: 16px; - background: #f4f4f4; } diff --git a/src/css/base/reqloading/loading.request.css b/src/css/base/reqloading/loading.request.css index c44f3b3fb..235bd2f21 100644 --- a/src/css/base/reqloading/loading.request.css +++ b/src/css/base/reqloading/loading.request.css @@ -7,8 +7,14 @@ filter: alpha(opacity=80); } .bi-request-loading .loading-comment { - font-size: 14px; + font-size: 20px; + color: #808080; } .bi-request-loading .load-fail-comment { - font-size: 14px; + font-size: 20px; + color: #808080; +} +.bi-request-loading .load-timeout-warning { + font-size: 16px; + color: #e85050; } diff --git a/src/css/base/single/editor/editor.state.css b/src/css/base/single/editor/editor.state.css index d1532829a..0d3f1bb14 100644 --- a/src/css/base/single/editor/editor.state.css +++ b/src/css/base/single/editor/editor.state.css @@ -1,10 +1,6 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-state-editor { - font-size: 12px; -} .bi-state-editor .state-editor-infinite-text { - font-size: 12px; - color: #1a1a1a; + color: #cccccc; } diff --git a/src/css/base/single/editor/editor.state.simple.css b/src/css/base/single/editor/editor.state.simple.css index 1e5c5a286..c2c892781 100644 --- a/src/css/base/single/editor/editor.state.simple.css +++ b/src/css/base/single/editor/editor.state.simple.css @@ -1,10 +1,6 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-simple-state-editor { - font-size: 12px; -} .bi-simple-state-editor .state-editor-infinite-text { - font-size: 12px; - color: #1a1a1a; + color: #cccccc; } diff --git a/src/css/base/single/text.css b/src/css/base/single/text.css index cf2c45754..0128c7c7c 100644 --- a/src/css/base/single/text.css +++ b/src/css/base/single/text.css @@ -5,5 +5,5 @@ text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; - word-break: break-word; + word-break: break-all; } diff --git a/src/css/base/third/ztree/zTreeStyle.css b/src/css/base/third/ztree/zTreeStyle.css index 2272c08b6..1ac2cf043 100644 --- a/src/css/base/third/ztree/zTreeStyle.css +++ b/src/css/base/third/ztree/zTreeStyle.css @@ -10,13 +10,10 @@ website: http://code.google.com/p/jquerytree/ .ztree * { padding: 0; margin: 0; - font-size: 12px; - font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif; } .ztree { margin: 0; padding: 5px; - color: #333333; } .ztree li { padding: 0; @@ -32,14 +29,13 @@ website: http://code.google.com/p/jquerytree/ padding: 0 0 0 18px; } .ztree li ul.line { - background: url(icon/tree-vertical-line-1.png) 0 0 repeat-y; + background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y; } .ztree li a { padding: 1px 3px 0 0; margin: 0; cursor: pointer; height: 24px; - color: #333; background-color: transparent; text-decoration: none; vertical-align: top; @@ -98,31 +94,31 @@ website: http://code.google.com/p/jquerytree/ cursor: auto; } .ztree li span.button.chk.checkbox_false_full { - background-image: url("icon/check-box-normal.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image: url("icon/check-box-normal.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable { background-position: 0 -56px; } .ztree li span.button.chk.checkbox_true_full { - background-image: url("icon/check-box-active.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image: url("icon/check-box-active.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable { background-position: -14px -56px; @@ -162,28 +158,28 @@ website: http://code.google.com/p/jquerytree/ height: 25px; } .ztree li span.button.root_open { - background-image: url("icon/tree-expand-1.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); } .ztree li span.button.root_close { - background-image: url("icon/tree-collapse-1.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); } .ztree li span.button.roots_open { - background-image: url("icon/tree-expand-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); } .ztree li span.button.roots_close { - background-image: url("icon/tree-collapse-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); } .ztree li span.button.center_open { - background-image: url("icon/tree-expand-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); } .ztree li span.button.center_close { - background-image: url("icon/tree-collapse-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open { - background-image: url("icon/tree-expand-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); } .ztree li span.button.bottom_close { - background-image: url("icon/tree-collapse-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); } .ztree li span.button.noline_open { background-position: -92px -72px; @@ -195,13 +191,13 @@ website: http://code.google.com/p/jquerytree/ background: none; } .ztree li span.button.roots_docu { - background-image: url("icon/tree-vertical-line-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu { - background-image: url("icon/tree-vertical-line-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu { - background-image: url("icon/tree-vertical-line-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu { background: none; diff --git a/src/css/base/timeouttoast/widget.timeouttoast.css b/src/css/base/timeouttoast/widget.timeouttoast.css new file mode 100644 index 000000000..6efd30424 --- /dev/null +++ b/src/css/base/timeouttoast/widget.timeouttoast.css @@ -0,0 +1,34 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-timeout-toast { + font-size: 14px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + background: #fddddd; + color: #e85050; +} +.bi-timeout-toast .cancel-button { + background: #ffffff; + border: 1px solid #d4dadd; + color: #1a1a1a; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} +.bi-timeout-toast .cancel-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +.bi-timeout-toast .retry-button { + background: #009de3; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + color: #ffffff; +} +.bi-timeout-toast .retry-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} diff --git a/src/css/base/view/popupview.css b/src/css/base/view/popupview.css index 38b7fba5f..0294fa968 100644 --- a/src/css/base/view/popupview.css +++ b/src/css/base/view/popupview.css @@ -14,6 +14,7 @@ -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + color: #1a1a1a; background: #ffffff; } .bi-list-view .list-view-toolbar { diff --git a/src/css/base/wrapper/flex.center.css b/src/css/base/wrapper/flex.center.css new file mode 100644 index 000000000..74feeac54 --- /dev/null +++ b/src/css/base/wrapper/flex.center.css @@ -0,0 +1,38 @@ +.bi-flex-center-layout { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: center; + /* 12版 */ + -webkit-justify-content: center; + -moz-justify-content: center; + -ms-justify-content: center; + -o-justify-content: center; + justify-content: center; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} diff --git a/src/css/base/wrapper/flex.horizontal.css b/src/css/base/wrapper/flex.horizontal.css new file mode 100644 index 000000000..195649267 --- /dev/null +++ b/src/css/base/wrapper/flex.horizontal.css @@ -0,0 +1,66 @@ +.bi-flex-horizontal-layout { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: flex-start; + /* 12版 */ + -webkit-align-items: flex-start; + -moz-align-items: flex-start; + -ms-align-items: flex-start; + -o-align-items: flex-start; + align-items: flex-start; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.bi-flex-horizontal-layout.middle { + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} +.bi-flex-horizontal-layout.bottom { + /* 09版 */ + -webkit-box-align: flex-end; + /* 12版 */ + -webkit-align-items: flex-end; + -moz-align-items: flex-end; + -ms-align-items: flex-end; + -o-align-items: flex-end; + align-items: flex-end; +} diff --git a/src/css/base/wrapper/flex.vertical.center.css b/src/css/base/wrapper/flex.vertical.center.css new file mode 100644 index 000000000..dd331f849 --- /dev/null +++ b/src/css/base/wrapper/flex.vertical.center.css @@ -0,0 +1,46 @@ +.bi-flex-vertical-center { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; +} diff --git a/src/css/base/wrapper/flex.wrapper.center.css b/src/css/base/wrapper/flex.wrapper.center.css new file mode 100644 index 000000000..a3f2e030e --- /dev/null +++ b/src/css/base/wrapper/flex.wrapper.center.css @@ -0,0 +1,41 @@ +.bi-flex-wrapper-center-layout .flex-wrapper-center-layout-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: center; + /* 12版 */ + -webkit-justify-content: center; + -moz-justify-content: center; + -ms-justify-content: center; + -o-justify-content: center; + justify-content: center; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + min-width: 100%; + min-height: 100%; + float: left; +} diff --git a/src/css/base/wrapper/flex.wrapper.horizontal.css b/src/css/base/wrapper/flex.wrapper.horizontal.css new file mode 100644 index 000000000..d3435658b --- /dev/null +++ b/src/css/base/wrapper/flex.wrapper.horizontal.css @@ -0,0 +1,67 @@ +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: flex-start; + /* 12版 */ + -webkit-align-items: flex-start; + -moz-align-items: flex-start; + -ms-align-items: flex-start; + -o-align-items: flex-start; + align-items: flex-start; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; + min-height: 100%; +} +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper.middle { + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper.bottom { + /* 09版 */ + -webkit-box-align: flex-end; + /* 12版 */ + -webkit-align-items: flex-end; + -moz-align-items: flex-end; + -ms-align-items: flex-end; + -o-align-items: flex-end; + align-items: flex-end; +} diff --git a/src/css/base/wrapper/flex.wrapper.vertical.center.css b/src/css/base/wrapper/flex.wrapper.vertical.center.css new file mode 100644 index 000000000..777983281 --- /dev/null +++ b/src/css/base/wrapper/flex.wrapper.vertical.center.css @@ -0,0 +1,48 @@ +.bi-flex-wrapper-vertical-center .flex-wrapper-vertical-center-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; + min-height: 100%; + float: left; +} diff --git a/src/less/base/base.less b/src/less/base/base.less new file mode 100644 index 000000000..b863c2e62 --- /dev/null +++ b/src/less/base/base.less @@ -0,0 +1,24 @@ +@import "../bibase"; + +@font-face { + font-family: 'bbr'; + src: url('@{webUrl}/resources/fonts/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('@{webUrl}/resources/fonts/iconfont.woff') format('woff'), /* chrome、firefox */ + url('@{webUrl}/resources/fonts/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ + url('@{webUrl}/resources/fonts/iconfont.svg#svgFontName') format('svg'); /* iOS 4.1- */ +} + +.b-font { + font-family: "bi"; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} + +.bi-base-request-fail-mask{ + & .mask-pane{ + background: @color-bi-background-default; + .opacity(0.8); + } +} \ No newline at end of file diff --git a/src/less/base/chart/chart.combine.less b/src/less/base/chart/chart.combine.less new file mode 100644 index 000000000..5a0426106 --- /dev/null +++ b/src/less/base/chart/chart.combine.less @@ -0,0 +1,13 @@ +@import "../../bibase"; +.bi-combine-chart { + & .bi-linkage-list { + background-color: @background-color-default; + border: 1px solid @border-color-line; + z-index: @zIndex-tip; + & .bi-linkage-list-item { + &:hover { + background-color: @color-bi-background-gray; + } + } + } +} \ No newline at end of file diff --git a/src/less/base/combo/combo.bubble.less b/src/less/base/combo/combo.bubble.less new file mode 100644 index 000000000..8eac71cea --- /dev/null +++ b/src/less/base/combo/combo.bubble.less @@ -0,0 +1,16 @@ +@import "../../bibase"; + +.bi-bubble-combo { + & .bubble-combo-triangle-left { + .solid-triangle-right(@color-bi-background-highlight); + } + & .bubble-combo-triangle-right { + .solid-triangle-left(@color-bi-background-highlight); + } + & .bubble-combo-triangle-top { + .solid-triangle-down(@color-bi-background-highlight); + } + & .bubble-combo-triangle-bottom { + .solid-triangle-up(@color-bi-background-highlight); + } +} \ No newline at end of file diff --git a/src/less/base/combo/popup.bubble.less b/src/less/base/combo/popup.bubble.less new file mode 100644 index 000000000..6c5ec1313 --- /dev/null +++ b/src/less/base/combo/popup.bubble.less @@ -0,0 +1,8 @@ +@import "../../bibase"; + +.bi-bubble-popup-view { + & .bubble-popup-line { + background-color: @color-bi-background-highlight; + } + .box-shadow(0 0 10px, rgba(0, 0, 0, 0.2)); +} \ No newline at end of file diff --git a/src/less/base/dom.less b/src/less/base/dom.less new file mode 100644 index 000000000..95c195b4b --- /dev/null +++ b/src/less/base/dom.less @@ -0,0 +1,7 @@ +@import "../bibase"; +@import "../lib/colors"; +/************hing light*****************/ +.bi-z-index-mask{ + background-color: @color-bi-background-black; + .opacity(0.5); +} \ No newline at end of file diff --git a/src/less/base/logintimeout/login.timeout.less b/src/less/base/logintimeout/login.timeout.less new file mode 100644 index 000000000..ebfa99736 --- /dev/null +++ b/src/less/base/logintimeout/login.timeout.less @@ -0,0 +1,30 @@ +@import "../../bibase"; +.bi-login-timeout-center{ + & .input-wrapper{ + border-bottom: 1px solid @color-bi-border-line; + & .login-input{ + font-size: @font-size-16; + } + & .error-mask{ + background: @color-bi-background-black; + .opacity(0.25); + color: @color-bi-text; + font-size: @font-size-16; + } + } + & .login-button{ + background: @color-bi-background-highlight; + .border-radius(25px); + font-size: @font-size-22; + color: @color-bi-text; + &:hover{ + .opacity(0.8); + } + } +} +.bi-login-timeout-south{ + & .keep-state{ + font-size: @font-size-14; + color: @color-bi-text-gray; + } +} \ No newline at end of file diff --git a/src/less/base/pager/pager.all.less b/src/less/base/pager/pager.all.count.less similarity index 50% rename from src/less/base/pager/pager.all.less rename to src/less/base/pager/pager.all.count.less index 4fad1a529..4b1499961 100644 --- a/src/less/base/pager/pager.all.less +++ b/src/less/base/pager/pager.all.count.less @@ -1,15 +1,12 @@ @import "../../bibase"; -.bi-all-pager { +.bi-all-count-pager { & .pager-editor { - background-color: @color-bi-background-default; } & .all-pager-prev { font-size: @font-size-16; - background: @color-bi-background-gray; } & .all-pager-next { font-size: @font-size-16; - background: @color-bi-background-gray; } } \ No newline at end of file diff --git a/src/less/base/pager/pager.direction.less b/src/less/base/pager/pager.direction.less index 8b4eaff8a..c15512fdb 100644 --- a/src/less/base/pager/pager.direction.less +++ b/src/less/base/pager/pager.direction.less @@ -3,10 +3,8 @@ .bi-direction-pager { & .direction-pager-prev { font-size: @font-size-16; - background: @color-bi-background-gray; } & .direction-pager-next { font-size: @font-size-16; - background: @color-bi-background-gray; } } \ No newline at end of file diff --git a/src/less/base/pager/pager.number.less b/src/less/base/pager/pager.number.less deleted file mode 100644 index 8170f697e..000000000 --- a/src/less/base/pager/pager.number.less +++ /dev/null @@ -1,12 +0,0 @@ -@import "../../bibase"; - -.bi-number-pager { - & .number-pager-prev { - font-size: @font-size-16; - background: @color-bi-background-gray; - } - & .number-pager-next { - font-size: @font-size-16; - background: @color-bi-background-gray; - } -} \ No newline at end of file diff --git a/src/less/base/pager/pager.skip.less b/src/less/base/pager/pager.skip.less deleted file mode 100644 index e4d956e7c..000000000 --- a/src/less/base/pager/pager.skip.less +++ /dev/null @@ -1,12 +0,0 @@ -@import "../../bibase"; - -.bi-skip-pager { - & .skip-pager-prev { - font-size: @font-size-16; - background: @color-bi-background-gray; - } - & .skip-pager-next { - font-size: @font-size-16; - background: @color-bi-background-gray; - } -} \ No newline at end of file diff --git a/src/less/base/reqloading/loading.request.less b/src/less/base/reqloading/loading.request.less index ee77ee074..ea2affda2 100644 --- a/src/less/base/reqloading/loading.request.less +++ b/src/less/base/reqloading/loading.request.less @@ -1,13 +1,20 @@ @import "../../bibase"; -.bi-request-loading{ - & .mask-pane{ + +.bi-request-loading { + & .mask-pane { background: @color-bi-background-default; .opacity(0.8); } - & .loading-comment{ - font-size: @font-size-14; + & .loading-comment { + font-size: 20px; + color: @color-bi-text-gray; } - & .load-fail-comment{ - font-size: @font-size-14; + & .load-fail-comment { + font-size: 20px; + color: @color-bi-text-gray; + } + & .load-timeout-warning { + font-size: @font-size-16; + color: @color-bi-text-warning; } } \ No newline at end of file diff --git a/src/less/base/single/editor/editor.state.less b/src/less/base/single/editor/editor.state.less index 9a541a242..d0db6d41e 100644 --- a/src/less/base/single/editor/editor.state.less +++ b/src/less/base/single/editor/editor.state.less @@ -2,9 +2,7 @@ .bi-state-editor{ - font-size: @font-size-12; & .state-editor-infinite-text{ - font-size: @font-size-12; - color: @font-color-normal; + color: @water-mark-color; } } \ No newline at end of file diff --git a/src/less/base/single/editor/editor.state.simple.less b/src/less/base/single/editor/editor.state.simple.less index c27a2a813..2204a08c0 100644 --- a/src/less/base/single/editor/editor.state.simple.less +++ b/src/less/base/single/editor/editor.state.simple.less @@ -2,9 +2,7 @@ .bi-simple-state-editor{ - font-size: @font-size-12; & .state-editor-infinite-text{ - font-size: @font-size-12; - color: @font-color-normal; + color: @water-mark-color; } } \ No newline at end of file diff --git a/src/less/base/single/text.less b/src/less/base/single/text.less index a6f1d83cd..568122a9c 100644 --- a/src/less/base/single/text.less +++ b/src/less/base/single/text.less @@ -2,5 +2,5 @@ .bi-text{ .overflow-dot(); - word-break: break-word; + word-break: break-all; } \ No newline at end of file diff --git a/src/less/base/table/table.grid.scrollbar.less b/src/less/base/table/table.grid.scrollbar.less index 0322c095c..408c42002 100644 --- a/src/less/base/table/table.grid.scrollbar.less +++ b/src/less/base/table/table.grid.scrollbar.less @@ -7,15 +7,14 @@ transition-timing-function: ease; user-select: none; background-color: rgba(0, 0, 0, 0.1); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#19000000, endColorstr=#19000000); - border-radius: 5px; + border-radius:5px; } .scrollbar-layout-main-vertical { bottom: 0; right: 0; top: 0; - transition-property: background-color; + transition-property: background-color ; width: 10px; } @@ -28,9 +27,8 @@ bottom: 0; height: 10px; left: 0; - transition-property: background-color; + transition-property: background-color ; background-color: rgba(0, 0, 0, 0.1); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#19000000, endColorstr=#19000000); } /* Touching the scroll-track directly makes the scroll-track bolder */ diff --git a/src/less/base/third/jquery.mCustomScrollbar.less b/src/less/base/third/jquery.mCustomScrollbar.less deleted file mode 100644 index 898d601b8..000000000 --- a/src/less/base/third/jquery.mCustomScrollbar.less +++ /dev/null @@ -1,1796 +0,0 @@ -/* -== malihu jquery custom scrollbar plugin == -Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller -*/ -/* -CONTENTS: - 1. BASIC STYLE - Plugin's basic/essential CSS properties (normally, should not be edited). - 2. VERTICAL SCROLLBAR - Positioning and dimensions of vertical scrollbar. - 3. HORIZONTAL SCROLLBAR - Positioning and dimensions of horizontal scrollbar. - 4. VERTICAL AND HORIZONTAL SCROLLBARS - Positioning and dimensions of 2-axis scrollbars. - 5. TRANSITIONS - CSS3 transitions for hover events, auto-expanded and auto-hidden scrollbars. - 6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS - 6.1 THEMES - Scrollbar colors, opacity, dimensions, backgrounds etc. via ready-to-use themes. -*/ -/* ------------------------------------------------------------------------------------------------------------------------- -1. BASIC STYLE ------------------------------------------------------------------------------------------------------------------------- -*/ -@import "../../bibase"; -@import "../../lib/font"; -@import "../../lib/colors"; - -.mCustomScrollbar { - -ms-touch-action: pinch-zoom; - touch-action: pinch-zoom; /* direct pointer events to js */ -} - -.mCustomScrollbar.mCS_no_scrollbar, .mCustomScrollbar.mCS_touch_action { - -ms-touch-action: auto; - touch-action: auto; -} - -.mCustomScrollBox { - /* contains plugin's markup */ - position: relative; - overflow: hidden; - height: 100%; - max-width: 100%; - outline: none; - direction: ltr; -} - -.mCSB_container { - /* contains the original content */ - overflow: hidden; - width: auto; - height: auto; -} - -/* ------------------------------------------------------------------------------------------------------------------------- -2. VERTICAL SCROLLBAR -y-axis ------------------------------------------------------------------------------------------------------------------------- -*/ - -.mCSB_inside > .mCSB_container { - margin-right: 30px; -} - -.mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; -} - -/* non-visible scrollbar */ - -.mCS-dir-rtl > .mCSB_inside > .mCSB_container { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} - -.mCS-dir-rtl > .mCSB_inside > .mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-left: 0; -} - -/* RTL direction/left-side scrollbar */ - -.mCSB_scrollTools { - /* contains scrollbar markup (draggable element, dragger rail, buttons etc.) */ - position: absolute; - width: 16px; - height: auto; - left: auto; - top: 0; - right: 0; - bottom: 0; -} - -.mCSB_outside + .mCSB_scrollTools { - right: -26px; -} - -/* scrollbar position: outside */ - -.mCS-dir-rtl > .mCSB_inside > .mCSB_scrollTools, -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - /* RTL direction/left-side scrollbar */ - right: auto; - left: 0; -} - -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - left: -26px; -} - -/* RTL direction/left-side scrollbar (scrollbar position: outside) */ - -.mCSB_scrollTools .mCSB_draggerContainer { - /* contains the draggable element and dragger rail markup */ - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - height: auto; -} - -.mCSB_scrollTools a + .mCSB_draggerContainer { - margin: 20px 0; -} - -.mCSB_scrollTools .mCSB_draggerRail { - width: 2px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} - -.mCSB_scrollTools .mCSB_dragger { - /* the draggable element */ - cursor: pointer; - width: 100%; - height: 30px; /* minimum dragger height */ - z-index: 1; -} - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - /* the dragger element */ - position: relative; - width: 4px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; - text-align: center; -} - -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 12px; /* auto-expanded scrollbar */ -} - -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 8px; /* auto-expanded scrollbar */ -} - -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown { - display: block; - position: absolute; - height: 20px; - width: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} - -.mCSB_scrollTools .mCSB_buttonDown { - bottom: 0; -} - -/* ------------------------------------------------------------------------------------------------------------------------- -3. HORIZONTAL SCROLLBAR -x-axis ------------------------------------------------------------------------------------------------------------------------- -*/ - -.mCSB_horizontal.mCSB_inside > .mCSB_container { - margin-right: 0; - margin-bottom: 30px; -} - -.mCSB_horizontal.mCSB_outside > .mCSB_container { - min-height: 100%; -} - -.mCSB_horizontal > .mCSB_container.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} - -/* non-visible scrollbar */ - -.mCSB_scrollTools.mCSB_scrollTools_horizontal { - width: auto; - height: 16px; - top: auto; - right: 0; - bottom: 0; - left: 0; -} - -.mCustomScrollBox + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: -26px; -} - -/* scrollbar position: outside */ - -.mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 20px; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 2px; - margin: 7px 0; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 30px; /* minimum dragger width */ - height: 100%; - left: 0; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} - -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 12px; /* auto-expanded scrollbar */ - margin: 2px auto; -} - -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 8px; /* auto-expanded scrollbar */ - margin: 4px 0; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft, -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - display: block; - position: absolute; - width: 20px; - height: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft { - left: 0; -} - -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - right: 0; -} - -/* ------------------------------------------------------------------------------------------------------------------------- -4. VERTICAL AND HORIZONTAL SCROLLBARS -yx-axis ------------------------------------------------------------------------------------------------------------------------- -*/ - -.mCSB_container_wrapper { - position: absolute; - height: auto; - width: auto; - overflow: hidden; - top: 0; - left: 0; - right: 0; - bottom: 0; - margin-right: 30px; - margin-bottom: 30px; -} - -.mCSB_container_wrapper > .mCSB_container { - padding-right: 30px; - padding-bottom: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 20px; -} - -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 20px; -} - -/* non-visible horizontal scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden + .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 0; -} - -/* non-visible vertical scrollbar/RTL direction/left-side scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 0; -} - -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 20px; -} - -/* non-visible scrollbar/RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 0; -} - -.mCS-dir-rtl > .mCSB_inside > .mCSB_container_wrapper { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} - -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden > .mCSB_container { - padding-right: 0; -} - -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden > .mCSB_container { - padding-bottom: 0; -} - -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; /* non-visible scrollbar */ - margin-left: 0; -} - -/* non-visible horizontal scrollbar */ -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} - -/* ------------------------------------------------------------------------------------------------------------------------- -5. TRANSITIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -.mCSB_scrollTools, -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - -webkit-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; - -moz-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; - -o-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; - transition: opacity .2s ease-in-out, background-color .2s ease-in-out; -} - -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, /* auto-expanded scrollbar */ -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail { - -webkit-transition: width .2s ease-out .2s, height .2s ease-out .2s, - margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, - margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, - opacity .2s ease-in-out, background-color .2s ease-in-out; - -moz-transition: width .2s ease-out .2s, height .2s ease-out .2s, - margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, - margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, - opacity .2s ease-in-out, background-color .2s ease-in-out; - -o-transition: width .2s ease-out .2s, height .2s ease-out .2s, - margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, - margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, - opacity .2s ease-in-out, background-color .2s ease-in-out; - transition: width .2s ease-out .2s, height .2s ease-out .2s, - margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, - margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, - opacity .2s ease-in-out, background-color .2s ease-in-out; -} - -/* ------------------------------------------------------------------------------------------------------------------------- -6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS ------------------------------------------------------------------------------------------------------------------------- -*/ - -/* ----------------------------------------- -6.1 THEMES ----------------------------------------- -*/ - -/* default theme ("light") */ - -.mCSB_scrollTools { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} - -.mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 0; - filter: "alpha(opacity=0)"; - -ms-filter: "alpha(opacity=0)"; -} - -.mCustomScrollbar > .mCustomScrollBox > .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollbar > .mCustomScrollBox ~ .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollBox:hover > .mCSB_scrollTools, -.mCustomScrollBox:hover ~ .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=100)"; - -ms-filter: "alpha(opacity=100)"; -} - -.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.4); - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} - -.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); - filter: "alpha(opacity=85)"; - -ms-filter: "alpha(opacity=85)"; -} - -.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} - -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - background-image: url('@{imageUrl}background/mCSB_buttons.png'); /* css sprites */ - background-repeat: no-repeat; - opacity: 0.4; - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} - -.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 0; - /* - sprites locations - light: 0 0, -16px 0, -32px 0, -48px 0, 0 -72px, -16px -72px, -32px -72px - dark: -80px 0, -96px 0, -112px 0, -128px 0, -80px -72px, -96px -72px, -112px -72px - */ -} - -.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -20px; - /* - sprites locations - light: 0 -20px, -16px -20px, -32px -20px, -48px -20px, 0 -92px, -16px -92px, -32px -92px - dark: -80px -20px, -96px -20px, -112px -20px, -128px -20px, -80px -92px, -96px -92px, -112 -92px - */ -} - -.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -40px; - /* - sprites locations - light: 0 -40px, -20px -40px, -40px -40px, -60px -40px, 0 -112px, -20px -112px, -40px -112px - dark: -80px -40px, -100px -40px, -120px -40px, -140px -40px, -80px -112px, -100px -112px, -120px -112px - */ -} - -.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -56px; - /* - sprites locations - light: 0 -56px, -20px -56px, -40px -56px, -60px -56px, 0 -128px, -20px -128px, -40px -128px - dark: -80px -56px, -100px -56px, -120px -56px, -140px -56px, -80px -128px, -100px -128px, -120px -128px - */ -} - -.mCSB_scrollTools .mCSB_buttonUp:hover, -.mCSB_scrollTools .mCSB_buttonDown:hover, -.mCSB_scrollTools .mCSB_buttonLeft:hover, -.mCSB_scrollTools .mCSB_buttonRight:hover { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} - -.mCSB_scrollTools .mCSB_buttonUp:active, -.mCSB_scrollTools .mCSB_buttonDown:active, -.mCSB_scrollTools .mCSB_buttonLeft:active, -.mCSB_scrollTools .mCSB_buttonRight:active { - opacity: 0.9; - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} - -/* theme: "dark" */ - -.mCS-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} - -.mCS-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} - -.mCS-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} - -.mCS-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} - -.mCS-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} - -/* ---------------------------------------- */ - -/* theme: "light-2", "dark-2" */ - -.mCS-light-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} - -.mCS-light-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} - -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} - -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} - -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} - -.mCS-light-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px 0; -} - -.mCS-light-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -20px; -} - -.mCS-light-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -40px; -} - -.mCS-light-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -56px; -} - -/* theme: "dark-2" */ - -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px 0; -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -20px; -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -40px; -} - -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -56px; -} - -/* ---------------------------------------- */ - -/* theme: "light-thick", "dark-thick" */ - -.mCS-light-thick.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 4px; - margin: 6px 0; -} - -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 6px; - margin: 5px auto; -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px 0; -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -20px; -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -40px; -} - -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -56px; -} - -/* theme: "dark-thick" */ - -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px 0; -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -20px; -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -40px; -} - -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -56px; -} - -/* ---------------------------------------- */ - -/* theme: "light-thin", "dark-thin" */ - -.mCS-light-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); -} - -.mCS-light-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 2px; -} - -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; -} - -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 2px; - margin: 7px auto; -} - -/* theme "dark-thin" */ - -.mCS-dark-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} - -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} - -/* ---------------------------------------- */ - -/* theme "rounded", "rounded-dark", "rounded-dots", "rounded-dots-dark" */ - -.mCS-rounded.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.15); -} - -.mCS-rounded.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger { - height: 14px; -} - -.mCS-rounded.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 1px; -} - -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 14px; -} - -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 14px; - margin: 1px 0; -} - -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 16px; /* auto-expanded scrollbar */ - height: 16px; - margin: -1px 0; -} - -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 4px; /* auto-expanded scrollbar */ -} - -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 16px; /* auto-expanded scrollbar */ - width: 16px; - margin: 0 -1px; -} - -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 4px; /* auto-expanded scrollbar */ - margin: 6px 0; -} - -.mCS-rounded.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 -72px; -} - -.mCS-rounded.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -92px; -} - -.mCS-rounded.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -112px; -} - -.mCS-rounded.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -128px; -} - -/* theme "rounded-dark", "rounded-dots-dark" */ - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px -72px; -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -92px; -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -112px; -} - -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -128px; -} - -/* theme "rounded-dots", "rounded-dots-dark" */ - -.mCS-rounded-dots.mCSB_scrollTools_vertical .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_vertical .mCSB_draggerRail { - width: 4px; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - background-color: transparent; - background-position: center; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAANElEQVQYV2NkIAAYiVbw//9/Y6DiM1ANJoyMjGdBbLgJQAX/kU0DKgDLkaQAvxW4HEvQFwCRcxIJK1XznAAAAABJRU5ErkJggg=="); - background-repeat: repeat-y; - opacity: 0.3; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} - -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - height: 4px; - margin: 6px 0; - background-repeat: repeat-x; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px -72px; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -92px; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -112px; -} - -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -128px; -} - -/* theme "rounded-dots-dark" */ - -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALElEQVQYV2NkIAAYSVFgDFR8BqrBBEifBbGRTfiPZhpYjiQFBK3A6l6CvgAAE9kGCd1mvgEAAAAASUVORK5CYII="); -} - -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px -72px; -} - -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -92px; -} - -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -112px; -} - -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -128px; -} - -/* ---------------------------------------- */ - -/* theme "3d", "3d-dark", "3d-thick", "3d-thick-dark" */ - -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-y; - background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to right, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} - -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-x; - background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} - -/* theme "3d", "3d-dark" */ - -.mCS-3d.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 70px; -} - -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 70px; -} - -.mCS-3d.mCSB_scrollTools, -.mCS-3d-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} - -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} - -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 8px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.5), inset -1px 0 1px rgba(255, 255, 255, 0.2); -} - -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} - -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 8px; -} - -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 8px; - margin: 4px 0; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5), inset 0 -1px 1px rgba(255, 255, 255, 0.2); -} - -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 8px; - margin: 4px auto; -} - -.mCS-3d.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} - -.mCS-3d.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} - -.mCS-3d.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} - -.mCS-3d.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} - -/* theme "3d-dark" */ - -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1); -} - -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); -} - -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} - -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} - -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} - -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} - -/* ---------------------------------------- */ - -/* theme: "3d-thick", "3d-thick-dark" */ - -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} - -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools, -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.mCSB_inside + .mCS-3d-thick.mCSB_scrollTools_vertical, -.mCSB_inside + .mCS-3d-thick-dark.mCSB_scrollTools_vertical { - right: 1px; -} - -.mCS-3d-thick.mCSB_scrollTools_vertical, -.mCS-3d-thick-dark.mCSB_scrollTools_vertical { - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} - -.mCS-3d-thick.mCSB_scrollTools_horizontal, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - bottom: 1px; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4); - width: 12px; - margin: 2px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} - -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 12px; - width: auto; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #000; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} - -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} - -/* theme: "3d-thick-dark" */ - -.mCS-3d-thick-dark.mCSB_scrollTools { - box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2); -} - -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.2); -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4), inset -1px 0 0 rgba(0, 0, 0, 0.2); -} - -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), inset 0 -1px 0 rgba(0, 0, 0, 0.2); -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #777; -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #fff; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} - -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} - -/* ---------------------------------------- */ - -/* theme: "minimal", "minimal-dark" */ - -.mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - right: 0; - margin: 12px 0; -} - -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: 0; - margin: 0 12px; -} - -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - left: 0; - right: auto; -} - -.mCS-minimal.mCSB_scrollTools .mCSB_draggerRail, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} - -.mCS-minimal.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 50px; -} - -.mCS-minimal.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 50px; -} - -.mCS-minimal.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} - -.mCS-minimal.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} - -/* theme: "minimal-dark" */ - -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} - -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} - -/* ---------------------------------------- */ - -/* theme "light-3", "dark-3" */ - -.mCS-light-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - width: 6px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} - -.mCS-light-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; -} - -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 6px; - margin: 5px 0; -} - -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 12px; -} - -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 12px; - margin: 2px 0; -} - -.mCS-light-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} - -.mCS-light-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} - -.mCS-light-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} - -.mCS-light-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} - -/* theme "dark-3" */ - -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} - -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} - -/* ---------------------------------------- */ - -/* theme "inset", "inset-dark", "inset-2", "inset-2-dark", "inset-3", "inset-3-dark" */ - -.mCS-inset.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 12px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} - -.mCS-inset.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - margin: 3px 5px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 6px; - margin: 5px 3px; - position: absolute; - width: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 12px; - margin: 2px 0; -} - -.mCS-inset.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} - -.mCS-inset.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} - -.mCS-inset.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} - -.mCS-inset.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} - -/* theme "inset-dark", "inset-2-dark", "inset-3-dark" */ - -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} - -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} - -/* theme "inset-2", "inset-2-dark" */ - -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; - border-width: 1px; - border-style: solid; - border-color: #fff; - border-color: rgba(255, 255, 255, 0.2); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - border-color: #000; - border-color: rgba(0, 0, 0, 0.2); -} - -/* theme "inset-3", "inset-3-dark" */ - -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.6); -} - -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.6); -} - -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} - -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} - -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} - -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); -} - -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} - -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} - -/* ---------------------------------------- */ - -/* theme "bi-default" */ -.mCS-bi-default { - & { - background-color: #dddddd; - } - & .mCSB_scrollTools.mCSB_scrollTools_horizontal { - height: 18px; - } - & .mCSB_scrollTools.mCSB_scrollTools_vertical { - width: 18px; - } - & .mCSB_scrollTools .mCSB_draggerRail { - border-radius: 0px; - } - & .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - border-radius: 2px; - } - & .mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 18px; - } - & .mCSB_scrollTools.mCSB_scrollTools_vertical a + .mCSB_draggerContainer { - margin: 18px 0; - } -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 2px; -} - -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 14px; - margin: 2px auto; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - width: 18px; - height: 100%; - margin: 0; -} - -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 18px; - margin: 0; -} - -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 14px; -} - -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 14px; - margin: 2px 0; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: @color-bi-background-gray; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - background-color: #dddddd; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - width: 16px; - height: 16px; - background-color: @color-bi-background-gray; - border: 1px solid @color-bi-border-line; - .opacity(1); -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp { - background-position: -128px -1px; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown { - background-position: -128px -21px; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -142px -40px; -} - -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - background-position: -141px -56px; -} - -/* ---------------------------------------- */ \ No newline at end of file diff --git a/src/less/base/third/ztree/img/line_conn.gif b/src/less/base/third/ztree/img/line_conn.gif new file mode 100644 index 0000000000000000000000000000000000000000..d561d36a915776730eb3069cee4c949f027667ed GIT binary patch literal 45 xcmZ?wbhEHbT_)p@)n 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 Ap8x;= literal 0 HcmV?d00001 diff --git a/src/less/base/third/ztree/img/zTreeStandard.png b/src/less/base/third/ztree/img/zTreeStandard.png new file mode 100644 index 0000000000000000000000000000000000000000..ffda01ef1cccc398ee4e2327f4093ba1130a4961 GIT binary patch literal 11173 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 X3wf1`XyoU;TL_tNiW1dgpn(4aGkUu% literal 0 HcmV?d00001 diff --git a/src/less/base/third/ztree/zTreeStyle.less b/src/less/base/third/ztree/zTreeStyle.less index f6edbb45c..5a94e0230 100644 --- a/src/less/base/third/ztree/zTreeStyle.less +++ b/src/less/base/third/ztree/zTreeStyle.less @@ -8,13 +8,13 @@ website: http://code.google.com/p/jquerytree/ -------------------------------------*/ -.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} -.ztree {margin:0; padding:5px; color:#333} +.ztree * {padding:0; margin:0; } +.ztree {margin:0; padding:5px; } .ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} .ztree li ul{ margin:0; padding:0 0 0 18px} -.ztree li ul.line{ background:url(icon/tree-vertical-line-1.png) 0 0 repeat-y;} +.ztree li ul.line{ background:url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y;} -.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:24px; color:#333; background-color: transparent; +.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:24px; background-color: transparent; text-decoration:none; vertical-align:top; display: inline-block} .ztree li a.curSelectedNode {} .ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} @@ -32,29 +32,29 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.chk {width:16px; height:16px; margin:0 3px 0 0; cursor: auto} .ztree li span.button.chk.checkbox_false_full { - background-image:url("icon/check-box-normal.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image:url("icon/check-box-normal.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image:url("icon/half_selected.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image:url("icon/half_selected.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} .ztree li span.button.chk.checkbox_true_full { - background-image:url("icon/check-box-active.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image:url("icon/check-box-active.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image:url("icon/half_selected.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image:url("icon/half_selected.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} .ztree li span.button.chk.radio_false_full {background-position:-28px 0} @@ -70,40 +70,40 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.switch {width:25px; height:25px} .ztree li span.button.root_open{ - background-image:url("icon/tree-expand-1.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); } .ztree li span.button.root_close{ - background-image:url("icon/tree-collapse-1.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); } .ztree li span.button.roots_open{ - background-image:url("icon/tree-expand-2.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); } .ztree li span.button.roots_close{ - background-image:url("icon/tree-collapse-2.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); } .ztree li span.button.center_open{ - background-image:url("icon/tree-expand-3.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); } .ztree li span.button.center_close{ - background-image:url("icon/tree-collapse-3.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open{ - background-image:url("icon/tree-expand-4.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); } .ztree li span.button.bottom_close{ - background-image:url("icon/tree-collapse-4.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); } .ztree li span.button.noline_open{background-position:-92px -72px} .ztree li span.button.noline_close{background-position:-74px -72px} .ztree li span.button.root_docu{ background:none;} .ztree li span.button.roots_docu{ - background-image:url("icon/tree-vertical-line-2.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu{ - background-image:url("icon/tree-vertical-line-3.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu{ - background-image:url("icon/tree-vertical-line-4.png"); + background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu{ background:none;} diff --git a/src/less/base/timeouttoast/widget.timeouttoast.less b/src/less/base/timeouttoast/widget.timeouttoast.less new file mode 100644 index 000000000..b9447cd36 --- /dev/null +++ b/src/less/base/timeouttoast/widget.timeouttoast.less @@ -0,0 +1,25 @@ +@import "../../bibase"; + +.bi-timeout-toast { + font-size: @font-size-14; + .border-radius(2px); + background: @color-bi-tip-warning-background; + color: @color-bi-text-warning; + & .cancel-button { + background: @color-bi-background-default; + border: 1px solid @color-bi-border-normal; + color: @color-bi-text-black; + .border-radius(2px); + &:hover { + .opacity(0.8); + } + } + & .retry-button { + background: @color-bi-background-highlight; + .border-radius(2px); + color: @color-bi-text; + &:hover { + .opacity(0.8); + } + } +} \ No newline at end of file diff --git a/src/less/base/view/popupview.less b/src/less/base/view/popupview.less index e077d7f20..79bc39e2e 100644 --- a/src/less/base/view/popupview.less +++ b/src/less/base/view/popupview.less @@ -11,6 +11,7 @@ & .list-view-outer{ border: 1px solid @color-bi-split-dark; .border-radius(2px); + color: @color-bi-text-black; background:@color-bi-background-default; } & .list-view-toolbar { From fb06141b8d50e772ade37d060544f7bc42f8bb16 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 15:14:25 +0800 Subject: [PATCH 08/19] add --- dist/base.css | 2005 ++++------------- dist/core.js | 276 ++- src/core/base.js | 8 +- src/css/base/pager/pager.all.css | 14 - src/css/base/pager/pager.number.css | 11 - src/css/base/pager/pager.skip.css | 11 - .../base/third/jquery.mCustomScrollbar.css | 1481 ------------ 7 files changed, 691 insertions(+), 3115 deletions(-) delete mode 100644 src/css/base/pager/pager.all.css delete mode 100644 src/css/base/pager/pager.number.css delete mode 100644 src/css/base/pager/pager.skip.css delete mode 100644 src/css/base/third/jquery.mCustomScrollbar.css diff --git a/dist/base.css b/dist/base.css index 6505eea15..867afd467 100644 --- a/dist/base.css +++ b/dist/base.css @@ -1,6 +1,38 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ +@font-face { + font-family: 'bbr'; + src: url('/resources/fonts/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('/resources/fonts/iconfont.woff') format('woff'), /* chrome、firefox */ url('/resources/fonts/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ url('/resources/fonts/iconfont.svg#svgFontName') format('svg'); + + /* iOS 4.1- */ +} +.b-font { + font-family: "bi"; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} +.bi-base-request-fail-mask .mask-pane { + background: #ffffff; + opacity: 0.8; + filter: alpha(opacity=80); +} +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-combine-chart .bi-linkage-list { + background-color: #ffffff; + border: 1px solid #eaeaea; + z-index: 1000000000; +} +.bi-combine-chart .bi-linkage-list .bi-linkage-list-item:hover { + background-color: #f4f4f4; +} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ @@ -41,6 +73,26 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ +.bi-bubble-popup-view { + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); +} +.bi-bubble-popup-view .bubble-popup-line { + background-color: #009de3; +} +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +/************hing light*****************/ +.bi-z-index-mask { + background-color: #1a1a1a; + opacity: 0.5; + filter: alpha(opacity=50); +} +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ /* BASICS */ .CodeMirror { /* Set height, width, borders, and global font properties here */ @@ -586,62 +638,65 @@ li.CodeMirror-hint-active { /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-all-pager .pager-editor { - background-color: #ffffff; +.bi-login-timeout-center .input-wrapper { + border-bottom: 1px solid #eaeaea; } -.bi-all-pager .all-pager-prev { +.bi-login-timeout-center .input-wrapper .login-input { font-size: 16px; - background: #f4f4f4; } -.bi-all-pager .all-pager-next { +.bi-login-timeout-center .input-wrapper .error-mask { + background: #1a1a1a; + opacity: 0.25; + filter: alpha(opacity=25); + color: #ffffff; font-size: 16px; - background: #f4f4f4; } -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.bi-pager .page-item { - border: 1px solid #d4dadd; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.bi-pager .page-item.active { +.bi-login-timeout-center .login-button { background: #009de3; + -webkit-border-radius: 25px; + -moz-border-radius: 25px; + border-radius: 25px; + font-size: 22px; color: #ffffff; } +.bi-login-timeout-center .login-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +.bi-login-timeout-south .keep-state { + font-size: 14px; + color: #808080; +} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-direction-pager .direction-pager-prev { +.bi-all-count-pager .all-pager-prev { font-size: 16px; - background: #f4f4f4; } -.bi-direction-pager .direction-pager-next { +.bi-all-count-pager .all-pager-next { font-size: 16px; - background: #f4f4f4; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-number-pager .number-pager-prev { - font-size: 16px; - background: #f4f4f4; +.bi-pager .page-item { + border: 1px solid #d4dadd; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; } -.bi-number-pager .number-pager-next { - font-size: 16px; - background: #f4f4f4; +.bi-pager .page-item.active { + background: #009de3; + color: #ffffff; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-skip-pager .skip-pager-prev { +.bi-direction-pager .direction-pager-prev { font-size: 16px; - background: #f4f4f4; } -.bi-skip-pager .skip-pager-next { +.bi-direction-pager .direction-pager-next { font-size: 16px; - background: #f4f4f4; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ @@ -652,10 +707,16 @@ li.CodeMirror-hint-active { filter: alpha(opacity=80); } .bi-request-loading .loading-comment { - font-size: 14px; + font-size: 20px; + color: #808080; } .bi-request-loading .load-fail-comment { - font-size: 14px; + font-size: 20px; + color: #808080; +} +.bi-request-loading .load-timeout-warning { + font-size: 16px; + color: #e85050; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ @@ -857,22 +918,14 @@ li.CodeMirror-hint-active { /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-state-editor { - font-size: 12px; -} .bi-state-editor .state-editor-infinite-text { - font-size: 12px; - color: #1a1a1a; + color: #cccccc; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -.bi-simple-state-editor { - font-size: 12px; -} .bi-simple-state-editor .state-editor-infinite-text { - font-size: 12px; - color: #1a1a1a; + color: #cccccc; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ @@ -930,7 +983,7 @@ li.CodeMirror-hint-active { text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; - word-break: break-word; + word-break: break-all; } /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ @@ -1271,1487 +1324,6 @@ li.CodeMirror-hint-active { overflow: hidden; background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/marker.png) no-repeat; } -/* -== malihu jquery custom scrollbar plugin == -Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller -*/ -/* -CONTENTS: - 1. BASIC STYLE - Plugin's basic/essential CSS properties (normally, should not be edited). - 2. VERTICAL SCROLLBAR - Positioning and dimensions of vertical scrollbar. - 3. HORIZONTAL SCROLLBAR - Positioning and dimensions of horizontal scrollbar. - 4. VERTICAL AND HORIZONTAL SCROLLBARS - Positioning and dimensions of 2-axis scrollbars. - 5. TRANSITIONS - CSS3 transitions for hover events, auto-expanded and auto-hidden scrollbars. - 6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS - 6.1 THEMES - Scrollbar colors, opacity, dimensions, backgrounds etc. via ready-to-use themes. -*/ -/* ------------------------------------------------------------------------------------------------------------------------- -1. BASIC STYLE ------------------------------------------------------------------------------------------------------------------------- -*/ -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.mCustomScrollbar { - -ms-touch-action: pinch-zoom; - touch-action: pinch-zoom; - /* direct pointer events to js */ -} -.mCustomScrollbar.mCS_no_scrollbar, -.mCustomScrollbar.mCS_touch_action { - -ms-touch-action: auto; - touch-action: auto; -} -.mCustomScrollBox { - /* contains plugin's markup */ - position: relative; - overflow: hidden; - height: 100%; - max-width: 100%; - outline: none; - direction: ltr; -} -.mCSB_container { - /* contains the original content */ - overflow: hidden; - width: auto; - height: auto; -} -/* ------------------------------------------------------------------------------------------------------------------------- -2. VERTICAL SCROLLBAR -y-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_inside > .mCSB_container { - margin-right: 30px; -} -.mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; -} -/* non-visible scrollbar */ -.mCS-dir-rtl > .mCSB_inside > .mCSB_container { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} -.mCS-dir-rtl > .mCSB_inside > .mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-left: 0; -} -/* RTL direction/left-side scrollbar */ -.mCSB_scrollTools { - /* contains scrollbar markup (draggable element, dragger rail, buttons etc.) */ - position: absolute; - width: 16px; - height: auto; - left: auto; - top: 0; - right: 0; - bottom: 0; -} -.mCSB_outside + .mCSB_scrollTools { - right: -26px; -} -/* scrollbar position: outside */ -.mCS-dir-rtl > .mCSB_inside > .mCSB_scrollTools, -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - /* RTL direction/left-side scrollbar */ - right: auto; - left: 0; -} -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - left: -26px; -} -/* RTL direction/left-side scrollbar (scrollbar position: outside) */ -.mCSB_scrollTools .mCSB_draggerContainer { - /* contains the draggable element and dragger rail markup */ - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - height: auto; -} -.mCSB_scrollTools a + .mCSB_draggerContainer { - margin: 20px 0; -} -.mCSB_scrollTools .mCSB_draggerRail { - width: 2px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} -.mCSB_scrollTools .mCSB_dragger { - /* the draggable element */ - cursor: pointer; - width: 100%; - height: 30px; - /* minimum dragger height */ - z-index: 1; -} -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - /* the dragger element */ - position: relative; - width: 4px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; - text-align: center; -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 12px; - /* auto-expanded scrollbar */ -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 8px; - /* auto-expanded scrollbar */ -} -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown { - display: block; - position: absolute; - height: 20px; - width: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} -.mCSB_scrollTools .mCSB_buttonDown { - bottom: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -3. HORIZONTAL SCROLLBAR -x-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_horizontal.mCSB_inside > .mCSB_container { - margin-right: 0; - margin-bottom: 30px; -} -.mCSB_horizontal.mCSB_outside > .mCSB_container { - min-height: 100%; -} -.mCSB_horizontal > .mCSB_container.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} -/* non-visible scrollbar */ -.mCSB_scrollTools.mCSB_scrollTools_horizontal { - width: auto; - height: 16px; - top: auto; - right: 0; - bottom: 0; - left: 0; -} -.mCustomScrollBox + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: -26px; -} -/* scrollbar position: outside */ -.mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 20px; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 2px; - margin: 7px 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 30px; - /* minimum dragger width */ - height: 100%; - left: 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 12px; - /* auto-expanded scrollbar */ - margin: 2px auto; -} -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 8px; - /* auto-expanded scrollbar */ - margin: 4px 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft, -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - display: block; - position: absolute; - width: 20px; - height: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft { - left: 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - right: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -4. VERTICAL AND HORIZONTAL SCROLLBARS -yx-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_container_wrapper { - position: absolute; - height: auto; - width: auto; - overflow: hidden; - top: 0; - left: 0; - right: 0; - bottom: 0; - margin-right: 30px; - margin-bottom: 30px; -} -.mCSB_container_wrapper > .mCSB_container { - padding-right: 30px; - padding-bottom: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 20px; -} -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 20px; -} -/* non-visible horizontal scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden + .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 0; -} -/* non-visible vertical scrollbar/RTL direction/left-side scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 0; -} -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 20px; -} -/* non-visible scrollbar/RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 0; -} -.mCS-dir-rtl > .mCSB_inside > .mCSB_container_wrapper { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden > .mCSB_container { - padding-right: 0; -} -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden > .mCSB_container { - padding-bottom: 0; -} -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; - /* non-visible scrollbar */ - margin-left: 0; -} -/* non-visible horizontal scrollbar */ -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -5. TRANSITIONS ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_scrollTools, -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - -webkit-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail { - -webkit-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -moz-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -o-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; -} -/* ------------------------------------------------------------------------------------------------------------------------- -6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS ------------------------------------------------------------------------------------------------------------------------- -*/ -/* ----------------------------------------- -6.1 THEMES ----------------------------------------- -*/ -/* default theme ("light") */ -.mCSB_scrollTools { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 0; - filter: "alpha(opacity=0)"; - -ms-filter: "alpha(opacity=0)"; -} -.mCustomScrollbar > .mCustomScrollBox > .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollbar > .mCustomScrollBox ~ .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollBox:hover > .mCSB_scrollTools, -.mCustomScrollBox:hover ~ .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=100)"; - -ms-filter: "alpha(opacity=100)"; -} -.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.4); - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); - filter: "alpha(opacity=85)"; - -ms-filter: "alpha(opacity=85)"; -} -.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - background-image: url('background/mCSB_buttons.png'); - /* css sprites */ - background-repeat: no-repeat; - opacity: 0.4; - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} -.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 0; - /* - sprites locations - light: 0 0, -16px 0, -32px 0, -48px 0, 0 -72px, -16px -72px, -32px -72px - dark: -80px 0, -96px 0, -112px 0, -128px 0, -80px -72px, -96px -72px, -112px -72px - */ -} -.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -20px; - /* - sprites locations - light: 0 -20px, -16px -20px, -32px -20px, -48px -20px, 0 -92px, -16px -92px, -32px -92px - dark: -80px -20px, -96px -20px, -112px -20px, -128px -20px, -80px -92px, -96px -92px, -112 -92px - */ -} -.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -40px; - /* - sprites locations - light: 0 -40px, -20px -40px, -40px -40px, -60px -40px, 0 -112px, -20px -112px, -40px -112px - dark: -80px -40px, -100px -40px, -120px -40px, -140px -40px, -80px -112px, -100px -112px, -120px -112px - */ -} -.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -56px; - /* - sprites locations - light: 0 -56px, -20px -56px, -40px -56px, -60px -56px, 0 -128px, -20px -128px, -40px -128px - dark: -80px -56px, -100px -56px, -120px -56px, -140px -56px, -80px -128px, -100px -128px, -120px -128px - */ -} -.mCSB_scrollTools .mCSB_buttonUp:hover, -.mCSB_scrollTools .mCSB_buttonDown:hover, -.mCSB_scrollTools .mCSB_buttonLeft:hover, -.mCSB_scrollTools .mCSB_buttonRight:hover { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCSB_scrollTools .mCSB_buttonUp:active, -.mCSB_scrollTools .mCSB_buttonDown:active, -.mCSB_scrollTools .mCSB_buttonLeft:active, -.mCSB_scrollTools .mCSB_buttonRight:active { - opacity: 0.9; - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} -/* theme: "dark" */ -.mCS-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-2", "dark-2" */ -.mCS-light-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px 0; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -20px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -40px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -56px; -} -/* theme: "dark-2" */ -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px 0; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -20px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -40px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-thick", "dark-thick" */ -.mCS-light-thick.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 4px; - margin: 6px 0; -} -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 6px; - margin: 5px auto; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px 0; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -20px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -40px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -56px; -} -/* theme: "dark-thick" */ -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px 0; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -20px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -40px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-thin", "dark-thin" */ -.mCS-light-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); -} -.mCS-light-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 2px; -} -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; -} -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 2px; - margin: 7px auto; -} -/* theme "dark-thin" */ -.mCS-dark-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} -/* ---------------------------------------- */ -/* theme "rounded", "rounded-dark", "rounded-dots", "rounded-dots-dark" */ -.mCS-rounded.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.15); -} -.mCS-rounded.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger { - height: 14px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 1px; -} -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 14px; -} -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 14px; - margin: 1px 0; -} -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 16px; - /* auto-expanded scrollbar */ - height: 16px; - margin: -1px 0; -} -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 4px; - /* auto-expanded scrollbar */ -} -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 16px; - /* auto-expanded scrollbar */ - width: 16px; - margin: 0 -1px; -} -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 4px; - /* auto-expanded scrollbar */ - margin: 6px 0; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 -72px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -92px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -112px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -128px; -} -/* theme "rounded-dark", "rounded-dots-dark" */ -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px -72px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -92px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -112px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -128px; -} -/* theme "rounded-dots", "rounded-dots-dark" */ -.mCS-rounded-dots.mCSB_scrollTools_vertical .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_vertical .mCSB_draggerRail { - width: 4px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - background-color: transparent; - background-position: center; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAANElEQVQYV2NkIAAYiVbw//9/Y6DiM1ANJoyMjGdBbLgJQAX/kU0DKgDLkaQAvxW4HEvQFwCRcxIJK1XznAAAAABJRU5ErkJggg=="); - background-repeat: repeat-y; - opacity: 0.3; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - height: 4px; - margin: 6px 0; - background-repeat: repeat-x; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px -72px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -92px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -112px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -128px; -} -/* theme "rounded-dots-dark" */ -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALElEQVQYV2NkIAAYSVFgDFR8BqrBBEifBbGRTfiPZhpYjiQFBK3A6l6CvgAAE9kGCd1mvgEAAAAASUVORK5CYII="); -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px -72px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -92px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -112px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -128px; -} -/* ---------------------------------------- */ -/* theme "3d", "3d-dark", "3d-thick", "3d-thick-dark" */ -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-y; - background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to right, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-x; - background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} -/* theme "3d", "3d-dark" */ -.mCS-3d.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 70px; -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 70px; -} -.mCS-3d.mCSB_scrollTools, -.mCS-3d-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 8px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.5), inset -1px 0 1px rgba(255, 255, 255, 0.2); -} -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 8px; -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 8px; - margin: 4px 0; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5), inset 0 -1px 1px rgba(255, 255, 255, 0.2); -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 8px; - margin: 4px auto; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "3d-dark" */ -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1); -} -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme: "3d-thick", "3d-thick-dark" */ -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools, -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.mCSB_inside + .mCS-3d-thick.mCSB_scrollTools_vertical, -.mCSB_inside + .mCS-3d-thick-dark.mCSB_scrollTools_vertical { - right: 1px; -} -.mCS-3d-thick.mCSB_scrollTools_vertical, -.mCS-3d-thick-dark.mCSB_scrollTools_vertical { - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} -.mCS-3d-thick.mCSB_scrollTools_horizontal, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - bottom: 1px; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4); - width: 12px; - margin: 2px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 12px; - width: auto; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #000; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme: "3d-thick-dark" */ -.mCS-3d-thick-dark.mCSB_scrollTools { - box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4), inset -1px 0 0 rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), inset 0 -1px 0 rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #777; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #fff; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme: "minimal", "minimal-dark" */ -.mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - right: 0; - margin: 12px 0; -} -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: 0; - margin: 0 12px; -} -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - left: 0; - right: auto; -} -.mCS-minimal.mCSB_scrollTools .mCSB_draggerRail, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-minimal.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 50px; -} -.mCS-minimal.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 50px; -} -.mCS-minimal.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} -.mCS-minimal.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} -/* theme: "minimal-dark" */ -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} -/* ---------------------------------------- */ -/* theme "light-3", "dark-3" */ -.mCS-light-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - width: 6px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} -.mCS-light-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; -} -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 6px; - margin: 5px 0; -} -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 12px; -} -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 12px; - margin: 2px 0; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "dark-3" */ -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme "inset", "inset-dark", "inset-2", "inset-2-dark", "inset-3", "inset-3-dark" */ -.mCS-inset.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 12px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} -.mCS-inset.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - margin: 3px 5px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 6px; - margin: 5px 3px; - position: absolute; - width: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 12px; - margin: 2px 0; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "inset-dark", "inset-2-dark", "inset-3-dark" */ -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* theme "inset-2", "inset-2-dark" */ -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; - border-width: 1px; - border-style: solid; - border-color: #fff; - border-color: rgba(255, 255, 255, 0.2); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - border-color: #000; - border-color: rgba(0, 0, 0, 0.2); -} -/* theme "inset-3", "inset-3-dark" */ -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.6); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.6); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -/* ---------------------------------------- */ -/* theme "bi-default" */ -.mCS-bi-default { - background-color: #dddddd; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_horizontal { - height: 18px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_vertical { - width: 18px; -} -.mCS-bi-default .mCSB_scrollTools .mCSB_draggerRail { - border-radius: 0px; -} -.mCS-bi-default .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - border-radius: 2px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 18px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_vertical a + .mCSB_draggerContainer { - margin: 18px 0; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 2px; -} -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 14px; - margin: 2px auto; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - width: 18px; - height: 100%; - margin: 0; -} -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 18px; - margin: 0; -} -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 14px; -} -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 14px; - margin: 2px 0; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #f4f4f4; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - background-color: #dddddd; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - width: 16px; - height: 16px; - background-color: #f4f4f4; - border: 1px solid #eaeaea; - opacity: 1; - filter: alpha(opacity=100); -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp { - background-position: -128px -1px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown { - background-position: -128px -21px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -142px -40px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - background-position: -141px -56px; -} -/* ---------------------------------------- */ /* required styles */ .leaflet-pane, .leaflet-tile, @@ -3255,13 +1827,10 @@ website: http://code.google.com/p/jquerytree/ .ztree * { padding: 0; margin: 0; - font-size: 12px; - font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif; } .ztree { margin: 0; padding: 5px; - color: #333333; } .ztree li { padding: 0; @@ -3277,14 +1846,13 @@ website: http://code.google.com/p/jquerytree/ padding: 0 0 0 18px; } .ztree li ul.line { - background: url(icon/tree-vertical-line-1.png) 0 0 repeat-y; + background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y; } .ztree li a { padding: 1px 3px 0 0; margin: 0; cursor: pointer; height: 24px; - color: #333; background-color: transparent; text-decoration: none; vertical-align: top; @@ -3343,31 +1911,31 @@ website: http://code.google.com/p/jquerytree/ cursor: auto; } .ztree li span.button.chk.checkbox_false_full { - background-image: url("icon/check-box-normal.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image: url("icon/check-box-normal.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable { background-position: 0 -56px; } .ztree li span.button.chk.checkbox_true_full { - background-image: url("icon/check-box-active.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image: url("icon/check-box-active.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image: url("icon/half_selected.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable { background-position: -14px -56px; @@ -3407,28 +1975,28 @@ website: http://code.google.com/p/jquerytree/ height: 25px; } .ztree li span.button.root_open { - background-image: url("icon/tree-expand-1.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); } .ztree li span.button.root_close { - background-image: url("icon/tree-collapse-1.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); } .ztree li span.button.roots_open { - background-image: url("icon/tree-expand-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); } .ztree li span.button.roots_close { - background-image: url("icon/tree-collapse-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); } .ztree li span.button.center_open { - background-image: url("icon/tree-expand-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); } .ztree li span.button.center_close { - background-image: url("icon/tree-collapse-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open { - background-image: url("icon/tree-expand-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); } .ztree li span.button.bottom_close { - background-image: url("icon/tree-collapse-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); } .ztree li span.button.noline_open { background-position: -92px -72px; @@ -3440,13 +2008,13 @@ website: http://code.google.com/p/jquerytree/ background: none; } .ztree li span.button.roots_docu { - background-image: url("icon/tree-vertical-line-2.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu { - background-image: url("icon/tree-vertical-line-3.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu { - background-image: url("icon/tree-vertical-line-4.png"); + background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu { background: none; @@ -3538,6 +2106,40 @@ ul.ztree.zTreeDragUL { /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ +.bi-timeout-toast { + font-size: 14px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + background: #fddddd; + color: #e85050; +} +.bi-timeout-toast .cancel-button { + background: #ffffff; + border: 1px solid #d4dadd; + color: #1a1a1a; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} +.bi-timeout-toast .cancel-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +.bi-timeout-toast .retry-button { + background: #009de3; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + color: #ffffff; +} +.bi-timeout-toast .retry-button:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ .bi-branch-tree .bi-branch-tree-view { min-width: 300px; } @@ -3637,6 +2239,7 @@ ul.ztree.zTreeDragUL { -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + color: #1a1a1a; background: #ffffff; } .bi-list-view .list-view-toolbar { @@ -3668,6 +2271,312 @@ ul.ztree.zTreeDragUL { .bi-scroll-view .scroll-drop-down-icon:active { background: #d4dadd; } +.bi-flex-center-layout { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: center; + /* 12版 */ + -webkit-justify-content: center; + -moz-justify-content: center; + -ms-justify-content: center; + -o-justify-content: center; + justify-content: center; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} +.bi-flex-horizontal-layout { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: flex-start; + /* 12版 */ + -webkit-align-items: flex-start; + -moz-align-items: flex-start; + -ms-align-items: flex-start; + -o-align-items: flex-start; + align-items: flex-start; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.bi-flex-horizontal-layout.middle { + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} +.bi-flex-horizontal-layout.bottom { + /* 09版 */ + -webkit-box-align: flex-end; + /* 12版 */ + -webkit-align-items: flex-end; + -moz-align-items: flex-end; + -ms-align-items: flex-end; + -o-align-items: flex-end; + align-items: flex-end; +} +.bi-flex-vertical-center { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.bi-flex-wrapper-center-layout .flex-wrapper-center-layout-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: center; + /* 12版 */ + -webkit-justify-content: center; + -moz-justify-content: center; + -ms-justify-content: center; + -o-justify-content: center; + justify-content: center; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + min-width: 100%; + min-height: 100%; + float: left; +} +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: flex-start; + /* 12版 */ + -webkit-align-items: flex-start; + -moz-align-items: flex-start; + -ms-align-items: flex-start; + -o-align-items: flex-start; + align-items: flex-start; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; + min-height: 100%; +} +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper.middle { + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; +} +.bi-flex-wrapper-horizontal-layout .flex-wrapper-horizontal-layout-wrapper.bottom { + /* 09版 */ + -webkit-box-align: flex-end; + /* 12版 */ + -webkit-align-items: flex-end; + -moz-align-items: flex-end; + -ms-align-items: flex-end; + -o-align-items: flex-end; + align-items: flex-end; +} +.bi-flex-wrapper-vertical-center .flex-wrapper-vertical-center-wrapper { + display: box; + /* OLD - Android 4.4- */ + display: -webkit-box; + /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; + /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; + /* TWEENER - IE 10 */ + display: -webkit-flex; + /* NEW - Chrome */ + display: flex; + /* NEW, Spec - Opera 12.1, Firefox 20+ */ + /* 09版 */ + -webkit-box-orient: horizontal; + /* 12版 */ + -webkit-flex-direction: row; + -moz-flex-direction: row; + -ms-flex-direction: row; + -o-flex-direction: row; + flex-direction: row; + /* 09版 */ + -webkit-box-pack: flex-start; + /* 12版 */ + -webkit-justify-content: flex-start; + -moz-justify-content: flex-start; + -ms-justify-content: flex-start; + -o-justify-content: flex-start; + justify-content: flex-start; + /* 09版 */ + -webkit-box-align: center; + /* 12版 */ + -webkit-align-items: center; + -moz-align-items: center; + -ms-align-items: center; + -o-align-items: center; + align-items: center; + /* 09版 */ + /*-webkit-box-lines: multiple;*/ + /* 12版 */ + -webkit-flex-wrap: nowrap; + -moz-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + -o-flex-wrap: nowrap; + flex-wrap: nowrap; + min-height: 100%; + float: left; +} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ diff --git a/dist/core.js b/dist/core.js index 61b8b721e..918dffeab 100644 --- a/dist/core.js +++ b/dist/core.js @@ -12906,7 +12906,7 @@ if (!window.BI) { //Utility _.extend(BI, { i18nText: function (key) { - var localeText = key; + var localeText = ""; if (!localeText) { localeText = key; } @@ -12923,7 +12923,7 @@ if (!window.BI) { assert: function (v, is) { if (this.isFunction(is)) { if (!is(v)) { - throw new Error(v + "值不合法"); + throw new Error(v + " error"); } else { return true; } @@ -12932,7 +12932,7 @@ if (!window.BI) { is = [is]; } if (!this.deepContains(is, v)) { - throw new Error(v + "值不合法"); + throw new Error(v + " error"); } }, @@ -12954,9 +12954,33 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, + createWidget: function (item, options) { + var el; + options || (options = {}); + if (BI.isEmpty(item) && BI.isEmpty(options)) { + return BI.Plugin.getObject("bi.layout", BI.createWidget({ + type: "bi.layout" + })); + } + if (BI.isWidget(item)) { + return item; + } + if (item && (item.type || options.type)) { + el = BI.extend({}, options, item); + return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); + } + if (item && item.el && (item.el.type || options.type)) { + el = BI.extend({}, options, item.el); + return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); + } + if (item && BI.isWidget(item.el)) { + return item.el; + } + }, + createWidgets: function (items, options) { if (!BI.isArray(items)) { - throw new Error("无法根据items创建组件?") + throw new Error("cannot create Widgets") } return BI.map(BI.flatten(items), function (i, item) { return BI.createWidget(item, BI.deepClone(options)); @@ -13127,7 +13151,9 @@ if (!window.BI) { backAny: function (obj, predicate, context) { predicate = BI.iteratee(predicate, context); for (var index = obj.length - 1; index >= 0; index--) { - if (predicate(index, obj[index], obj)) return true; + if (predicate(index, obj[index], obj)) { + return true; + } } return false; }, @@ -13135,7 +13161,9 @@ if (!window.BI) { backEvery: function (obj, predicate, context) { predicate = BI.iteratee(predicate, context); for (var index = obj.length - 1; index >= 0; index--) { - if (!predicate(index, obj[index], obj)) return false; + if (!predicate(index, obj[index], obj)) { + return false; + } } return true; }, @@ -13261,7 +13289,9 @@ if (!window.BI) { }, uniq: function (array, isSorted, iteratee, context) { - if (array == null) return []; + if (array == null) { + return []; + } if (!_.isBoolean(isSorted)) { context = iteratee; iteratee = isSorted; @@ -13423,11 +13453,15 @@ if (!window.BI) { isDeepMatch: function (object, attrs) { var keys = BI.keys(attrs), length = keys.length; - if (object == null) return !length; + if (object == null) { + return !length; + } var obj = Object(object); for (var i = 0; i < length; i++) { var key = keys[i]; - if (!BI.isEqual(attrs[key], obj[key]) || !(key in obj)) return false; + if (!BI.isEqual(attrs[key], obj[key]) || !(key in obj)) { + return false; + } } return true; }, @@ -13453,20 +13487,24 @@ if (!window.BI) { }, deepRemove: function (obj, target) { + var done = false; var i; if (BI.isArray(obj)) { for (i = 0; i < obj.length; i++) { if (BI.isEqual(target, obj[i])) { obj.splice(i--, 1); + done = true; } } } else { BI.each(obj, function (i, v) { if (BI.isEqual(target, obj[i])) { delete obj[i]; + done = true; } }); } + return done; }, deepWithout: function (obj, target) { @@ -13489,8 +13527,14 @@ if (!window.BI) { } }, - deepUniq: function () { - + deepUnique: function (array) { + var result = []; + BI.each(array, function (i, item) { + if (!BI.deepContains(result, item)) { + result.push(item); + } + }); + return result; }, //比较两个对象得出不一样的key值 @@ -13541,31 +13585,54 @@ if (!window.BI) { var copies = callbacks.slice(0); callbacks = []; for (var i = 0; i < copies.length; i++) { - copies[i].func.apply(null, copies[i].args); + copies[i](); } } + if (typeof Promise !== 'undefined') { + var p = Promise.resolve(); + timerFunc = function () { + p.then(nextTickHandler); + } + } else + /* istanbul ignore if */ if (typeof MutationObserver !== 'undefined') { var counter = 1; var observer = new MutationObserver(nextTickHandler); - var textNode = document.createTextNode(counter); + var textNode = document.createTextNode(counter + ""); observer.observe(textNode, { characterData: true }); timerFunc = function () { counter = (counter + 1) % 2; - textNode.data = counter; + textNode.data = counter + ""; } } else { - timerFunc = setTimeout + timerFunc = function () { + setTimeout(nextTickHandler, 0) + } } - return function (cb) { + return function queueNextTick(cb) { + var _resolve; var args = [].slice.call(arguments, 1); - callbacks.push({func: cb, args: args}); - if (pending) return; - pending = true; - timerFunc(nextTickHandler, 0); + callbacks.push(function () { + if (cb) { + cb.apply(null, args); + } + if (_resolve) { + _resolve.apply(null, args); + } + }); + if (!pending) { + pending = true; + timerFunc(); + } + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve) { + _resolve = resolve + }) + } } })() }); @@ -13599,7 +13666,7 @@ if (!window.BI) { try { return parseInt(number, radix); } catch (e) { - throw new Error("转成int类型失败"); + throw new Error(number + "parse int error"); return NaN; } }, @@ -13608,7 +13675,7 @@ if (!window.BI) { try { return parseFloat(number); } catch (e) { - throw new Error("转成float类型失败"); + throw new Error(number + "parse float error"); return NaN; } }, @@ -13670,9 +13737,9 @@ if (!window.BI) { var sum = 0; BI.each(array, function (i, item) { if (iteratee) { - sum += new Number(iteratee.apply(context, [i, item])); + sum += Number(iteratee.apply(context, [i, item])); } else { - sum += new Number(item); + sum += Number(item); } }); return sum; @@ -13735,6 +13802,10 @@ if (!window.BI) { return BI.isString(str) && BI.isEmpty(str); }, + contentFormat: function () { + return FR.contentFormat.apply(FR, arguments); + }, + /** * 对字符串进行加密 {@link #decrypt} * @static @@ -13848,23 +13919,23 @@ if (!window.BI) { //浏览器相关方法 _.extend(BI, { isIE: function () { - return $.browser.msie; + return /(msie|trident)/i.test(navigator.userAgent.toLowerCase()); }, isChrome: function () { - return $.browser.chrome; + return /chrome/i.test(navigator.userAgent.toLowerCase()); }, isFireFox: function () { - return $.browser.mozilla; + return /firefox/i.test(navigator.userAgent.toLowerCase()); }, isOpera: function () { - return $.browser.opera; + return /opera/i.test(navigator.userAgent.toLowerCase()); }, isSafari: function () { - return $.browser.safari; + return /safari/i.test(navigator.userAgent.toLowerCase()); }, isKhtml: function () { @@ -13898,6 +13969,124 @@ if (!window.BI) { //BI请求 _.extend(BI, { + ajax: (function () { + var loading, timeoutToast; + return function (option) { + option || (option = {}); + option.data = BI.extend({}, Data.SharingPool.cat("urlParameters"), option.data); + //encode + encodeBIParam(option.data); + + var async = true; + if (BI.isNotNull(option.async)) { + async = option.async; + } + + if (BI.isNull(loading)) { + loading = BI.createWidget({ + type: "bi.request_loading" + }); + } + + if (BI.isNull(timeoutToast)) { + timeoutToast = BI.createWidget({ + type: "bi.timeout_toast" + }); + timeoutToast.setCallback(function (op) { + decodeBIParam(op.data); + BI.ajax(op); + }); + } + timeoutToast.addReq(option); + + FR.ajax({ + url: option.url, + type: "POST", + data: option.data, + async: async, + error: function () { + if (!timeoutToast.hasReq(option)) { + return; + } + timeoutToast.removeReq(option); + //失败 取消、重新加载 + loading.setCallback(function () { + decodeBIParam(option.data); + BI.ajax(option); + }); + loading.showError(); + }, + complete: function (res, status) { + if (!timeoutToast.hasReq(option)) { + return; + } + timeoutToast.removeReq(option); + //登录超时 + if (BI.isNotNull(res.responseText) && + res.responseText.indexOf("fs-login-content") > -1 && + res.responseText.indexOf("fs-login-input-password-confirm") === -1) { + if (BI.Popovers.isVisible(BI.LoginTimeOut.POPOVER_ID)) { + return; + } + if (BI.isNotNull(BI.Popovers.get(BI.LoginTimeOut.POPOVER_ID))) { + BI.Popovers.open(BI.LoginTimeOut.POPOVER_ID); + return; + } + var loginTimeout = BI.createWidget({ + type: "bi.login_timeout" + }); + loginTimeout.on(BI.LoginTimeOut.EVENT_LOGIN, function () { + decodeBIParam(option.data); + BI.ajax(option); + BI.Popovers.remove(BI.LoginTimeOut.POPOVER_ID); + }); + BI.Popovers.create(BI.LoginTimeOut.POPOVER_ID, loginTimeout, { + width: 600, + height: 400 + }).open(BI.LoginTimeOut.POPOVER_ID); + } else if (BI.isNotNull(res.responseText) && + res.responseText.indexOf("script") > -1 && + res.responseText.indexOf("Session Timeout...") > -1) { + //登录失效 + loading.setCallback(function () { + location.reload(); + }); + loading.showError(); + + } else if (status === "success" && BI.isFunction(option.success)) { + option.success(FR.jsonDecode(res.responseText)); + } + if (BI.isFunction(option.complete)) { + option.complete(FR.jsonDecode(res.responseText), status); + } + } + }); + + return function cancel() { + timeoutToast.removeReq(option); + }; + + function encodeBIParam(data) { + for (var key in data) { + if (_.isObject(data[key])) { + data[key] = window.encodeURIComponent(FR.jsonEncode(data[key])); + } else { + data[key] = window.encodeURIComponent(data[key]); + } + } + } + + function decodeBIParam(data) { + for (var key in data) { + data[key] = window.decodeURIComponent(data[key]); + if (_.isObject(data[key])) { + data[key] = FR.jsonDecode(data[key]); + } + } + } + } + })(), + /** * 异步ajax请求 * @param {String} op op参数 @@ -13907,38 +14096,29 @@ if (!window.BI) { * @param {Function} complete 回调 */ requestAsync: function (op, cmd, data, callback, complete) { - // if (BI.isNull(BI.REQUEST_LOADING)) { - // BI.REQUEST_LOADING = BI.createWidget({ - // type: "bi.request_loading" - // }); - // } data = data || {}; if (!BI.isKey(op)) { op = 'fr_bi_dezi'; } - if (op === "fr_bi_dezi") { + if (op === "fr_bi_dezi" || op === "fr_bi_configure") { data.sessionID = Data.SharingPool.get("sessionID"); } var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); - (BI.ajax || FR.ajax)({ + return (BI.ajax)({ url: url, type: 'POST', data: data, error: function () { // BI.Msg.toast(BI.i18nText("BI-Ajax_Error")); - //失败 取消、重新加载 - // BI.REQUEST_LOADING.setCallback(function () { - // BI.requestAsync(op, cmd, data, callback, complete); - // }); - // BI.REQUEST_LOADING.showError(); }, - complete: function (res, status) { - if (BI.isFunction(callback) && status === 'success') { - callback(BI.jsonDecode(res.responseText)); - BI.Maskers.hide(BI.RequstLoading.MASK_ID); + success: function (res) { + if (BI.isFunction(callback)) { + callback(res); } + }, + complete: function (res, status) { if (BI.isFunction(complete)) { - complete(); + complete(res); } } }); @@ -13961,7 +14141,7 @@ if (!window.BI) { } var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); var result = {}; - (BI.ajax || FR.ajax)({ + (BI.ajax)({ url: url, type: 'POST', async: false, @@ -13971,7 +14151,7 @@ if (!window.BI) { }, complete: function (res, status) { if (status === 'success') { - result = BI.jsonDecode(res.responseText); + result = res; } } }); diff --git a/src/core/base.js b/src/core/base.js index 0ea04ee91..aa33e64a3 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -33,7 +33,7 @@ if (!window.BI) { //Utility _.extend(BI, { i18nText: function (key) { - var localeText = FR.i18n[key]; + var localeText = ""; if (!localeText) { localeText = key; } @@ -485,7 +485,11 @@ if (!window.BI) { }, isWidthOrHeight: function (w) { - return FR.isWidthOrHeight(w); + if (typeof w == 'number') { + return w >= 0; + } else if (typeof w == 'string') { + return /^\d{1,3}%$/.exec(w) || w == 'auto' || /^\d+px$/.exec(w); + } }, isNotNull: function (obj) { diff --git a/src/css/base/pager/pager.all.css b/src/css/base/pager/pager.all.css deleted file mode 100644 index 278e4a9b7..000000000 --- a/src/css/base/pager/pager.all.css +++ /dev/null @@ -1,14 +0,0 @@ -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.bi-all-pager .pager-editor { - background-color: #ffffff; -} -.bi-all-pager .all-pager-prev { - font-size: 16px; - background: #f4f4f4; -} -.bi-all-pager .all-pager-next { - font-size: 16px; - background: #f4f4f4; -} diff --git a/src/css/base/pager/pager.number.css b/src/css/base/pager/pager.number.css deleted file mode 100644 index 637e904e2..000000000 --- a/src/css/base/pager/pager.number.css +++ /dev/null @@ -1,11 +0,0 @@ -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.bi-number-pager .number-pager-prev { - font-size: 16px; - background: #f4f4f4; -} -.bi-number-pager .number-pager-next { - font-size: 16px; - background: #f4f4f4; -} diff --git a/src/css/base/pager/pager.skip.css b/src/css/base/pager/pager.skip.css deleted file mode 100644 index 26b5a82ab..000000000 --- a/src/css/base/pager/pager.skip.css +++ /dev/null @@ -1,11 +0,0 @@ -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.bi-skip-pager .skip-pager-prev { - font-size: 16px; - background: #f4f4f4; -} -.bi-skip-pager .skip-pager-next { - font-size: 16px; - background: #f4f4f4; -} diff --git a/src/css/base/third/jquery.mCustomScrollbar.css b/src/css/base/third/jquery.mCustomScrollbar.css deleted file mode 100644 index b42acb6ec..000000000 --- a/src/css/base/third/jquery.mCustomScrollbar.css +++ /dev/null @@ -1,1481 +0,0 @@ -/* -== malihu jquery custom scrollbar plugin == -Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller -*/ -/* -CONTENTS: - 1. BASIC STYLE - Plugin's basic/essential CSS properties (normally, should not be edited). - 2. VERTICAL SCROLLBAR - Positioning and dimensions of vertical scrollbar. - 3. HORIZONTAL SCROLLBAR - Positioning and dimensions of horizontal scrollbar. - 4. VERTICAL AND HORIZONTAL SCROLLBARS - Positioning and dimensions of 2-axis scrollbars. - 5. TRANSITIONS - CSS3 transitions for hover events, auto-expanded and auto-hidden scrollbars. - 6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS - 6.1 THEMES - Scrollbar colors, opacity, dimensions, backgrounds etc. via ready-to-use themes. -*/ -/* ------------------------------------------------------------------------------------------------------------------------- -1. BASIC STYLE ------------------------------------------------------------------------------------------------------------------------- -*/ -/****添加计算宽度的--运算符直接需要space****/ -/****** common color(常用颜色,可用于普遍场景) *****/ -/**** custom color(自定义颜色,用于特定场景) ****/ -.mCustomScrollbar { - -ms-touch-action: pinch-zoom; - touch-action: pinch-zoom; - /* direct pointer events to js */ -} -.mCustomScrollbar.mCS_no_scrollbar, -.mCustomScrollbar.mCS_touch_action { - -ms-touch-action: auto; - touch-action: auto; -} -.mCustomScrollBox { - /* contains plugin's markup */ - position: relative; - overflow: hidden; - height: 100%; - max-width: 100%; - outline: none; - direction: ltr; -} -.mCSB_container { - /* contains the original content */ - overflow: hidden; - width: auto; - height: auto; -} -/* ------------------------------------------------------------------------------------------------------------------------- -2. VERTICAL SCROLLBAR -y-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_inside > .mCSB_container { - margin-right: 30px; -} -.mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; -} -/* non-visible scrollbar */ -.mCS-dir-rtl > .mCSB_inside > .mCSB_container { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} -.mCS-dir-rtl > .mCSB_inside > .mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden { - margin-left: 0; -} -/* RTL direction/left-side scrollbar */ -.mCSB_scrollTools { - /* contains scrollbar markup (draggable element, dragger rail, buttons etc.) */ - position: absolute; - width: 16px; - height: auto; - left: auto; - top: 0; - right: 0; - bottom: 0; -} -.mCSB_outside + .mCSB_scrollTools { - right: -26px; -} -/* scrollbar position: outside */ -.mCS-dir-rtl > .mCSB_inside > .mCSB_scrollTools, -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - /* RTL direction/left-side scrollbar */ - right: auto; - left: 0; -} -.mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools { - left: -26px; -} -/* RTL direction/left-side scrollbar (scrollbar position: outside) */ -.mCSB_scrollTools .mCSB_draggerContainer { - /* contains the draggable element and dragger rail markup */ - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - height: auto; -} -.mCSB_scrollTools a + .mCSB_draggerContainer { - margin: 20px 0; -} -.mCSB_scrollTools .mCSB_draggerRail { - width: 2px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} -.mCSB_scrollTools .mCSB_dragger { - /* the draggable element */ - cursor: pointer; - width: 100%; - height: 30px; - /* minimum dragger height */ - z-index: 1; -} -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - /* the dragger element */ - position: relative; - width: 4px; - height: 100%; - margin: 0 auto; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; - text-align: center; -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 12px; - /* auto-expanded scrollbar */ -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 8px; - /* auto-expanded scrollbar */ -} -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown { - display: block; - position: absolute; - height: 20px; - width: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} -.mCSB_scrollTools .mCSB_buttonDown { - bottom: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -3. HORIZONTAL SCROLLBAR -x-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_horizontal.mCSB_inside > .mCSB_container { - margin-right: 0; - margin-bottom: 30px; -} -.mCSB_horizontal.mCSB_outside > .mCSB_container { - min-height: 100%; -} -.mCSB_horizontal > .mCSB_container.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} -/* non-visible scrollbar */ -.mCSB_scrollTools.mCSB_scrollTools_horizontal { - width: auto; - height: 16px; - top: auto; - right: 0; - bottom: 0; - left: 0; -} -.mCustomScrollBox + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: -26px; -} -/* scrollbar position: outside */ -.mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 20px; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 2px; - margin: 7px 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 30px; - /* minimum dragger width */ - height: 100%; - left: 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 12px; - /* auto-expanded scrollbar */ - margin: 2px auto; -} -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 8px; - /* auto-expanded scrollbar */ - margin: 4px 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft, -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - display: block; - position: absolute; - width: 20px; - height: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft { - left: 0; -} -.mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight { - right: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -4. VERTICAL AND HORIZONTAL SCROLLBARS -yx-axis ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_container_wrapper { - position: absolute; - height: auto; - width: auto; - overflow: hidden; - top: 0; - left: 0; - right: 0; - bottom: 0; - margin-right: 30px; - margin-bottom: 30px; -} -.mCSB_container_wrapper > .mCSB_container { - padding-right: 30px; - padding-bottom: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 20px; -} -.mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 20px; -} -/* non-visible horizontal scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden + .mCSB_scrollTools.mCSB_scrollTools_vertical { - bottom: 0; -} -/* non-visible vertical scrollbar/RTL direction/left-side scrollbar */ -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - right: 0; -} -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 20px; -} -/* non-visible scrollbar/RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal { - left: 0; -} -.mCS-dir-rtl > .mCSB_inside > .mCSB_container_wrapper { - /* RTL direction/left-side scrollbar */ - margin-right: 0; - margin-left: 30px; -} -.mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden > .mCSB_container { - padding-right: 0; -} -.mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden > .mCSB_container { - padding-bottom: 0; -} -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden { - margin-right: 0; - /* non-visible scrollbar */ - margin-left: 0; -} -/* non-visible horizontal scrollbar */ -.mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden { - margin-bottom: 0; -} -/* ------------------------------------------------------------------------------------------------------------------------- -5. TRANSITIONS ------------------------------------------------------------------------------------------------------------------------- -*/ -.mCSB_scrollTools, -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - -webkit-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; -} -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, -.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, -.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail { - -webkit-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -moz-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - -o-transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; - transition: width 0.2s ease-out 0.2s, height 0.2s ease-out 0.2s, margin-left 0.2s ease-out 0.2s, margin-right 0.2s ease-out 0.2s, margin-top 0.2s ease-out 0.2s, margin-bottom 0.2s ease-out 0.2s, opacity 0.2s ease-in-out, background-color 0.2s ease-in-out; -} -/* ------------------------------------------------------------------------------------------------------------------------- -6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS ------------------------------------------------------------------------------------------------------------------------- -*/ -/* ----------------------------------------- -6.1 THEMES ----------------------------------------- -*/ -/* default theme ("light") */ -.mCSB_scrollTools { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 0; - filter: "alpha(opacity=0)"; - -ms-filter: "alpha(opacity=0)"; -} -.mCustomScrollbar > .mCustomScrollBox > .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollbar > .mCustomScrollBox ~ .mCSB_scrollTools.mCSB_scrollTools_onDrag, -.mCustomScrollBox:hover > .mCSB_scrollTools, -.mCustomScrollBox:hover ~ .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox > .mCSB_scrollTools, -.mCS-autoHide:hover > .mCustomScrollBox ~ .mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=100)"; - -ms-filter: "alpha(opacity=100)"; -} -.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.4); - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); - filter: "alpha(opacity=85)"; - -ms-filter: "alpha(opacity=85)"; -} -.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} -.mCSB_scrollTools .mCSB_buttonUp, -.mCSB_scrollTools .mCSB_buttonDown, -.mCSB_scrollTools .mCSB_buttonLeft, -.mCSB_scrollTools .mCSB_buttonRight { - background-image: url('background/mCSB_buttons.png'); - /* css sprites */ - background-repeat: no-repeat; - opacity: 0.4; - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; -} -.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 0; - /* - sprites locations - light: 0 0, -16px 0, -32px 0, -48px 0, 0 -72px, -16px -72px, -32px -72px - dark: -80px 0, -96px 0, -112px 0, -128px 0, -80px -72px, -96px -72px, -112px -72px - */ -} -.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -20px; - /* - sprites locations - light: 0 -20px, -16px -20px, -32px -20px, -48px -20px, 0 -92px, -16px -92px, -32px -92px - dark: -80px -20px, -96px -20px, -112px -20px, -128px -20px, -80px -92px, -96px -92px, -112 -92px - */ -} -.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -40px; - /* - sprites locations - light: 0 -40px, -20px -40px, -40px -40px, -60px -40px, 0 -112px, -20px -112px, -40px -112px - dark: -80px -40px, -100px -40px, -120px -40px, -140px -40px, -80px -112px, -100px -112px, -120px -112px - */ -} -.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -56px; - /* - sprites locations - light: 0 -56px, -20px -56px, -40px -56px, -60px -56px, 0 -128px, -20px -128px, -40px -128px - dark: -80px -56px, -100px -56px, -120px -56px, -140px -56px, -80px -128px, -100px -128px, -120px -128px - */ -} -.mCSB_scrollTools .mCSB_buttonUp:hover, -.mCSB_scrollTools .mCSB_buttonDown:hover, -.mCSB_scrollTools .mCSB_buttonLeft:hover, -.mCSB_scrollTools .mCSB_buttonRight:hover { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; -} -.mCSB_scrollTools .mCSB_buttonUp:active, -.mCSB_scrollTools .mCSB_buttonDown:active, -.mCSB_scrollTools .mCSB_buttonLeft:active, -.mCSB_scrollTools .mCSB_buttonRight:active { - opacity: 0.9; - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; -} -/* theme: "dark" */ -.mCS-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} -.mCS-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-2", "dark-2" */ -.mCS-light-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-light-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-light-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px 0; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -20px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -40px; -} -.mCS-light-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -56px; -} -/* theme: "dark-2" */ -.mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px 0; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -20px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -40px; -} -.mCS-dark-2.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-thick", "dark-thick" */ -.mCS-light-thick.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - width: 4px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 4px; - margin: 6px 0; -} -.mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 6px; - margin: 5px auto; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-light-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px 0; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -20px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -40px; -} -.mCS-light-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -56px; -} -/* theme: "dark-thick" */ -.mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px 0; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -20px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -40px; -} -.mCS-dark-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -56px; -} -/* ---------------------------------------- */ -/* theme: "light-thin", "dark-thin" */ -.mCS-light-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.1); -} -.mCS-light-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 2px; -} -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; -} -.mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 2px; - margin: 7px auto; -} -/* theme "dark-thin" */ -.mCS-dark-thin.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px 0; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -20px; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -40px; -} -.mCS-dark-thin.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -56px; -} -/* ---------------------------------------- */ -/* theme "rounded", "rounded-dark", "rounded-dots", "rounded-dots-dark" */ -.mCS-rounded.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.15); -} -.mCS-rounded.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger { - height: 14px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 1px; -} -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 14px; -} -.mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 14px; - margin: 1px 0; -} -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - width: 16px; - /* auto-expanded scrollbar */ - height: 16px; - margin: -1px 0; -} -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 4px; - /* auto-expanded scrollbar */ -} -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar { - height: 16px; - /* auto-expanded scrollbar */ - width: 16px; - margin: 0 -1px; -} -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 4px; - /* auto-expanded scrollbar */ - margin: 6px 0; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 -72px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -92px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -112px; -} -.mCS-rounded.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -128px; -} -/* theme "rounded-dark", "rounded-dots-dark" */ -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.15); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -80px -72px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -80px -92px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -80px -112px; -} -.mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -80px -128px; -} -/* theme "rounded-dots", "rounded-dots-dark" */ -.mCS-rounded-dots.mCSB_scrollTools_vertical .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_vertical .mCSB_draggerRail { - width: 4px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - background-color: transparent; - background-position: center; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAANElEQVQYV2NkIAAYiVbw//9/Y6DiM1ANJoyMjGdBbLgJQAX/kU0DKgDLkaQAvxW4HEvQFwCRcxIJK1XznAAAAABJRU5ErkJggg=="); - background-repeat: repeat-y; - opacity: 0.3; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - height: 4px; - margin: 6px 0; - background-repeat: repeat-x; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonUp { - background-position: -16px -72px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonDown { - background-position: -16px -92px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -20px -112px; -} -.mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonRight { - background-position: -20px -128px; -} -/* theme "rounded-dots-dark" */ -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALElEQVQYV2NkIAAYSVFgDFR8BqrBBEifBbGRTfiPZhpYjiQFBK3A6l6CvgAAE9kGCd1mvgEAAAAASUVORK5CYII="); -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -96px -72px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -96px -92px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -100px -112px; -} -.mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -100px -128px; -} -/* ---------------------------------------- */ -/* theme "3d", "3d-dark", "3d-thick", "3d-thick-dark" */ -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-y; - background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to right, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - background-repeat: repeat-x; - background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.5)), color-stop(100%, rgba(255, 255, 255, 0))); - background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: -ms-linear-gradient(top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); - background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%); -} -/* theme "3d", "3d-dark" */ -.mCS-3d.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 70px; -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 70px; -} -.mCS-3d.mCSB_scrollTools, -.mCS-3d-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; -} -.mCS-3d.mCSB_scrollTools .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 8px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.5), inset -1px 0 1px rgba(255, 255, 255, 0.2); -} -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} -.mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 8px; -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 8px; - margin: 4px 0; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5), inset 0 -1px 1px rgba(255, 255, 255, 0.2); -} -.mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 8px; - margin: 4px auto; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-3d.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "3d-dark" */ -.mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1); -} -.mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-3d-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme: "3d-thick", "3d-thick-dark" */ -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools { - opacity: 1; - filter: "alpha(opacity=30)"; - -ms-filter: "alpha(opacity=30)"; -} -.mCS-3d-thick.mCSB_scrollTools, -.mCS-3d-thick-dark.mCSB_scrollTools, -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.mCSB_inside + .mCS-3d-thick.mCSB_scrollTools_vertical, -.mCSB_inside + .mCS-3d-thick-dark.mCSB_scrollTools_vertical { - right: 1px; -} -.mCS-3d-thick.mCSB_scrollTools_vertical, -.mCS-3d-thick-dark.mCSB_scrollTools_vertical { - box-shadow: inset 1px 0 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} -.mCS-3d-thick.mCSB_scrollTools_horizontal, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - bottom: 1px; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.5); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4); - width: 12px; - margin: 2px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #555; -} -.mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 12px; - width: auto; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #000; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-3d-thick.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme: "3d-thick-dark" */ -.mCS-3d-thick-dark.mCSB_scrollTools { - box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1), inset 0 0 14px rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.4), inset -1px 0 0 rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), inset 0 -1px 0 rgba(0, 0, 0, 0.2); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #777; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer { - background-color: #fff; - background-color: rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 1px 16px rgba(0, 0, 0, 0.1); -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme: "minimal", "minimal-dark" */ -.mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - right: 0; - margin: 12px 0; -} -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools.mCSB_scrollTools_horizontal, -.mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal { - bottom: 0; - margin: 0 12px; -} -/* RTL direction/left-side scrollbar */ -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, -.mCS-dir-rtl > .mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical { - left: 0; - right: auto; -} -.mCS-minimal.mCSB_scrollTools .mCSB_draggerRail, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; -} -.mCS-minimal.mCSB_scrollTools_vertical .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_vertical .mCSB_dragger { - height: 50px; -} -.mCS-minimal.mCSB_scrollTools_horizontal .mCSB_dragger, -.mCS-minimal-dark.mCSB_scrollTools_horizontal .mCSB_dragger { - width: 50px; -} -.mCS-minimal.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} -.mCS-minimal.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} -/* theme: "minimal-dark" */ -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); - filter: "alpha(opacity=20)"; - -ms-filter: "alpha(opacity=20)"; -} -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.5); - filter: "alpha(opacity=50)"; - -ms-filter: "alpha(opacity=50)"; -} -/* ---------------------------------------- */ -/* theme "light-3", "dark-3" */ -.mCS-light-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - width: 6px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} -.mCS-light-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; -} -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-light-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 6px; - margin: 5px 0; -} -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 12px; -} -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 12px; - margin: 2px 0; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-light-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "dark-3" */ -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-dark-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-dark-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* ---------------------------------------- */ -/* theme "inset", "inset-dark", "inset-2", "inset-2-dark", "inset-3", "inset-3-dark" */ -.mCS-inset.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - width: 12px; - background-color: #000; - background-color: rgba(0, 0, 0, 0.2); -} -.mCS-inset.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 6px; - margin: 3px 5px; - position: absolute; - height: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - height: 6px; - margin: 5px 3px; - position: absolute; - width: auto; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mCS-inset.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 12px; - margin: 2px 0; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonUp { - background-position: -32px -72px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonDown { - background-position: -32px -92px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -40px -112px; -} -.mCS-inset.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3.mCSB_scrollTools .mCSB_buttonRight { - background-position: -40px -128px; -} -/* theme "inset-dark", "inset-2-dark", "inset-3-dark" */ -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.1); -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonUp, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonUp { - background-position: -112px -72px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonDown, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonDown { - background-position: -112px -92px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -120px -112px; -} -.mCS-inset-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonRight, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonRight { - background-position: -120px -128px; -} -/* theme "inset-2", "inset-2-dark" */ -.mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: transparent; - border-width: 1px; - border-style: solid; - border-color: #fff; - border-color: rgba(255, 255, 255, 0.2); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail { - border-color: #000; - border-color: rgba(0, 0, 0, 0.2); -} -/* theme "inset-3", "inset-3-dark" */ -.mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.6); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail { - background-color: #000; - background-color: rgba(0, 0, 0, 0.6); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.75); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.85); -} -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #000; - background-color: rgba(0, 0, 0, 0.9); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.75); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.85); -} -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, -.mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background-color: #fff; - background-color: rgba(255, 255, 255, 0.9); -} -/* ---------------------------------------- */ -/* theme "bi-default" */ -.mCS-bi-default { - background-color: #dddddd; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_horizontal { - height: 18px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_vertical { - width: 18px; -} -.mCS-bi-default .mCSB_scrollTools .mCSB_draggerRail { - border-radius: 0px; -} -.mCS-bi-default .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - border-radius: 2px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer { - margin: 0 18px; -} -.mCS-bi-default .mCSB_scrollTools.mCSB_scrollTools_vertical a + .mCSB_draggerContainer { - margin: 18px 0; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 14px; - margin: 0 2px; -} -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 14px; - margin: 2px auto; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - width: 18px; - height: 100%; - margin: 0; -} -.mCS-bi-default.mCSB_scrollTools_horizontal .mCSB_draggerRail { - width: 100%; - height: 18px; - margin: 0; -} -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - width: 14px; -} -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, -.mCS-bi-default.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail { - height: 14px; - margin: 2px 0; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background-color: #f4f4f4; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_draggerRail { - background-color: #dddddd; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft, -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - width: 16px; - height: 16px; - background-color: #f4f4f4; - border: 1px solid #eaeaea; - opacity: 1; - filter: alpha(opacity=100); -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonUp { - background-position: -128px -1px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonDown { - background-position: -128px -21px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonLeft { - background-position: -142px -40px; -} -.mCS-bi-default.mCSB_scrollTools .mCSB_buttonRight { - background-position: -141px -56px; -} -/* ---------------------------------------- */ From 47ab82194994dc3e4087e675e84ab338db006dbe Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 15:19:47 +0800 Subject: [PATCH 09/19] update --- dist/icon/bubble_no_projector.png | Bin 0 -> 3106 bytes dist/icon/bubble_projector.png | Bin 0 -> 3290 bytes dist/icon/business_package.png | Bin 0 -> 559 bytes dist/icon/business_package_add.png | Bin 0 -> 525 bytes dist/icon/business_package_add_disable.png | Bin 0 -> 502 bytes dist/icon/chartsetting/address_marker_big.png | Bin 0 -> 3465 bytes .../icon/chartsetting/address_marker_small.png | Bin 0 -> 3224 bytes dist/icon/chartsetting/icon_bubble_3d.png | Bin 0 -> 694 bytes dist/icon/chartsetting/icon_bubble_normal.png | Bin 0 -> 400 bytes dist/icon/chartsetting/icon_dashboard_1.png | Bin 0 -> 868 bytes dist/icon/chartsetting/icon_dashboard_2.png | Bin 0 -> 769 bytes dist/icon/chartsetting/icon_dashboard_3.png | Bin 0 -> 971 bytes dist/icon/chartsetting/icon_dashboard_4.png | Bin 0 -> 3298 bytes dist/icon/chartsetting/icon_dashboard_5.png | Bin 0 -> 3362 bytes dist/icon/chartsetting/icon_dashboard_6.png | Bin 0 -> 386 bytes dist/icon/chartsetting/icon_dashboard_7.png | Bin 0 -> 329 bytes .../chartsetting/icon_gradual_highlight.png | Bin 0 -> 556 bytes .../icon_multi_pie_gradient_darker.png | Bin 0 -> 514 bytes .../icon_multi_pie_gradient_lighter.png | Bin 0 -> 523 bytes dist/icon/chartsetting/icon_style_3d.png | Bin 0 -> 256 bytes .../icon_style_acc_radar_circle.png | Bin 0 -> 1057 bytes .../icon_style_acc_radar_polygon.png | Bin 0 -> 1124 bytes .../chartsetting/icon_style_area_broken.png | Bin 0 -> 369 bytes .../chartsetting/icon_style_area_curve.png | Bin 0 -> 391 bytes .../chartsetting/icon_style_area_vertical.png | Bin 0 -> 210 bytes dist/icon/chartsetting/icon_style_gradual.png | Bin 0 -> 290 bytes .../chartsetting/icon_style_line_broken.png | Bin 0 -> 356 bytes .../chartsetting/icon_style_line_curve.png | Bin 0 -> 366 bytes .../chartsetting/icon_style_line_vertical.png | Bin 0 -> 208 bytes dist/icon/chartsetting/icon_style_normal.png | Bin 0 -> 179 bytes .../icon_style_pie_equal_arc_rose.png | Bin 0 -> 347 bytes .../chartsetting/icon_style_pie_normal.png | Bin 0 -> 432 bytes .../icon_style_pie_not_equal_arc_rose.png | Bin 0 -> 413 bytes .../chartsetting/icon_style_radar_circle.png | Bin 0 -> 793 bytes .../chartsetting/icon_style_radar_polygon.png | Bin 0 -> 826 bytes .../chartsetting/icon_style_transparent.png | Bin 0 -> 195 bytes dist/icon/check-box-active.png | Bin 0 -> 302 bytes dist/icon/check-box-disable2.png | Bin 0 -> 303 bytes dist/icon/dots.png | Bin 0 -> 2834 bytes dist/icon/drag/icon_area.png | Bin 0 -> 666 bytes dist/icon/drag/icon_area_a.png | Bin 0 -> 594 bytes dist/icon/drag/icon_area_c.png | Bin 0 -> 459 bytes dist/icon/drag/icon_area_pa.png | Bin 0 -> 475 bytes dist/icon/drag/icon_area_r.png | Bin 0 -> 569 bytes dist/icon/drag/icon_axis.png | Bin 0 -> 218 bytes dist/icon/drag/icon_axis_a.png | Bin 0 -> 205 bytes dist/icon/drag/icon_axis_c.png | Bin 0 -> 224 bytes dist/icon/drag/icon_axis_f.png | Bin 0 -> 196 bytes dist/icon/drag/icon_axis_pa.png | Bin 0 -> 202 bytes dist/icon/drag/icon_bar.png | Bin 0 -> 222 bytes dist/icon/drag/icon_bar_a.png | Bin 0 -> 199 bytes dist/icon/drag/icon_bar_c.png | Bin 0 -> 191 bytes dist/icon/drag/icon_bubble.png | Bin 0 -> 372 bytes dist/icon/drag/icon_bubble_f.png | Bin 0 -> 352 bytes dist/icon/drag/icon_combine.png | Bin 0 -> 424 bytes dist/icon/drag/icon_combine_m.png | Bin 0 -> 431 bytes dist/icon/drag/icon_complex.png | Bin 0 -> 208 bytes dist/icon/drag/icon_cross.png | Bin 0 -> 214 bytes dist/icon/drag/icon_dashboard.png | Bin 0 -> 865 bytes dist/icon/drag/icon_donut.png | Bin 0 -> 510 bytes dist/icon/drag/icon_funnel.png | Bin 0 -> 284 bytes dist/icon/drag/icon_group.png | Bin 0 -> 221 bytes dist/icon/drag/icon_line.png | Bin 0 -> 504 bytes dist/icon/drag/icon_map_c.png | Bin 0 -> 403 bytes dist/icon/drag/icon_map_g.png | Bin 0 -> 452 bytes dist/icon/drag/icon_map_gis.png | Bin 0 -> 438 bytes dist/icon/drag/icon_map_s.png | Bin 0 -> 311 bytes dist/icon/drag/icon_multi_pie.png | Bin 0 -> 625 bytes dist/icon/drag/icon_multi_pie_lighter.png | Bin 0 -> 523 bytes dist/icon/drag/icon_multi_pie_thicker.png | Bin 0 -> 514 bytes dist/icon/drag/icon_pie.png | Bin 0 -> 432 bytes dist/icon/drag/icon_radar.png | Bin 0 -> 826 bytes dist/icon/drag/icon_radar_a.png | Bin 0 -> 1124 bytes dist/icon/drag/icon_rect_tree.png | Bin 0 -> 242 bytes dist/icon/drag/icon_scatter.png | Bin 0 -> 176 bytes dist/icon/drag/pure/icon_date.png | Bin 0 -> 2876 bytes dist/icon/drag/pure/icon_date_range.png | Bin 0 -> 195 bytes dist/icon/drag/pure/icon_detail.png | Bin 0 -> 160 bytes dist/icon/drag/pure/icon_image.png | Bin 0 -> 409 bytes dist/icon/drag/pure/icon_input.png | Bin 0 -> 191 bytes dist/icon/drag/pure/icon_interval_slider.png | Bin 0 -> 236 bytes dist/icon/drag/pure/icon_list_label.png | Bin 0 -> 169 bytes dist/icon/drag/pure/icon_more.png | Bin 0 -> 238 bytes dist/icon/drag/pure/icon_number.png | Bin 0 -> 205 bytes dist/icon/drag/pure/icon_query.png | Bin 0 -> 247 bytes dist/icon/drag/pure/icon_query_g.png | Bin 0 -> 223 bytes dist/icon/drag/pure/icon_reset.png | Bin 0 -> 256 bytes dist/icon/drag/pure/icon_reuse.png | Bin 0 -> 171 bytes dist/icon/drag/pure/icon_single_slider.png | Bin 0 -> 229 bytes dist/icon/drag/pure/icon_string.png | Bin 0 -> 198 bytes dist/icon/drag/pure/icon_string_list.png | Bin 0 -> 183 bytes dist/icon/drag/pure/icon_tree.png | Bin 0 -> 278 bytes dist/icon/drag/pure/icon_tree_label.png | Bin 0 -> 176 bytes dist/icon/drag/pure/icon_tree_list.png | Bin 0 -> 181 bytes dist/icon/drag/pure/icon_web.png | Bin 0 -> 210 bytes dist/icon/drag/pure/icon_year.png | Bin 0 -> 223 bytes dist/icon/drag/pure/icon_year_m.png | Bin 0 -> 235 bytes dist/icon/drag/pure/icon_year_m_d.png | Bin 0 -> 234 bytes dist/icon/drag/pure/icon_year_s.png | Bin 0 -> 232 bytes dist/icon/drag/small/icin_select_tab.png | Bin 0 -> 263 bytes dist/icon/drag/small/icon_area.png | Bin 0 -> 3353 bytes dist/icon/drag/small/icon_area_a.png | Bin 0 -> 3240 bytes dist/icon/drag/small/icon_area_c.png | Bin 0 -> 3294 bytes dist/icon/drag/small/icon_area_pa.png | Bin 0 -> 3242 bytes dist/icon/drag/small/icon_area_r.png | Bin 0 -> 3242 bytes dist/icon/drag/small/icon_axis.png | Bin 0 -> 3203 bytes dist/icon/drag/small/icon_axis_a.png | Bin 0 -> 3184 bytes dist/icon/drag/small/icon_axis_c.png | Bin 0 -> 3307 bytes dist/icon/drag/small/icon_axis_f.png | Bin 0 -> 3117 bytes dist/icon/drag/small/icon_axis_pa.png | Bin 0 -> 3184 bytes dist/icon/drag/small/icon_bar.png | Bin 0 -> 3196 bytes dist/icon/drag/small/icon_bar_a.png | Bin 0 -> 3168 bytes dist/icon/drag/small/icon_bar_c.png | Bin 0 -> 3036 bytes dist/icon/drag/small/icon_bubble.png | Bin 0 -> 3191 bytes dist/icon/drag/small/icon_bubble_f.png | Bin 0 -> 3257 bytes dist/icon/drag/small/icon_combine.png | Bin 0 -> 3339 bytes dist/icon/drag/small/icon_combine_m.png | Bin 0 -> 3341 bytes dist/icon/drag/small/icon_complex.png | Bin 0 -> 2999 bytes dist/icon/drag/small/icon_cross.png | Bin 0 -> 3032 bytes dist/icon/drag/small/icon_dashboard.png | Bin 0 -> 3546 bytes dist/icon/drag/small/icon_detail.png | Bin 0 -> 2977 bytes dist/icon/drag/small/icon_donut.png | Bin 0 -> 3269 bytes dist/icon/drag/small/icon_funnel.png | Bin 0 -> 274 bytes .../drag/small/icon_funnel_not_continue.png | Bin 0 -> 271 bytes dist/icon/drag/small/icon_gis.png | Bin 0 -> 3033 bytes dist/icon/drag/small/icon_group.png | Bin 0 -> 2994 bytes dist/icon/drag/small/icon_image.png | Bin 0 -> 3172 bytes dist/icon/drag/small/icon_input.png | Bin 0 -> 2982 bytes dist/icon/drag/small/icon_interval_slider.png | Bin 0 -> 301 bytes dist/icon/drag/small/icon_line.png | Bin 0 -> 3367 bytes dist/icon/drag/small/icon_map_c.png | Bin 0 -> 3043 bytes dist/icon/drag/small/icon_map_g.png | Bin 0 -> 3083 bytes dist/icon/drag/small/icon_map_s.png | Bin 0 -> 2978 bytes dist/icon/drag/small/icon_multi_pie.png | Bin 0 -> 474 bytes dist/icon/drag/small/icon_multi_select.png | Bin 0 -> 267 bytes dist/icon/drag/small/icon_multi_tree.png | Bin 0 -> 262 bytes dist/icon/drag/small/icon_number_interval.png | Bin 0 -> 306 bytes dist/icon/drag/small/icon_pie.png | Bin 0 -> 3217 bytes dist/icon/drag/small/icon_radar.png | Bin 0 -> 3486 bytes dist/icon/drag/small/icon_radar_a.png | Bin 0 -> 3555 bytes dist/icon/drag/small/icon_rect_tree.png | Bin 0 -> 218 bytes dist/icon/drag/small/icon_scatter.png | Bin 0 -> 2901 bytes dist/icon/drag/small/icon_single_slider.png | Bin 0 -> 295 bytes dist/icon/drag/small/icon_string_label.png | Bin 0 -> 208 bytes dist/icon/drag/small/icon_string_list.png | Bin 0 -> 212 bytes dist/icon/drag/small/icon_tree_label.png | Bin 0 -> 257 bytes dist/icon/drag/small/icon_tree_list.png | Bin 0 -> 219 bytes dist/icon/drag/small/icon_web.png | Bin 0 -> 3058 bytes dist/icon/drag_helper.png | Bin 0 -> 3585 bytes dist/icon/example.png | Bin 0 -> 190645 bytes dist/icon/half_selected.png | Bin 0 -> 2881 bytes dist/icon/icon_down_arrow.png | Bin 0 -> 203 bytes dist/icon/inner-join.png | Bin 0 -> 255 bytes dist/icon/left-join.png | Bin 0 -> 250 bytes dist/icon/loading.gif | Bin 381 -> 1810 bytes dist/icon/loading_bar.gif | Bin 0 -> 5886 bytes dist/icon/no_auth.png | Bin 0 -> 1864 bytes dist/icon/no_data.png | Bin 0 -> 4286 bytes dist/icon/outer-join.png | Bin 0 -> 256 bytes dist/icon/package_selected.png | Bin 0 -> 367 bytes dist/icon/push_down.png | Bin 0 -> 200 bytes dist/icon/push_up.png | Bin 0 -> 199 bytes dist/icon/radio-active.png | Bin 0 -> 296 bytes dist/icon/radio-disable.png | Bin 0 -> 361 bytes dist/icon/radio-disable2.png | Bin 0 -> 319 bytes dist/icon/radio-normal.png | Bin 0 -> 357 bytes dist/icon/real_time.png | Bin 0 -> 4802 bytes dist/icon/report.png | Bin 0 -> 676 bytes dist/icon/right-join.png | Bin 0 -> 251 bytes dist/icon/slider-active.png | Bin 0 -> 416 bytes dist/icon/slider-normal.png | Bin 0 -> 425 bytes dist/icon/table_style_1.png | Bin 0 -> 211 bytes dist/icon/table_style_2.png | Bin 0 -> 211 bytes dist/icon/table_style_3.png | Bin 0 -> 260 bytes dist/icon/test_fail.png | Bin 0 -> 3724 bytes dist/icon/test_success.png | Bin 0 -> 1201 bytes dist/icon/union.png | Bin 0 -> 226 bytes 177 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 dist/icon/bubble_no_projector.png create mode 100644 dist/icon/bubble_projector.png create mode 100644 dist/icon/business_package.png create mode 100644 dist/icon/business_package_add.png create mode 100644 dist/icon/business_package_add_disable.png create mode 100644 dist/icon/chartsetting/address_marker_big.png create mode 100644 dist/icon/chartsetting/address_marker_small.png create mode 100644 dist/icon/chartsetting/icon_bubble_3d.png create mode 100644 dist/icon/chartsetting/icon_bubble_normal.png create mode 100644 dist/icon/chartsetting/icon_dashboard_1.png create mode 100644 dist/icon/chartsetting/icon_dashboard_2.png create mode 100644 dist/icon/chartsetting/icon_dashboard_3.png create mode 100644 dist/icon/chartsetting/icon_dashboard_4.png create mode 100644 dist/icon/chartsetting/icon_dashboard_5.png create mode 100644 dist/icon/chartsetting/icon_dashboard_6.png create mode 100644 dist/icon/chartsetting/icon_dashboard_7.png create mode 100644 dist/icon/chartsetting/icon_gradual_highlight.png create mode 100644 dist/icon/chartsetting/icon_multi_pie_gradient_darker.png create mode 100644 dist/icon/chartsetting/icon_multi_pie_gradient_lighter.png create mode 100644 dist/icon/chartsetting/icon_style_3d.png create mode 100644 dist/icon/chartsetting/icon_style_acc_radar_circle.png create mode 100644 dist/icon/chartsetting/icon_style_acc_radar_polygon.png create mode 100644 dist/icon/chartsetting/icon_style_area_broken.png create mode 100644 dist/icon/chartsetting/icon_style_area_curve.png create mode 100644 dist/icon/chartsetting/icon_style_area_vertical.png create mode 100644 dist/icon/chartsetting/icon_style_gradual.png create mode 100644 dist/icon/chartsetting/icon_style_line_broken.png create mode 100644 dist/icon/chartsetting/icon_style_line_curve.png create mode 100644 dist/icon/chartsetting/icon_style_line_vertical.png create mode 100644 dist/icon/chartsetting/icon_style_normal.png create mode 100644 dist/icon/chartsetting/icon_style_pie_equal_arc_rose.png create mode 100644 dist/icon/chartsetting/icon_style_pie_normal.png create mode 100644 dist/icon/chartsetting/icon_style_pie_not_equal_arc_rose.png create mode 100644 dist/icon/chartsetting/icon_style_radar_circle.png create mode 100644 dist/icon/chartsetting/icon_style_radar_polygon.png create mode 100644 dist/icon/chartsetting/icon_style_transparent.png create mode 100644 dist/icon/check-box-active.png create mode 100644 dist/icon/check-box-disable2.png create mode 100644 dist/icon/dots.png create mode 100644 dist/icon/drag/icon_area.png create mode 100644 dist/icon/drag/icon_area_a.png create mode 100644 dist/icon/drag/icon_area_c.png create mode 100644 dist/icon/drag/icon_area_pa.png create mode 100644 dist/icon/drag/icon_area_r.png create mode 100644 dist/icon/drag/icon_axis.png create mode 100644 dist/icon/drag/icon_axis_a.png create mode 100644 dist/icon/drag/icon_axis_c.png create mode 100644 dist/icon/drag/icon_axis_f.png create mode 100644 dist/icon/drag/icon_axis_pa.png create mode 100644 dist/icon/drag/icon_bar.png create mode 100644 dist/icon/drag/icon_bar_a.png create mode 100644 dist/icon/drag/icon_bar_c.png create mode 100644 dist/icon/drag/icon_bubble.png create mode 100644 dist/icon/drag/icon_bubble_f.png create mode 100644 dist/icon/drag/icon_combine.png create mode 100644 dist/icon/drag/icon_combine_m.png create mode 100644 dist/icon/drag/icon_complex.png create mode 100644 dist/icon/drag/icon_cross.png create mode 100644 dist/icon/drag/icon_dashboard.png create mode 100644 dist/icon/drag/icon_donut.png create mode 100644 dist/icon/drag/icon_funnel.png create mode 100644 dist/icon/drag/icon_group.png create mode 100644 dist/icon/drag/icon_line.png create mode 100644 dist/icon/drag/icon_map_c.png create mode 100644 dist/icon/drag/icon_map_g.png create mode 100644 dist/icon/drag/icon_map_gis.png create mode 100644 dist/icon/drag/icon_map_s.png create mode 100644 dist/icon/drag/icon_multi_pie.png create mode 100644 dist/icon/drag/icon_multi_pie_lighter.png create mode 100644 dist/icon/drag/icon_multi_pie_thicker.png create mode 100644 dist/icon/drag/icon_pie.png create mode 100644 dist/icon/drag/icon_radar.png create mode 100644 dist/icon/drag/icon_radar_a.png create mode 100644 dist/icon/drag/icon_rect_tree.png create mode 100644 dist/icon/drag/icon_scatter.png create mode 100644 dist/icon/drag/pure/icon_date.png create mode 100644 dist/icon/drag/pure/icon_date_range.png create mode 100644 dist/icon/drag/pure/icon_detail.png create mode 100644 dist/icon/drag/pure/icon_image.png create mode 100644 dist/icon/drag/pure/icon_input.png create mode 100644 dist/icon/drag/pure/icon_interval_slider.png create mode 100644 dist/icon/drag/pure/icon_list_label.png create mode 100644 dist/icon/drag/pure/icon_more.png create mode 100644 dist/icon/drag/pure/icon_number.png create mode 100644 dist/icon/drag/pure/icon_query.png create mode 100644 dist/icon/drag/pure/icon_query_g.png create mode 100644 dist/icon/drag/pure/icon_reset.png create mode 100644 dist/icon/drag/pure/icon_reuse.png create mode 100644 dist/icon/drag/pure/icon_single_slider.png create mode 100644 dist/icon/drag/pure/icon_string.png create mode 100644 dist/icon/drag/pure/icon_string_list.png create mode 100644 dist/icon/drag/pure/icon_tree.png create mode 100644 dist/icon/drag/pure/icon_tree_label.png create mode 100644 dist/icon/drag/pure/icon_tree_list.png create mode 100644 dist/icon/drag/pure/icon_web.png create mode 100644 dist/icon/drag/pure/icon_year.png create mode 100644 dist/icon/drag/pure/icon_year_m.png create mode 100644 dist/icon/drag/pure/icon_year_m_d.png create mode 100644 dist/icon/drag/pure/icon_year_s.png create mode 100644 dist/icon/drag/small/icin_select_tab.png create mode 100644 dist/icon/drag/small/icon_area.png create mode 100644 dist/icon/drag/small/icon_area_a.png create mode 100644 dist/icon/drag/small/icon_area_c.png create mode 100644 dist/icon/drag/small/icon_area_pa.png create mode 100644 dist/icon/drag/small/icon_area_r.png create mode 100644 dist/icon/drag/small/icon_axis.png create mode 100644 dist/icon/drag/small/icon_axis_a.png create mode 100644 dist/icon/drag/small/icon_axis_c.png create mode 100644 dist/icon/drag/small/icon_axis_f.png create mode 100644 dist/icon/drag/small/icon_axis_pa.png create mode 100644 dist/icon/drag/small/icon_bar.png create mode 100644 dist/icon/drag/small/icon_bar_a.png create mode 100644 dist/icon/drag/small/icon_bar_c.png create mode 100644 dist/icon/drag/small/icon_bubble.png create mode 100644 dist/icon/drag/small/icon_bubble_f.png create mode 100644 dist/icon/drag/small/icon_combine.png create mode 100644 dist/icon/drag/small/icon_combine_m.png create mode 100644 dist/icon/drag/small/icon_complex.png create mode 100644 dist/icon/drag/small/icon_cross.png create mode 100644 dist/icon/drag/small/icon_dashboard.png create mode 100644 dist/icon/drag/small/icon_detail.png create mode 100644 dist/icon/drag/small/icon_donut.png create mode 100644 dist/icon/drag/small/icon_funnel.png create mode 100644 dist/icon/drag/small/icon_funnel_not_continue.png create mode 100644 dist/icon/drag/small/icon_gis.png create mode 100644 dist/icon/drag/small/icon_group.png create mode 100644 dist/icon/drag/small/icon_image.png create mode 100644 dist/icon/drag/small/icon_input.png create mode 100644 dist/icon/drag/small/icon_interval_slider.png create mode 100644 dist/icon/drag/small/icon_line.png create mode 100644 dist/icon/drag/small/icon_map_c.png create mode 100644 dist/icon/drag/small/icon_map_g.png create mode 100644 dist/icon/drag/small/icon_map_s.png create mode 100644 dist/icon/drag/small/icon_multi_pie.png create mode 100644 dist/icon/drag/small/icon_multi_select.png create mode 100644 dist/icon/drag/small/icon_multi_tree.png create mode 100644 dist/icon/drag/small/icon_number_interval.png create mode 100644 dist/icon/drag/small/icon_pie.png create mode 100644 dist/icon/drag/small/icon_radar.png create mode 100644 dist/icon/drag/small/icon_radar_a.png create mode 100644 dist/icon/drag/small/icon_rect_tree.png create mode 100644 dist/icon/drag/small/icon_scatter.png create mode 100644 dist/icon/drag/small/icon_single_slider.png create mode 100644 dist/icon/drag/small/icon_string_label.png create mode 100644 dist/icon/drag/small/icon_string_list.png create mode 100644 dist/icon/drag/small/icon_tree_label.png create mode 100644 dist/icon/drag/small/icon_tree_list.png create mode 100644 dist/icon/drag/small/icon_web.png create mode 100644 dist/icon/drag_helper.png create mode 100644 dist/icon/example.png create mode 100644 dist/icon/half_selected.png create mode 100644 dist/icon/icon_down_arrow.png create mode 100644 dist/icon/inner-join.png create mode 100644 dist/icon/left-join.png create mode 100644 dist/icon/loading_bar.gif create mode 100644 dist/icon/no_auth.png create mode 100644 dist/icon/no_data.png create mode 100644 dist/icon/outer-join.png create mode 100644 dist/icon/package_selected.png create mode 100644 dist/icon/push_down.png create mode 100644 dist/icon/push_up.png create mode 100644 dist/icon/radio-active.png create mode 100644 dist/icon/radio-disable.png create mode 100644 dist/icon/radio-disable2.png create mode 100644 dist/icon/radio-normal.png create mode 100644 dist/icon/real_time.png create mode 100644 dist/icon/report.png create mode 100644 dist/icon/right-join.png create mode 100644 dist/icon/slider-active.png create mode 100644 dist/icon/slider-normal.png create mode 100644 dist/icon/table_style_1.png create mode 100644 dist/icon/table_style_2.png create mode 100644 dist/icon/table_style_3.png create mode 100644 dist/icon/test_fail.png create mode 100644 dist/icon/test_success.png create mode 100644 dist/icon/union.png diff --git a/dist/icon/bubble_no_projector.png b/dist/icon/bubble_no_projector.png new file mode 100644 index 0000000000000000000000000000000000000000..573381726c44a6b081a8c103aa4525ee146e40a4 GIT binary patch literal 3106 zcmV+-4BhjIP)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z0Z&OpK~#9!?A0-AlTj1~;3uWrNWjK^mzs_D8Mi*LiN~Z!fvloxDeeBm9W;Q*5I@YE}0Nx2V>gyuwR-!Wph(o#G?1 zI9=g8co&sl{eUy;ygGjbI}Z?Wdu&~cme(-993AL7j7x%VCBGi3vD_b zw>R(s^+*k|o1~pzb2dGUp5IiyjlsN4{}7mt+mCRJ0}LXap^42T?feXp*LaKP!8t*1 z)T(}2_|T@~_5m(2Pi&x)q@Cunv#5@5IlMtUu>XIW4zZQP%h3N9)3lB6x5RGR_69GO wK0%UpF0hFTKF6wrgD#2)lpg-%I~Vvp07!UWCxPH8-2eap07*qoM6N<$g7E_Jng9R* literal 0 HcmV?d00001 diff --git a/dist/icon/bubble_projector.png b/dist/icon/bubble_projector.png new file mode 100644 index 0000000000000000000000000000000000000000..bc579e005856bf0d88e83fc31f1efd8d94be8157 GIT binary patch literal 3290 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 Y0NgafT28ISbpQYW07*qoM6N<$g043_w*UYD literal 0 HcmV?d00001 diff --git a/dist/icon/business_package.png b/dist/icon/business_package.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f3b387ba7435617ba73867654b78aee9f8088a GIT binary patch literal 559 zcmeAS@N?(olHy`uVBq!ia0vp^Q9$g?!3HEhC{3^dQk(@Ik;M!Q+`=Ht$S`Y;1W-`2 z#5JNMI6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZXoP$%OaPZ!6Kid%249rR*ylxg_* ze@%4kV!k-*mP<>M!~JEsxZ<5&aDI}kYOZR~i|tyX@J6Y`aFugH%9IjqWy6n@dDcDM|L&q@D*u+5JI_}KGH=W1H9L^TX0CUWhnYDqCgVx4 zpKS8#+d`GE=SrM;xiGZzjgX<%)4O?ovtu`Iw+?c!RA^`CE%La)Vgf=A!eGSg>i|N$ xCX8T2s^q?f+y*Rh2OX9l(RTJ zZr{>+`6fL7ex^$@_s}|L{o2>|3AeYcTKD?(-q*X%mMNTb;$C;=%)a-%H{MyY>uQHL zJk1NT4o_RK=8nzzUgk2ksD{++(9o$D-xsGFZ+O79i8qo__rCJuzJ-~yURM~Dy4c*g zw={Ft(Zv6+-!3*S;rV2BK}Lm<*93?z7%)KSX8U}fi7AzZCsTon7-x98IEGZ*dUMA&tJy)K;i2J!g4=wydU9?)|J?)r?%2ujch1Qsi#vJ^ zylR`byf+u+%3!`x<&@LT{xAMK&*1=8M~0g%pKQV-r``SQ)8F^rQ(NlEOWRFJB@(B~ z|BA199W^zza<92>@|Uf@WABu*KibVRXW7cE+t<2eJKig8sL?oicbRO5@r6xAtP#gp zjH}cVZbpf^9&CRYb6`^y>(1A2>@6c$w>a=wv(4Na8hX>LS^k-B$&LRdxejLRyqgp= zn4~~x0VfD)M_+w;_xjJ8?>|bnC%Xz?aA5WYBVH3mAlmD2FX(@#shxt+)gbo3H5m&U zmzkb@@qfl^nLijxedOW~9_wP8)xZWe9&SVT!eogweX$qJH$E$Mf9z*qW>8r-S0u(E RI2;&}44$rjF6*2UngE{H&l~^% literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/address_marker_big.png b/dist/icon/chartsetting/address_marker_big.png new file mode 100644 index 0000000000000000000000000000000000000000..8365a270e9285dd62cdcf170de34f02472adab08 GIT binary patch literal 3465 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 literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_bubble_normal.png b/dist/icon/chartsetting/icon_bubble_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..dfe3819037e050627a4e00b7f1cedccd888468f4 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6H#21Z#=7srr_TS*BLtjxR;o>vp@ ze|BQ<5M?N|6X14ewP*Nvq*+yn_sWI`HWPwaANe}euxhPgK2qmUBi$j}C|29BGF|cF z2euUtLmg`5Jzp6K%x8FHw&MK*yF{gn%s&IB-#@NYF0VDcU+08N(hY6}R&KKbR?WB* zpBPUzWNbP0l+XkK97K#2 literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_dashboard_1.png b/dist/icon/chartsetting/icon_dashboard_1.png new file mode 100644 index 0000000000000000000000000000000000000000..89e25f2b278f88fff9b676da79e46b7b88ceb39e GIT binary patch literal 868 zcmV-q1DpJbP)wjCX8Xgb?gx<59qe5VszJ4bQ3{z zVHng^;$M(RG*npHCTYVlwz(g=?esmL=N!KskIf`sIQ!mx@B2Q__v3xv4>)6Sb#j=W zpC1v!l=u=h)1vt1CMPGCPDLPq37YKf?Y$fhhY<(_u(Pv+fq?;O&*$^l-rh#BSX>u> zX9dyRi3kL6p8-4*i^bsedg1r`rEPU}6~n{BmT#p}L9JFpDwQJ9YlEnu;<+8b7lww0 zW=2Ox<*J*_CK`=~wEKKM%a`-@dR_X^mobbrFq{dva^X0_plY=$C&W&mX`0j{k%;B! z@p#bR-!Ju6t0jpTOAJQ>o;i;t9*-j!45Ik?J@)taJ7x*Nb06Nwg)o*F#{C`HL6T=q z;kjQJpFr)?JLuKQvEa1rete7I*j-6LF))&C1WZL{3y*^5O3?-{q5JAJXKLLJ-SHZ)*orOhq$WOz~d71?~0&lwLeR>(|f2V-Y&%XrqrQ zrBVrddwU?3Q9IBKTY{Iwi{qzC>Bbn`YboSkJ;#^mO*wZj^A(|3T-welzCArXay0HP zp%NS`4PE?9KgL4#8P>jkJ1CyPD5k|6^v}>-}M$k7YFh1(aaHB+b(q-E|<$B zSX7T_j*W{Mz)VoZ=W!wAb+@gSI_GFprCctfP$Zp?NVnytdy8076I8K?R u3W5Lj;QZ5*X$L;llli|N{WF(80t^5nU8ZXP@vKb%0000{U%`6JZdZESt2u#;{2W`SN3P2_%QK#9}}R;z7ASou87)q?}5n!0mQ3lKr4*8Y`Yory(AX%jnwLZE)`d6d>|MBEg7BlEXmP zb*NM-P_0%;rpx9eoJI2u>;i(pAas3cWuBUd1R!H+m zB*HY0EciixyE$|Bz0K#~69qQ4EX#l!V+otSJKiy99fW~;8>7*PnfiXqXg^ywhH7u@ zvm3=IhjOj{X0vG^XU&`-huupqmuoBwL0HZJA3g)^N2_4`()M&sK8jHe<(g1cm8pQ! z$XFyt1r~86n46meuh%<4B4)0DGkg|W_wPVcQ9#lDFr#boQH*k|5Cj1vNdo$I=;P$+ zXWEYOd`6LcNs z;f5w3^e*PzC)xV@r#j24V~5}IKjP8juK)u8F4!*UNiocW00000NkvXXu0mjf&1GR< literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_dashboard_3.png b/dist/icon/chartsetting/icon_dashboard_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f140c7c427b0e2c67f89f576f9d84b8d4e51da7b GIT binary patch literal 971 zcmV;+12p`JP)i%}H+^=rF+>uha0s_S$*L1!b%BBq(egrp{B7Cd{9h(wsg177@%KMyh_ zo_OE|^Ws6oWI@?1OOQ1FOl=+0nw3qp%g}b+>Yh)(`ntB#B_24*$^E`_?){x}?mhQ+ zf&X1(e{yO!95Sj{GOa2d`+M7>?rW0FUEsYY^u4!80Pqtnzl~ zbV0b?B~*@`x2$Rj^*juv4Zxfy+0a1X75T&1^0X1xoih-QMDaN=ihAQK6ez>!@|y+Q z4TlUawpEo&T`(Gl#2`Eia970SCLL%KZ42p>l4DqDs}X!J-uZ;FJl}^Ey8a~F`eoHH z#P(y}T(6*n5yuilAt`{m1&1wg~e6YEA$VuM@Gc5U$>H z3bx9ni&0zqL_80|+M84XwPHp75HxHHrrVm5z^B=^A$Or2Jvmi^(l^=2C(2sOPVlM- z^m;$yZH>tRtSfW_==2vS$|s@BoY-!kG9}QOZ-(9I`mr@NfOt8AG6iCN zeK>fjH8Ejq(3KHX>Z3I;gWrM3SjGyRoty@?iJmu`n8{J2M{998PF-^dtvK3wSvXK}&na`UO-XjvSK-499a?-r#QYm-fKGKWT{1SL&s_ZCvni|T68bsTjn0PN#TPiYaf-2bc4lt_Fx;b^# zyx0%yhz`KAsSfkY%y|0dLt0?Ud|BmuI88-}4SvD+bGOK>Eos?QN_JEQRkKaC0FT+( zq|IDc0A-y`$eOaJy=UM{GO{VLAh98_;vIRR!Oi8Oms4Xzrbr(kSB01_k-0$EQYOv% t!O23he{lZxlQ|`!GZJa#pOK#e3;=b#SGTV0d}aUu002ovPDHLkV1g@_zZU=i literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_dashboard_4.png b/dist/icon/chartsetting/icon_dashboard_4.png new file mode 100644 index 0000000000000000000000000000000000000000..079b9db426c8daddf9fbe38619aff491f2d6d745 GIT binary patch literal 3298 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 literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_dashboard_7.png b/dist/icon/chartsetting/icon_dashboard_7.png new file mode 100644 index 0000000000000000000000000000000000000000..45f6a85029f56a89f11b5ce457568e8062d8fb87 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqHCTmjv*Ddk`g3X7dL17Nmmvq@VQ}Rv-%Ymfb?`jf${CRBdyj4)T*?_$*T6pTzsp1D7 zCD8j^*pw6pLjO1DJAeE)&D+xpy1C_`<$p}lSNNHvRNbXX1o2rV13cO ze?Cb!_o`MrXkZnKYia82Zti~g`TKevRcpCLM;OH~uy_})dFQjlTT2S)i6RDp1cqDl W{NFZyn{W*1Lk3S*KbLh*2~7Zi*@8C! literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_gradual_highlight.png b/dist/icon/chartsetting/icon_gradual_highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..e617c565a9dbb738b26da88deb11f61bde983871 GIT binary patch literal 556 zcmV+{0@MA8P)3J`1=29DofHM`Oi`4F})?+yx{M8-xTK#HJFcO;KqZrT&{4 zM@`+*hV-{!lxgf{>^E;dPMC8JHYpKoSmI?Coj>;6*+Culw<3rc1H6C&VeqHJE!-y( zu1+}<>%q^l>kVrXHfGYYW4-r?fR;S#NdXssniy_n1i*J zY0f}<21zFTcJ=0C}#I0*(1Hn!(*C_w!lZNutrP&zZkh0-&&HDZ${Lsc`Vz&L#}Q?kpGx zR-FN@S4x0Fhh939-cNUDo&ya7ffZz2_2XIz2^?v^e~Su@h78OC?*pnBDFuA=4Bmgo zHGJ{;>MDtSXj=ei{8tJAiJ0xZvg1``TLuu?763ho=ZfHS7j@F6XfKtFnP{q6_20$_% zh(WXh6hDCC3qX93AxUNf=@!g;k^m&@p#~BHAj=wo7A+ub!MrB|Kyp10JCG3~ARh$+ zEqZ|60*K-Jp}_$LoXm_2I)bbWx`HeWoGb|C-~aq)xbyih!|B(*7{34gk8H{ZAa(>= zaskx>EQZ@jurs(zvx67@-pGcFb22k1^RY0npm~HJs6?8Jnc?A=zd-y4ET+uM0`v_Ba&Xzh zf~XLj%z()a6f7_x%)!K<&W~w0GLYwC24WTlM7)6=w*VT^i5Ob@u6zyvWh@pZh5$2B zcD#logHx}6eEfZ_Fqxcl?#;{qcsro7oJ4iB$lnSMcyjh>~WkxnY;RFsxRL~8?>==#G zt_CO^!r>Ab`$tDeMcZhk3^btPSF{~Aj3$6qH$iP!U|P;vo&yN^IEYO1AautpBe&2* z?lKr8UaXo>_%^_>{*El5Q8XaH;tbzwvPLT5n8|Zi{NdApr?27Sc7^z!gt*sqyIP76 z)oWFN>0>l~N4!)sJFDNZJ-Lz&uT^JmKET69#0O!&laaJ+IXubwCk6Vj*PhW(j1|9C zb;uOzP&1od$se)0+*k52Y&)6;xKA_ogar4zX_RGh`(O0YcZ=Tb!cU@54$9<+E?6)|0co?_AM zkRda$yHFnas<3hPB2goWnI+dl3PrESx{G>@L~26PD&AG@!N#uu0|1qBs>^-qK~4Yw N002ovPDHLkV1ltj?1%sW literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_3d.png b/dist/icon/chartsetting/icon_style_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..3a3285707ef0e540e70365f57f39d7e536f55651 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqFzrI$B>F!Nq_$Tw`bO6e7s;w zL*c*Rrdj{gy^NbO#EN3gZaOtQe1CsGPyPSDsXxAdmv7;Hdi`!f%j)EXM}7;huSxpx z^|$!p_woA!GuRX(cSxzRNi_#@yXh{F*)Ul!_;~PQ?gD&#MU0?eW8p32@D;-(!|gF%Kvgv1Ruxw)OrJ>PfEcOC<< z-50mf%gM<}D;|Bg?YPB1UI%geaeF&DI;1TVAow62F5D8&^HNPsjhsv-9VU~>pUGsT zNF*XCibAC1ga=97n<7A90gorlaG<@ty=mx8!ucVZfgj46dS?%>g$wmYI8i3*OMOWAC8 zn6$R<)2kZqDAf=!G+T5O#W=oK^MWM7Jd*yR1T3L0_9!l;vSTETypkQP6SM>FuAgwU z;T1TJgy3RRnq&wDBI&?lVr@8Q!%i2&Du|$u>DX(rSo&{GEB0q!Qt)yv<;4GlEVm** zTYL>q7pI|0SK(7uSH=S0GH^SfIK$!aBJ;eLVe}Ovpi=Z>=iYk*2!1)Q^-mUvy6RA(|wFj<1d`kJDE{OUZ#-Udkp%B`PoYz2 zC7FOoj2eR~o6*>69SSPBim~79DkJ^9f9nGZu_yNs3WbCdHa$F;O~NVuEOb`3NN<-v zQo`wX@anEha5uEFZcIIby)nTsg2g1F3UFW~l%(NUEGD<@O?je<-eoH{_~(-IG7_lX z&Zic@%vFw5o8nF-y{a0YsVjk*nVDRP`ie#1Wt})iGYDmC#v$j%gkMID-3ac;U7T2W zAqqxr^jb@4kUE>nxlu^^;_>(}!|)bFKqD8ur@7+H4-u0-g2}rH%ZH(>wDz}Aq84Jw zY@ek}(|x_oJX>MV_}&Gcds+Q^^2ay#k71`0&3sGGdS1k>`FF2~Ch7qj{l?14+0pQ8 z-qN_HX^9cIu(NwGFLusY?%!$F$Sk2F2=3fyTyN@w!;&`6h`ZSpsustVKREyUlezuZ bF98MsK4YcW!WJ(@00000NkvXXu0mjfPao^Q literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_acc_radar_polygon.png b/dist/icon/chartsetting/icon_style_acc_radar_polygon.png new file mode 100644 index 0000000000000000000000000000000000000000..6c15e6f24be634092b7faa8092914d4b740c2f72 GIT binary patch literal 1124 zcmV-q1e^PbP)g(&1{}TsjJZ!O8E}6|{uCZ3BROC{rG>%Tf z&+GsVi!PTdmN&ZvY10Tx#rp2vQM&=ocGcki;=F{@VRRIKk{x3U!veAxlBg(3d{H(C ziRJR&WR}s{U^jC^o8Cm7xaLUOYfs;dGZNvPMdEm#ANKit1Lt03QhSvGhfTnE(|E~N&0N>UQ80g=Rf39oe+$BShphBCq2di`cPo%W+# zf3uxd4%EZ(ZjU(mb4e94>VeBwY5^yc|g|Jz zdD5u81FQzB=QvgeCe0W;Y<)$V-}ptSC{>YiV9_(G97Sc?G5T4ZEA_)~)&5g%lLMFi zs3#?p$@Ujb8^J5zZH!X*YwR5;RM+9kv5$dprzoywJ_DECMuv&1!OSbMvQog4qmbk~_9xrS-WvaHupsGW<{|Y}IPPCOi8gpj${UWDH@V7t-HI_%~@gS6F@r8Z?%$f?QHY zvFbvhQ|5SQX^HYSr0ILx_5;muRI7{$-|>^e)jMSoPr57P!G7=&R?N!6-3je+i)&pj zb>Lo#j)su3v$L~GE|)7HRMGk6KaeS5n$tS%liV}6OzmxNJj0Y1p@~P3#-7%j58Ctv q4Yr_$bEsAK`qx8q^pD1$0t^5H(!tdxZo!@a0000$WdzEFoQ+@ zO!XrMm8A>xW-~oGe|(`IqlXy7N12>UKWZ3^D)a^Jvp*71*v2lkO-@SY!~*#abHAP*lL1;bYwnRe|_jN!-;=b_}gAIaeIy@tC%S@niIc^$IWd%Dw7X zeMan$Jt;-c;j%6B+8P6{Hbn*w0|x7MPxsjg7OcRKVDNPH Kb6Mw<&;$Vetbfk{ literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_area_curve.png b/dist/icon/chartsetting/icon_style_area_curve.png new file mode 100644 index 0000000000000000000000000000000000000000..e8bee4d650fc29dd985b279d1a7795839633fdbd GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6H#21XH27srr_TS*BLtjxR;E7LCR zQD<^6V(j2IP&paXz_~f#;>OpF5iB{3LJ12ez2$k-S|U$7mKjm;oprZass~@K31;KE@Z4$*w^IS#M!Sl;dOLlg_3|i%cH*z-XaAn zN*NxVJ`&AP_*PpZt)c3_fQiz@t4%!n`*kZm{B&SASs)R?cO=MxS^C0}zlA&H=Cj_| z^G8%FU}h*i?7{yyv+ffx5E(pO{an^LB{Ts5q!*Bs literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_area_vertical.png b/dist/icon/chartsetting/icon_style_area_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..68755fa42fb2aca6c63d8f7626b02d42056d939b GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqIgdi$B>F!NeL3Hhvf_=EzQ0+ z`M*Sxr%}Y&q=g3x>pb50?hrA&Xw{LC$H=`j(Ptj3O3OzDUL~)|dO-z2r3bcyB)78&qol`;+0Jg$H A1^@s6 literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_gradual.png b/dist/icon/chartsetting/icon_style_gradual.png new file mode 100644 index 0000000000000000000000000000000000000000..862bc17af725ed0053c07025d06c073f97296358 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqV=9Gjv*DdlK%YvZ_ljDD9qf; z$Za`G;<>%*i?{zfFZHBEGZ-@V%l7n4`N_ai5h+=Cs`lSuhn=i7YkVqnez-@=8`Las zz=vor^B@N)@?r;(`p#_*X-~Ny it-7vwe-#6V0Yhbl+U_%Pv!sAdXYh3Ob6Mw<&;$U_=5Uk% literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_line_broken.png b/dist/icon/chartsetting/icon_style_line_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd5ae62f05370ea9cacaa1d16d295e016d18cbb GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqK}>~jv*Ddk`g3X7dNOFyzgX` zP-axqiry&K!JF~)7n{Ppe!VkJ4#5mF{3hLWaG1+5;SBpDhZ0RE#}NK+-}b0;x~#Bf zC^^CSNO#8fBa9wRF=-q}{yO}tk$EN3kisY+o;3N`bLI)t#hGGD89lU{l=JUR{(9ko z1KVE*8^#sy7(a?R#5`rV#?jf#?{G;_YqxwJ=aK0OcREf_?Xl3A!Eb6I*dD`h#c9H8 zex|FY0{M(bO1~dW>_2?_f(Lu#7lsvXg7I&Xy_d0G5c$Zke4WZnRtImp39}R5IUk;; xw$qTY<9zUCk1ruCUXwZ(Fa4&Wz{$WO!Eob_kM;gVt3biV;OXk;vd$@?2>@uxfwBMq literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_line_curve.png b/dist/icon/chartsetting/icon_style_line_curve.png new file mode 100644 index 0000000000000000000000000000000000000000..b7cab0b4e61046362f8d622d47eab9b17b20e847 GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqTik_jv*Ddk`g3X56c+@on2Dt z&(e^>Bp{#QF=;1*aN5E}$=97=s%xYI@`k63a?c{_v%*=D{`Av#sP~mO-p?qa};}TI( zf&BgKNsc)$XN4SSQFVWJd}`(i#v4VSoHnp7P7o2`W?A+xM@O1Ta JS?83{1OOpmi%S3i literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_line_vertical.png b/dist/icon/chartsetting/icon_style_line_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..c654f3cf32b132c3f5c14bc92f400ee1808b5270 GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqF7HC$B>F!NoflV6Xdog{D?l_ zF>PI?|G(r8)sqH6=ObT;C2SVpnvo&vVzRxV^;+VYreL<44mOE49?cz>rnEk(eihN6 yUKgQpDkkK#M@TpGs$G-(61Lb$Fp4p-NHF+@OS;M}D+~u(#Ng@b=d#Wzp$P!;r9#{Q literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_normal.png b/dist/icon/chartsetting/icon_style_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b0cd6374fe3d8ae47a82204c97b77f2140a5e1f5 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlA_q?w$B>F!Nq_$Tw`bO66lU&a z5fy02IZUvw2 UnJ4T=fo3syy85}Sb4q9e0HcICBLDyZ literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_pie_equal_arc_rose.png b/dist/icon/chartsetting/icon_style_pie_equal_arc_rose.png new file mode 100644 index 0000000000000000000000000000000000000000..e5ee1145b8a7522d02ca0d3ba17957c90024002d GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq8FYnjv*Ddk`g3XSs0WJyWUjC zSum`uQDD2s#O|#k(Ydvuwc#L_Lzdl@giQ?Ga))^vuGCHF*5p)Dv(a0AqhOAhL$hmx z)WkDQ%1)eZKl_72|2JM?Q_y>2kX`N2#sA5(Ab~+(K6}(Mhc4D7%OnB&ZCcX6>2SSX z;b@baQ0zSqFF!Wc%dASeGZ}b)^Q%l>=HM;WAjp?=Ex9{j!s$XupP*WXEk_u#JQ;LE mFY3fPPyV2>K#qaKfML;2+xio-=T(7zX7F_Nb6Mw<&;$TBl6G7G literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_pie_normal.png b/dist/icon/chartsetting/icon_style_pie_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..9c5dbe98a7650003917aad099d53a57c2983568e GIT binary patch literal 432 zcmV;h0Z;ykP)#>M1t|hsjB}#<^>>L2*e9G%-TNSGJ^?^ z;Q>JEJ`nfA3`YY7P`Ud+3j;{90BAVK)$4&+fQV24saX%S#DORape~OSj}LxaxLlsJ`9r|p-+V;J6DbxfP*&#vxqSWG`(g1wOA5)c-~s`|VZma6$C3;9ELcc{ z;S2;US%}Yq1wj0P2*Z&r@dwh0Q2qy~8MsSRXi>4A2*XhvCZ;wAq?VyWy<`Ew;u>g) z1JG~<5{nJTdA5<14d#6m#fiA9j^4+WJ&K{K}eJp6Zk zey`L-9p~*b>sjSLNa|^vxx}BM&7k{&{gIQ&SN4vL4;UB^CmvL2I6A5INQA*ej>D20 zB8(Vk@S6#Q&SEmYU6;{yAl;&BgVnjuqB|UNRMeS1GEY!j@Q}$xC6+PfXZwmG*%?_5 zs@b*z>U?F86+Z8N<^btO@Kkm;OXk;vd$@? F2>>;XlFI-9 literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_radar_circle.png b/dist/icon/chartsetting/icon_style_radar_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..635d41fcd749e827510629ec8d6ede5ce10e6ca8 GIT binary patch literal 793 zcmV+!1LpjRP)b&b!0RSyS})QEAG`bJoA14u_hwd-j{30e zXUymGUV3PRAR%BeX9;P7?)UpQ25H#$5r0IF0%3uLR5q!MG}{WyJy--pcGDw8!0wl6 zcL~APrf-{tAECz*0a2)AuMCX9BCd+!-EsS6WlyS@qq0wmHTp-up@vyJD~Q4=GG=ct zHCi1Pq-S~Mx;riS26%Hx@{RUHzy})P&j1U136J?K?wxivFdZjML5yrbQ1pQYYxSf^ z<2)`Rrw`wh3M_n$@Pu&poNEib3?W8%&|N6@>PMN+VUaboehXkHs}x?E;9EDwDyPP` zrK`uQ>nDyib7V8bbkbajY_&5KRk0y&zz4q2V6Dz@2tEigD&F&NrtCPYn8qbfO)obc zFEBYN?>YmM^?8rHGjHsUWIk_=u5nFt$8#aoe18 z04db{xIbMC)4i8Uro;EXtY~jHT~9GzZH^dt&y!?H0aiAQL@0uH$Ffv?cJdTx=t?OJ5pc^*SaVA4Aj`exLguH^t>h{eVw+^~Nr>&+Hl*2!{U|{B{y@E` zvml9A`t%_b-1&cQ*Y9#4+m~mj57n-1Lw-0Bc3kBOO$k4q5Fe_?2?>2 zK~#9!v{lV(6HyS~e60y-XhI=Uq&3@%A1G|`pai5XIrL;Gc=DD=JV(KkAW1L1+MX>Y zJ%|^<690e(m8d6ED)k_mh(aM0lDdhhF(3XW%*u1k+D*`fAG162o0)y@&6|;=|NPjj zkP3x@AL1Sm1G2!aa5!AE;%m1MJPlC-=2=Cu#QM=!fB+OI1B8HOU=^qW0pKQ(0?I%f ztI1nVfWRRRObIr5JIZY9;oTcs^o+D!&q8RR|p8#G#FK?z{`=I z?8GBJ`LVxwnbO_?@m9}KR%ESl*}He?th+ihs5+oOPj=!FpZo^h4W~(U72kg!_qlA{ z*OSghA~@EJer);flVMuclo?sO;gGt)y|#B9yo*q4W@T!YU>mr)dl-22**>;&#$An` zI(D!^29gIIIrr``kkh)Z22@et#jrP-%Jdw)P>^=d))0;K&A}z+6-P-RO}XmP$k>(lQ57brOFS-wBS-!R1aBZ0!*GlS)B0je>{%Wua?bsAXEgAiH?a0J)k=vBAFtaR2}S07*qoM6N<$ Ef<5kv3IG5A literal 0 HcmV?d00001 diff --git a/dist/icon/chartsetting/icon_style_transparent.png b/dist/icon/chartsetting/icon_style_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..fcf229c947fda6b08fab1bc7befe1abfd64a8e44 GIT binary patch literal 195 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_area.png b/dist/icon/drag/icon_area.png new file mode 100644 index 0000000000000000000000000000000000000000..d86416cbc68b23a5cc408452c30876819ba8638f GIT binary patch literal 666 zcmV;L0%iS)P)aA8bD%FO4ka2%qLJs5{%?lAWj8Zf}9NJv$HcD5)xs#jILNt z;{t=Y{2hiz*A0kHMX!K(BFIosd;nda0E}2uF-g|t*c5XLTu=G)i}%#`FZ?R#d4mN{ zWS#(Gogd$L&I1i+6%b-+V`FFhimpgdc5@^H!(XnyKP7gFNPfKd?uG0FqVmCu2Wl2K zPun{)Gymf-aoxTbThOrcJP>2$coX`f0tOz%=S^Ah5fA)m(T_A|Nq$U|NG1Ol8Nbu%8#$gQ}E?v z3?Bepy^UY!>rG@akPDGr$-?$Qo{{CdILPAv|5$(Evj8OyK;egOI5q&X?DsdxQ}}|0 z(!!2t059y)($W-=ieQSstXZ=d8AidN0RRC80N^ms+MO<@0%XnJ0=% zvF@d+1?YzJiXXA4xY=WXtcHaQLluA&2>SzZ0nBhg+0BuxoG<-=VyltWGZK?BpoW1A z1*Z^Z7RD<~ObjnMxtLB$%6-1fFSRS5ne~e}P-;SlddVcBd;oRnd`2b)Ep~RMy+Ffu zv$HcU;pSz21yjQ%a8;38_WvLII$)TJK@A0Y|2`o@G=KjRbN=x?Qt;nj3uXp}91gR#1vq^GG<*}( z@UMgn4*34nTIKg|Z=V1E6rp&Fk&#Pa_?KllItnt1GZ z1@&bsE(f9ez`^*}Pf%vL42?)o@Z2NDH$+7;(0dzxoT~au&4LgmlGD=C{!_!yS+iy_ gGK_*j0{{XH0E76PO(s;XUjP6A07*qoM6N<$f+r>ixc~qF literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_area_c.png b/dist/icon/drag/icon_area_c.png new file mode 100644 index 0000000000000000000000000000000000000000..23f54f06e855b9f315a88159b88a5c06c0afd7b6 GIT binary patch literal 459 zcmV;+0W|)JP)4LL5v4;)B4j zPDIiJN+9!rSPO{VfpQnf4WfJ?{s=O>;$}|(NT5T#WCM`@0LXL%S`>iS2S5b|K&lLg zuK@8&v~UH5wF@X%#MI^lKwS)yzXrsKK#Lv_8_7R`*cFH!pnQ;JUw~Kx5h!dGpq3o~8m@q3_+BKXVnAE~#5_P82(;t^Q5GNrpbHal z7>*1;`C>KE761)}`M@9QLVSiZKqGxK&Nu)XXaG$q3TSZvitsjQn3DvsMKU`O?*`%} zxN;{cfCClVkyp$QfN$&gVM6ze`^E{X^vC&o2tE z;F{Urar25D^<(9H8Tt1&-=SY$rFTp)4Y)wG1t0^s1TR(n`^WZ#h5fx17t=3!kodp9 zoLBz;WqZlQ@>LfY%HMx}R+s`5`+(I9d=?1EY_I075w=nu84VXy+SlHgV{rn=g znpQda!LM)9izy9voECJbmt3GmxMQsk($dltfYg0z7&>d#EXL8QmS_MFU;s?tg9Hx; ROIiQ`002ovPDHLkV1m@=(4YVS literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_area_r.png b/dist/icon/drag/icon_area_r.png new file mode 100644 index 0000000000000000000000000000000000000000..529d2a193b60c9650cb3695fdf27bfb0fb1299c2 GIT binary patch literal 569 zcmV-90>=G`P)K!y6xk5qfB+x`3f}`j{NP}T!~-O`0!AhVFKJn}d|dij z2pHbL$jDH_!peB!-#>=nzkmMg0L2)fmVE%qxeAN0R4#eV+$FaG`8KOIgkrYk}sESF(&uV4PQ`1IlLYM?JK;Pe4Bxy=W<`iG=6 zTh+%8e{^3y`==x*%yI(cQf^-6SKPb|uYhVUBU}3V)t>^O4|#yx)yU>CV@t~%oJ_}M z71*c0c=kKw>z98~zkdDy0CZW+=TCnXe}4bZ#>U3}_2>704xo@D$jhK$1M&mD{Qm3z<@4WsP`v#8`(FuY z@HLW=FQG7^2N5u39QpsBp$Dk3 zff_jwBZz>8#}IPW$O0&Fkd~JApBjeFnl+1YG-wA800=MuOq0QNI@>8m00000NkvXX Hu0mjfgscaV literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_axis.png b/dist/icon/drag/icon_axis.png new file mode 100644 index 0000000000000000000000000000000000000000..d366542862e4aa3e43d6ef475fa2ae730947efa6 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqI6Fe$B>F!NeL3Hhvf_=ty=gf z?R>q&Zs)x%3+mLOekZ($KH%ixc_!?QTy2}1(|GlRfJ5k-#+R+>O789ZJ6 KT-G@yGywo9vq@M0 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_axis_a.png b/dist/icon/drag/icon_axis_a.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd017016314f04a2a2e7fd612c72dabc5596b90 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq9{)n$B>F!NeL3Hhvf_=ty=gf z?R>q&Zs)x%3+mLOekZ($KH!u&LwJ&Wg}lstndT$f3-2%mO;%K7zhK|Nv9sffg7n#p wC8A}SnVJ7rCcan`xmiNe?cfPU21Ygpk$hQirk97ZfwnMsy85}Sb4q9e0O#gG;{X5v literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_axis_c.png b/dist/icon/drag/icon_axis_c.png new file mode 100644 index 0000000000000000000000000000000000000000..3777d9050e98ce1e9da9b4730f65e31920d6a823 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqFhfG$B>F!NeL3Hhvf{EiZ5Nd z^e_1Eg~-imhDlo)ShVuK9ngIlpr5ERwLeczcx`h>>jb8pbxN!}d-yfJDmrq%sg66K z{4t@EMfs?mg6SDf%ZAolj!qYtob;4TPh`yNYTL(ZqW{M2AO`~jBOAkWPn~VbnfZl4 Piy1s!{an^LB{Ts5u;NDX literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_axis_f.png b/dist/icon/drag/icon_axis_f.png new file mode 100644 index 0000000000000000000000000000000000000000..2688e0580e1e059f7407b630f2b0d59491cbf6f8 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqCig<$B>F!NeL3Hhvf_=tva~x z`O$ib-wB;8%2x8Rw!&*`9g4XlJa~n24jL@5li1qu#bcRCko)6=50MQ*jhUI5|5qly mSQEKfLelNv2}TA+Hip(TvE37j<<|oZXYh3Ob6Mw<&;$Stb3Fq9 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_axis_pa.png b/dist/icon/drag/icon_axis_pa.png new file mode 100644 index 0000000000000000000000000000000000000000..43d3d75448a96e8f360c4874607d4fea2b71c538 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqHs?a$B>F!NeL3Hhvf_wafjS_ z^OHZhe8qHwNvGV+`#Z1MNo-Acpqrq$mdKI;Vst0QG7>HUIzs literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_bar.png b/dist/icon/drag/icon_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0aa55f99b5029b3020955c246b4e5aae3e0283 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqHIqW$B>F!NeL3H&0I^CF8#ZF z+f1DoOy6wvH$)X}aA}$-!#yKIR?B32Lu-_y;}%xW+4cfGFDmyj^(b5Ld3>~s6brfY zW}(IA(iPJU_#Rt0e3SFl`BAv4>xsn!gY0A($Da)I%iS4$85|lI8JJdxO|_EyavEqY NgQu&X%Q~loCIEB*NM!&3 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_bar_a.png b/dist/icon/drag/icon_bar_a.png new file mode 100644 index 0000000000000000000000000000000000000000..fc25739b1ef5ed21f1d35de18ac9a7de00a397b9 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq7Y9P$B>F!NeL3H&0I^CF8#ZF z+f1DoOy6wv19UciiDg=5eZ^bi{1YYPvV{CUhE-EfrKu+UhF{YoeE69aWNh2y6) qWG<-5PYCksJ$6uIfeZtS1Vhtyd9e)+TP=a+GkCiCxvX}1r7bW_klWg@NiHVk?=G7mhKCJsL zcG!2Tn#jgxRiU0AUkonZy6$sWn~&ot>oyAq_7{alQtU^LGcL3-n8p8MHh;lUZo{7p nws~%k6CNDAuzoTl6AuH6k+#et$CO1t%NRUe{an^LB{Ts5GKE1* literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_bubble.png b/dist/icon/drag/icon_bubble.png new file mode 100644 index 0000000000000000000000000000000000000000..745053b7cd0cfff8d380ba246f5df5a36566982c GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6H#21Z6t7srr_TS*BLtcx3h4s>`Q z+V{MbVL}xD5x#(h%nmXY8(bbS@4B_*th`i1i0zcy7U#nkFsdDIIbJm3;U|YXY)3x@ z7?vDnUC^fA{-`RYQp`ro!hzSWQ6iDBcLqO_T=!uCuNg;RMa54maZj=!Dry$Q#wqm-B!bzr#tb(f@!u4aduw0uJjtXEH8WFY@6RLxw_8QF6nk!pKjI zuZq|-{xV9q@O$(!vnf3~E-A+D@-!u5!+~Oz_Q>eN8HwgxZVU_@1`M)_emzD0W=nt} O#^CAd=d#Wzp$Pzx0);aG literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_bubble_f.png b/dist/icon/drag/icon_bubble_f.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e22f561bdfa10ea52e905462c348b3732b7d0b GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqPLzdjv*Ddk`g3X7c;QEsgB#j zo+xlzHT`^j(pN*lpoX&>Y=dJYG>dc<#l>Xy707k`Z_aRf^>J6q;l;s>4q0{r+zcPt z75I227+W(K$t+82TFa>H>6mi0^tUaC^G<`qk_*06Y5Zm~(zXBku3F$&8Y6e(1tEv$ z%(Y7e6w(tsate|o3fB093UvNvJUfa1fI<}m&muO3-EvyjEDnZ6PI#f<^f^!AiqMSI z#(*;0Nz4E~#&tnL^G`0V`yDba5lz!})HJ-wtqBwZOMs*RgxxLZj7!B3I`arEi6pYQk(Gx=y3*5S3j3^P6wX`VMfh^hw>;2`0DqPX~>`F)r{!0=rFjP&`)k&c`Q zh{|XX7x^%hUJL>m_<*Vzt#kbchMQ_dRL#jWFDe*mQJT)0HH(p96pS1I5MTgfE^lm^ Sn1&eu0000w(ySlbwk)9}pAfK-c#JDF-0_FnjkW0jkD9%i{eY2NXcLg`glJ+6O?F1-$&R zfI*z&6T_vCG7NgBs@5-gc#`484?c#MKlvDTo~m;A^5+mFe4ZLGL ztN^4y3LQX(gMc3Y6A%>;BYzTE>3$xTpJ2;p+_fW|OgY&YL54Q~nfIY#%CO|2IYZp3 z1cuT}!60rTh=1&@64+1>cnS1P<5h3sl4+hdKZvRa5#S)F!NeL3HEDXvW9(OO9RwLT3>efob?;;fh5iOw#Ng@b=d#Wzp$Pz>5F!NeL3HEDXvW9(Oup3*qn}R(kMNw&)4RuB472ZcR`YM zre0h7{QCX_772>38*TKpb9EKe*0~wq(pX@}z+u49U?+KL?MB;lpmhwMu6{1-oD!M< D0?9!W literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_dashboard.png b/dist/icon/drag/icon_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ebbc98ce3d7b917ae3a8e4bae40062204d15e732 GIT binary patch literal 865 zcmV-n1D^beP)x$oR_&Xwqt$u!MicXxM% zZCh-G##H-k?QCvt9-QQFH~|=-QM=uK(d~AV!{MM}u}DixOI%+nmFW2Rm@1XZ5&Iiq zfp%sJz9Z%_bMHFCmj@cvW7nS2Hvk zjkLJ9$oauwzyrY-7`g$FbEG9043g97q{_#))a`bsRtdlh?_TkPz!wQyAmCRRfkm=?Xr@I4qH>*Vafnj8o~wQ~Kn)&SiHppUD*na@`rh)@HNuUAeo^ zOr6}5+0XVv+RHwn!>?b4&ExUWHj|M&eNwi~yu* zVpti5U$MS%SCgr{X>1OteS$GE9$=pdZ|Mba%uDpMJs{V458Zzdp3sear7V-dU{C|> ziz(W{;6eqU5=62X4dgOQBc}xq8FV7mYBegC%X|m|b9~5s%VaV#>jRn19+?H>`z(u% z6^+m5^D?mXIysU`rFfa5*}$XRaGF>wrn{@7BArfSn)3gNM1o^Y1i(DU$c1yEP#~Af zMRRj=)5}nj$mjF%0PqEd_%@99K_r*Up~Y8}Zsc7l^5QNA!NoG)1M&1TJve%mB@%#7 rdT{>g$s7m%rzi7&Kl-OmzXTWnPqL{T&K!$1^{!6BQWgE$5XcJ1V-%?}XbFK8nE0ilDqXqVzpusDmo{DKrZIoYgE zU3E!Dak|mb@5&3b*SpI_aO;DQqnFq3z5Cv~caF2O8rw5{JR5)cSYn_Lbj9B5=~Ia1 z4Ojvxz`TN5%l8xr)355+Ee)6WXiDbNb&DK{igkFA>EGSr~Ag4~|xa^k@%~%&3|!8+55$Thr>1+rD5ENC*6w&td(I0YD%S!F zzu^1xiX9$5Cv+D$ap4;s#-@a5cJShXoSYC*^4 z7R18mLPcKt;D|!X502C=s|N?<+}YV*?N@*S0Gs7|j*-v*VE_OC07*qoM6N<$g3^)R A5j_o!xn1VO&y&Zxd(#G8ZA4u3%k1?gqVG4kF!NeL3HEDXvW9(OS+Nw<^b@rqr zJ#Luek*4T+`0)At?g=szL|i`YS+iwp!<8O0n@0`L#Cn*T7!(dLtW1_TvNXz9A80Fs Mr>mdKI;Vst01_ukAOHXW literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_line.png b/dist/icon/drag/icon_line.png new file mode 100644 index 0000000000000000000000000000000000000000..4bc87282bc9250545558e81f4ee2cac1473f969d GIT binary patch literal 504 zcmV*HiQbD2jW1WFAfmn0|g-7541=DkE8m5cp}ii2Otb$L&d-jggFwc z1wfZ?08$H}F2v^g1`rK2xB(^xW4lhh2eM>8)RDO30BA`e)HVHRhJ!Tb192f1y9=e1 zt`&gd1nNkFksJub2|!Dbli_@j@34inrSB33QQ3P87Z3Onmx_R{0EKNL$WTyx09~H| zWP`%C5m&tY`@=Hf+h=|Q^t^#HnZn}Z$2Xqy&`1o#mfnF50LMX}K^7?J9D(=&Q5g;D zlKF?4pqfMyUlUT_(X z;RB%I2GFDi(vS!X5}@HA%i^K&U;xd*51@`v1X}Qc6blr925-QZ{h<~bK$GQx;a#l5 ugD5R6O#!J0rU=ZMHH(p96bu>w5MTh$7L}xbb8qJW00007srr_TS*BLtjxR;nx+T# zJ#S^4V8wq#yy3>jgw7-EDV1tWvqU>KD9d>@>)hhMa+%>!g)W1Z0K=o74$o>+j#|XX zH>j{Yy578m>wq=z}bkah{Ne(VE^cj-a6^=by&F$bW@u=%bvy0js7M-@{7#qeZT^B?T>oVNh!*DZO zg^5`s?La1@=mFL*HVtQ+xJ4oY7<$~<_lPmXPT*L=q`BcpLxKRK?oEazA`4fhGI!eT zb_k1PId${GC${*Dj9&k_8~Jh+)F-hnkeGj(yD?(knh=(=2N(RXWbl368Q|>r$06WZ v6I-t0)k`V{H?A=k9?a-9|H0_cz{t>?9>JJD=SUzhKp8w;{an^LB{Ts5(ddvJ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_map_g.png b/dist/icon/drag/icon_map_g.png new file mode 100644 index 0000000000000000000000000000000000000000..8bedc486243e93b09e807f5f88a0a54e40d15a2b GIT binary patch literal 452 zcmV;#0XzPQP){RWIf zvH}wXsyhde_(fuLKIok9g@kP|@X!~e7f4_)@!Anz=#O2*@`+jlsOF|DUpkv8qZOD2 zerh1!)(qIt9DhEuQl6@*GrezA7N74Q^gTwLmc&zY3Z4~YrLy>ZTLTao$l6b=hQ>O- z3!wm8OEd(QthP$E=+tDvOiCV@8dDBtxJIv*%D7X2QWq(LV*?I3;}r5`N*n7glwAVs zIErZS?J_~60)HI4+MLNYmGA!nv|Ct~OjG1$XRx*=jm@uodnwcdjw#ngVP~SI8XUAz u3fU&lT6UQPbCu=(W%tZ={l@EY6<`1ciGBZytVbsR0000{P)G!Y~XhhymcolM!G7$_Q)#6VOWhQU6GU3Caj;K$!qW;K{QiV52j#0!c~) zFNkE-Z5=zl%Q;DYYK_;|F55eMT1}GDBO_aoN%ER(OJ}=zE10YyVv^Vb3+3}k@5a6(rg;ItBbZl|_;GUh^6n+R{q39QECAw!yp&Fvs_xjA z_u5BtCvX71iYxdBN-VIXR!lU>Ms*>Hb@Cc9aRt!&&J(f^39SjqJ_w3vl2sQMM;AN% zdw&)YnHx)?6O4?+^Nr_H9xQ+>$QyIoVAS`L9y5jgRQ=<_Y@qha2@w=oLb>Jz7ov^A zg3&>Z)dwFML0oJU g(#U_^*G+%{0Kx2eKc0f@>Hq)$07*qoM6N<$f|PW!OaK4? literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_map_s.png b/dist/icon/drag/icon_map_s.png new file mode 100644 index 0000000000000000000000000000000000000000..10955a52b2be476f6d4d2f9b49ac9fc278487751 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq9dLzjv*Ddk`g3X7bl1qBnhwC zar3jB2dBeMd8;elER9M38%>l${@G6uVtMr2WpQ6uohP_Izopr0L-Xp A;Q#;t literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_multi_pie.png b/dist/icon/drag/icon_multi_pie.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7f462696bfe0aac599d65ceaa33378eb46e372 GIT binary patch literal 625 zcmV-%0*?KOP)F4i03#s}shGZ8Sn07#t&;sTiAXutu8=l^|w{XP&IkYoYS z@cBThABY8r2nmqo=doGBgv0O#AeDeD_Ws*HhP^j_fbqX~ml*ziy34@u?-#O?1vgn) z4X%B;gJKB_jxeuB7TbFHJHyetKjHi`v5R2(?`t*&W^pS9CLURk;Riv%1;iJC*btu& zPz+yl?i-5XC;;e#f3Ht2ILY_}W;h6dd=Y@p0=VS;H-8w;J^F<&>=)E?a~|CH=JIa1FOFuZ|Z2<-ANf4?!j{P_kwbz$`ZN{aaaj96@d!>sK9%y5|4i(hZh zQx)NSfXn4cn?E=Zs~Fva4=CQ@!mxjVvN{LI<@;aVO0fshi7*KXHW6fX53pKbt-^5u z*%D(pHf)B&f+YcF2@f+DgE%{i1qbj2(FPbpQG|uT2x1Ak;V_W!^?s_olZa&^n)pVX zg&j1b-A8u$l}~>Uo_zWn-EanWW<~~AMK%T{LFNT)Jda=wc%a3jqKLONg%%Z{47Y%r zhY76l)6f45*WdnutKnl~1Q`sr1m+N^B^Q7eTp(Cn11(7a8qRfZ_Fqxcl?#;{qcsro7oJ4iB$lnSMcyjh>~WkxnY;RFsxRL~8?>==#G zt_CO^!r>Ab`$tDeMcZhk3^btPSF{~Aj3$6qH$iP!U|P;vo&yN^IEYO1AautpBe&2* z?lKr8UaXo>_%^_>{*El5Q8XaH;tbzwvPLT5n8|Zi{NdApr?27Sc7^z!gt*sqyIP76 z)oWFN>0>l~N4!)sJFDNZJ-Lz&uT^JmKET69#0O!&laaJ+IXubwCk6Vj*PhW(j1|9C zb;uOzP&1od$se)0+*k52Y&)6;xKA_ogar4zX_RGh`(O0YcZ=Tb!cU@54$9<+E?6)|0co?_AM zkRda$yHFnas<3hPB2goWnI+dl3PrESx{G>@L~26PD&AG@!N#uu0|1qBs>^-qK~4Yw N002ovPDHLkV1ltj?1%sW literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_multi_pie_thicker.png b/dist/icon/drag/icon_multi_pie_thicker.png new file mode 100644 index 0000000000000000000000000000000000000000..ec17cfa7a2aee71b64c15e43a7577713a9d373b9 GIT binary patch literal 514 zcmV+d0{#7oP)F6XfKtFnP{q6_20$_% zh(WXh6hDCC3qX93AxUNf=@!g;k^m&@p#~BHAj=wo7A+ub!MrB|Kyp10JCG3~ARh$+ zEqZ|60*K-Jp}_$LoXm_2I)bbWx`HeWoGb|C-~aq)xbyih!|B(*7{34gk8H{ZAa(>= zaskx>EQZ@jurs(zvx67@-pGcFb22k1^RY0npm~HJs6?8Jnc?A=zd-y4ET+uM0`v_Ba&Xzh zf~XLj%z()a6f7_x%)!K<&W~w0GLYwC24WTlM7)6=w*VT^i5Ob@u6zyvWh@pZh5$2B zcD#logHx}6eE#>M1t|hsjB}#<^>>L2*e9G%-TNSGJ^?^ z;Q>JEJ`nfA3`YY7P`Ud+3j;{90BAVK)$4&+fQV24saX%S#DORape~OSj}LxaxLlsJ`9r|p-+V;J6DbxfP*&#vxqSWG`(g1wOA5)c-~s`|VZma6$C3;9ELcc{ z;S2;US%}Yq1wj0P2*Z&r@dwh0Q2qy~8MsSRXi>4A2*XhvCZ;wAq?VyWy<`Ew;u>g) z1JG~<5{nJTdA?>2 zK~#9!v{lV(6HyS~e60y-XhI=Uq&3@%A1G|`pai5XIrL;Gc=DD=JV(KkAW1L1+MX>Y zJ%|^<690e(m8d6ED)k_mh(aM0lDdhhF(3XW%*u1k+D*`fAG162o0)y@&6|;=|NPjj zkP3x@AL1Sm1G2!aa5!AE;%m1MJPlC-=2=Cu#QM=!fB+OI1B8HOU=^qW0pKQ(0?I%f ztI1nVfWRRRObIr5JIZY9;oTcs^o+D!&q8RR|p8#G#FK?z{`=I z?8GBJ`LVxwnbO_?@m9}KR%ESl*}He?th+ihs5+oOPj=!FpZo^h4W~(U72kg!_qlA{ z*OSghA~@EJer);flVMuclo?sO;gGt)y|#B9yo*q4W@T!YU>mr)dl-22**>;&#$An` zI(D!^29gIIIrr``kkh)Z22@et#jrP-%Jdw)P>^=d))0;K&A}z+6-P-RO}XmP$k>(lQ57brOFS-wBS-!R1aBZ0!*GlS)B0je>{%Wua?bsAXEgAiH?a0J)k=vBAFtaR2}S07*qoM6N<$ Ef<5kv3IG5A literal 0 HcmV?d00001 diff --git a/dist/icon/drag/icon_radar_a.png b/dist/icon/drag/icon_radar_a.png new file mode 100644 index 0000000000000000000000000000000000000000..6c15e6f24be634092b7faa8092914d4b740c2f72 GIT binary patch literal 1124 zcmV-q1e^PbP)g(&1{}TsjJZ!O8E}6|{uCZ3BROC{rG>%Tf z&+GsVi!PTdmN&ZvY10Tx#rp2vQM&=ocGcki;=F{@VRRIKk{x3U!veAxlBg(3d{H(C ziRJR&WR}s{U^jC^o8Cm7xaLUOYfs;dGZNvPMdEm#ANKit1Lt03QhSvGhfTnE(|E~N&0N>UQ80g=Rf39oe+$BShphBCq2di`cPo%W+# zf3uxd4%EZ(ZjU(mb4e94>VeBwY5^yc|g|Jz zdD5u81FQzB=QvgeCe0W;Y<)$V-}ptSC{>YiV9_(G97Sc?G5T4ZEA_)~)&5g%lLMFi zs3#?p$@Ujb8^J5zZH!X*YwR5;RM+9kv5$dprzoywJ_DECMuv&1!OSbMvQog4qmbk~_9xrS-WvaHupsGW<{|Y}IPPCOi8gpj${UWDH@V7t-HI_%~@gS6F@r8Z?%$f?QHY zvFbvhQ|5SQX^HYSr0ILx_5;muRI7{$-|>^e)jMSoPr57P!G7=&R?N!6-3je+i)&pj zb>Lo#j)su3v$L~GE|)7HRMGk6KaeS5n$tS%liV}6OzmxNJj0Y1p@~P3#-7%j58Ctv q4Yr_$bEsAK`qx8q^pD1$0t^5H(!tdxZo!@a0000VNmY)QMl?9qle{!le!F#SY&>QrR>#V zUKxHM{fA9_Bb%6p^pYKNzW*4+3{!Si==3?U^ZIPzTNKFc*1-B8<<F!NeL3HiyK4|?tgw{ z%c0zD*vrPQSn6}dh(kOmdKI;Vst0Ku~`6aWAK literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_date.png b/dist/icon/drag/pure/icon_date.png new file mode 100644 index 0000000000000000000000000000000000000000..564de143c4a3dafb9c07f6ff449aca9c4cc190fb GIT binary patch literal 2876 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_detail.png b/dist/icon/drag/pure/icon_detail.png new file mode 100644 index 0000000000000000000000000000000000000000..0dd1c90829edba16087c2274ae2b4a949496fbd5 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj>7Fi*As*hzDGLk}mTdgV^JU|K zeb0~9NBww`(8;2FgI$5!K_)AT$yoR(lan2zWzz(y3CfAD3~C%aKCfV1Jdwx$>0t}e z-e)Nh96fGEftiepcc^)ZcXmBEYTEhBBgpS66W{E!CfgYpjEi4LCTTh60Ig*3boFyt I=akR{0I|_FTL1t6 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_image.png b/dist/icon/drag/pure/icon_image.png new file mode 100644 index 0000000000000000000000000000000000000000..5b134275c9df0c29702820a658793611699bcf45 GIT binary patch literal 409 zcmV;K0cQS*P)f!?6y1{%>r2nKH;H_#(M^Z>nqb;Z+-Y+XFYydp>_ zR0z=cb|f?3Z@!s%JcNM{4y+H`0q8EHA)JJ^j4KBMAU^tpWSajUaOyHRbaa^8IV=248}L}oVJ zETnm1O=-_~F!?pk@U<=L?00000NkvXXu0mjf DhQGGa literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_input.png b/dist/icon/drag/pure/icon_input.png new file mode 100644 index 0000000000000000000000000000000000000000..e51e61c026c23b61312ceff877d844cb9e346f85 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjZJsWUAs*hzDGLk}mTdgV^JU|K zeb0~9C)E^faAA6*5Oihon#LUNgmunl46!^j{d@Wyvo;)K)ZsW`C~!Avla7KV--TS& zC(N^=9ddr~U$$`IkI&KUd}N`Z+QYe0HYQb2@%p0E%}vvnZ0gA2_PFZN_3NU=0qLj@ o9%`ySo}u3JEflVXE?L3Ou#6!>vLrB82}1B`q*aklNZHkl^_2#`irx_!sd{^Dsyfc4s@0 z_2Fc4Xp670o}tqxogFa^XN`)U%~h4 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_list_label.png b/dist/icon/drag/pure/icon_list_label.png new file mode 100644 index 0000000000000000000000000000000000000000..c9cc73878c79a09a2f3199752e882080aedea8ec GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XyggkULn>}1B`h#Z*z&&e`z+@HzRu8l>_WF^Gsg>oMb0Rq_&VdB-$gMraN!A($5sW4m)vk$T oio7ao|2MhpEb$@Ww&wp4ogO))8Ocg?>;M1&07*qoM6N<$f+l%q4*&oF literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_number.png b/dist/icon/drag/pure/icon_number.png new file mode 100644 index 0000000000000000000000000000000000000000..ccba87f6c4be826a5de45572c9780db951fe5944 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjQ#@T9Lp;2bQx+H|EZO*zXR(+7 z&%;D9mv6TE|C;~QY;a*Znr=||**&)6B5!IgYy@i@q<6Xe%_C#ibw?4vAHNA z>~#c4nXI?eX9{|D!B#SG?F{vr7RkfhWbLRny~N0NfaL2srH;vU0_9MJMRHO-p+$~* zstVAZu*jzfdi<^}8Cpb>w^G6CbP!OzNKsGrc@QgMRsxF@jqad3MI#R$vdFS3DVVv* xdML(_H-6n?H)0v;O)2^U3}LwZXe8PH30_inOso(T0w4eY002ovPDHLkV1f)`W-|Z) literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_query_g.png b/dist/icon/drag/pure/icon_query_g.png new file mode 100644 index 0000000000000000000000000000000000000000..baa471d3e710780570ab1e10ab5c8e01d8d39329 GIT binary patch literal 223 zcmV<503iQ~P)D`lCoFh)`ESkLf4~9t<8 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_reset.png b/dist/icon/drag/pure/icon_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..fe324f55d5fb5c11d7adea00c01f3bf09550a6b2 GIT binary patch literal 256 zcmV+b0ssDqP)CAMy2+j{Wd0CCiln0000B>As*hzDGLk}mTdgVlfeC^ zI_}T%Ba50}1B}lL`^GZy#{AR2FulYr@s!+tyiHw`1YCc7X zCSLCG?wMf2ttXzaxksi_ElKndH(!cniM*gFdrOnxbgKzcYDvM&8`~c9C`C#5O<`@} zapx=Fb8a=1=$b^afGK~id8y3{fsYy{u-?#V?L7Ep(PzUL&Y%Ww zLp|;bSCxMk6+|}3E#A@8{?G2fR4)g;gJS9@G})%xoDqLuaX`%TL{iI>jWZc9J5OTW w@rXgq&p=+_%(N5@3EejwY_~E51bLJggw8CiWxTnE8R#$uPgg&ebxsLQ0KrH}6aWAK literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_string_list.png b/dist/icon/drag/pure/icon_string_list.png new file mode 100644 index 0000000000000000000000000000000000000000..d861da26c99c10a8d2d782e3ad6db6568053336a GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XB0XIkLn>}1B`q*a*z&&eW(0 zJgb}F_+4nDR3~rPuU`#f6KxF&89sCFtYooNVKd`fA*jB%&_IfPaiIgd{DnP!%PbdE e3NW%rFzh$bJNonej>$kv7(8A5T-G@yGywp!+B`h~ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_tree.png b/dist/icon/drag/pure/icon_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d4555ea37c7ce8d5abf3fe5ac344b37717a248 GIT binary patch literal 278 zcmV+x0qOpUP)}1B}lw#5Olfmeb0}6|BDBOINgeL6Bcddchgmn z73lil_?%g+sD{mJTg#6M-34g|8wF->T#@!NL#5yCQ-;cA#Yu&s{a5;CFJxw5;$ev6 WbV(>ETpA8Eox#)9&t;ucLK6UU|2t#= literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_tree_list.png b/dist/icon/drag/pure/icon_tree_list.png new file mode 100644 index 0000000000000000000000000000000000000000..c391a400bfb00beea8d12f954e9e62692de2099c GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X!aZFaLn>}1r7bW_Shkf_N8!-E=SS;ny7;Df7);7$6kc0v zkj412A)tldN`AwIQ|TL)oOODgkfdmqJTY67du5zl?~{uja=j^9KN!Lzf_G1mwOY&7 cz`)FK7<7|Kr0wLUHx3vIVCg!0FyO6YXATM literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_web.png b/dist/icon/drag/pure/icon_web.png new file mode 100644 index 0000000000000000000000000000000000000000..836dffbe6a95adba02c39b0e2d00ec2e9d8bb223 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjGd*1#Lp;2bQx+H|EZO*z=gYp_4`V2D<|HzyJU5SF8xxba378N@iu{WLrf$Lq4aC3`ZI>nIb(p{5P@w zmz0#|6YVxXRO`?HxE{1D>8eK;}g(sI9LOZgeLiyf1k5p%2-=tu@nS3j3^ HP6ReyNbu-<55dE%53zHsx!Zpo&?hPZtXHZ!DI=&>I-trU~! zrNMV%6T{8ZN0w<#kjv>i@_}*bQI;w#>8%Xe9Z9~+u5eVR7zcD^XG!<|{Lp;2bQx+H|EZO*zCxQD- zb=;r!$dU~%OnI7{EcDtR1n~aV#O0qU|O0oIR?*Ji&C~=8K;N9JwzT^V@MJv^_3juvz?&D>&&fON!vO zgu@#eE~#|MxwGghOzGNS*|8#|MQ+=ULlsw;dUi2|-))o$Q8~(JxiTw3N8$L=A72)T jT)$!_bJJ$lb}fe0%_gTe~DWM4faf(>$ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_year_m_d.png b/dist/icon/drag/pure/icon_year_m_d.png new file mode 100644 index 0000000000000000000000000000000000000000..697446bef0ada1f6cc814b233e5eceb13e0f733d GIT binary patch literal 234 zcmVEDEi{ayi}D`1Gq5t0$_g+MU^Uh1iL1#i*SsGQbh1qn3 kFx9yIu1AYgz3@}T2^rp4C=~6&=l}o!07*qoM6N<$f&f%yHvj+t literal 0 HcmV?d00001 diff --git a/dist/icon/drag/pure/icon_year_s.png b/dist/icon/drag/pure/icon_year_s.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed48d519f9eabf2ecbbbed4bebfffc542656dd0 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj>pfi@Lp;2bQx+H|EZO*zCxQD- zb=;r!$dU~%OnI7{EcDtR1n~aV#O0qU|O0oIR?*Ji&C~=8K;N9JwzT^V@MJv^_3juvz?&D>&&fON!vO zgu@#eE~#|Mxi=qX%4wC`SK}OFv{YpU+jQ0+uUKLZn(U}?@QX?K%4o^<@N#odOz`c3 fl+PLWRxvP4zw|>=X>FM+(CG}Gu6{1-oD!MB1Vtn%paLm3Yiu7Sd!RP3}@_N znskFvOe6W>L7`5z85$QZ{0%t!^+eY~lT8bGbSh%f`;UbmSjI7(k$a&OpU@_T)r=1B zbsRpOt6w3Z+?D5X!_Xj5iaR2f!NivFRV#CfBtvf)yG~ov5q*Ze!5xVV0gcQdmzibS zv=&Hry<>{lBd=i2Bj;cme?Y0tTP{6FjZMSh@@WR<1_ow^`LX&&wHkbRKu0rpy85}S Ib4q9e00yO1n*aa+ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_area.png b/dist/icon/drag/small/icon_area.png new file mode 100644 index 0000000000000000000000000000000000000000..af7c63778c0ba1bd76a4ce431046c560d1a5574a GIT binary patch literal 3353 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_area_a.png b/dist/icon/drag/small/icon_area_a.png new file mode 100644 index 0000000000000000000000000000000000000000..0d70bb70952712801a7e560592727b65565550c3 GIT binary patch literal 3240 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_axis.png b/dist/icon/drag/small/icon_axis.png new file mode 100644 index 0000000000000000000000000000000000000000..13f463165aac552b5a739be3139870c62be4cc34 GIT binary patch literal 3203 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_bar_c.png b/dist/icon/drag/small/icon_bar_c.png new file mode 100644 index 0000000000000000000000000000000000000000..b19ea86849c6798d45511ad1fca4c8c83117cc75 GIT binary patch literal 3036 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_bubble_f.png b/dist/icon/drag/small/icon_bubble_f.png new file mode 100644 index 0000000000000000000000000000000000000000..6ece1da63107506497ffeeeb4252e51e55f3e0bd GIT binary patch literal 3257 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_combine.png b/dist/icon/drag/small/icon_combine.png new file mode 100644 index 0000000000000000000000000000000000000000..8b9eccb7df0883501551408b4f97fae7e81feb73 GIT binary patch literal 3339 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 V-TCrdF<$@x002ovPDHLkV1k`OQhNXZ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_combine_m.png b/dist/icon/drag/small/icon_combine_m.png new file mode 100644 index 0000000000000000000000000000000000000000..197bdc0f077766c79a3213803ff6d917c44b763d GIT binary patch literal 3341 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 X+~nisKs*2300000NkvXXu0mjfNI7bA literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_complex.png b/dist/icon/drag/small/icon_complex.png new file mode 100644 index 0000000000000000000000000000000000000000..9be6fc6919ccaa9833f4070b9468bee1bbab2ad2 GIT binary patch literal 2999 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_cross.png b/dist/icon/drag/small/icon_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..ee8cdccaf4929f67a9f2c7e8832b061aedeaf00a GIT binary patch literal 3032 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 UM(Jk-DgXcg07*qoM6N<$g2U6pEC2ui literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_detail.png b/dist/icon/drag/small/icon_detail.png new file mode 100644 index 0000000000000000000000000000000000000000..e23eea1ff7b500d8ddc4d4106ff449c399393b1b GIT binary patch literal 2977 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 DY*;px literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_funnel.png b/dist/icon/drag/small/icon_funnel.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd250b83510e240bf0dc95aa0ac35c3a1fa8a72 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xws^WYhE&{2N|4Anz@hY}I!=W_lU3-eokfJw#s=0?jG61y zFE+Rd9AtT_qj2~u_X9SDxt|z3aupmuv#pS0n;|YS<*KC`)5>lase%UzQw}z%R4{g2 zXWq!bcvillg2_wgfWxI{{EQA-^BWk2pa0~_IgrJ`5pw6v!RKB4vaeJdPcZ33h&1lG z-ha5kX$>c5w>H;?9ZV^|Sr+jyG|DeuB{e}PT)90mn)#$AYeoknhcQnUgFpg9Yo4Cq U<#Sq}f$nGUboFyt=akR{0JH&IrvLx| literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_funnel_not_continue.png b/dist/icon/drag/small/icon_funnel_not_continue.png new file mode 100644 index 0000000000000000000000000000000000000000..7e3e9e25934a0fd54be2cbed98cf13db42ed8790 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XHhQ`^hE&{2N|4Anz@hY}I!=W_lU3-eokfJw#s=17jE{b* zNIl?Cn&H55VF|OtstGJ-TLWwb^basx&{han5xB62VTGljD$fMROV9Xuf0Ug6Eb1^Z z{h*jd#UW+EY@LKc))UenGY)Y#Zqs)N?>@`Qlay7w!F46mxsnDRt-Nnvm^GPY;&xnE z7#GxWxj}yUstuO1vN}%;vZEUk8A6OVc4`Wyad6L)m+mxiXiU7o(7?dVu;ztMe_QmT R2SCR&c)I$ztaD0e0sz9;T{Qpz literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_gis.png b/dist/icon/drag/small/icon_gis.png new file mode 100644 index 0000000000000000000000000000000000000000..b1363f9ffd906d600b85ccf551312756221935e1 GIT binary patch literal 3033 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 buAcz_Qr0(-n>r8^00000NkvXXu0mjfzK_8t literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_group.png b/dist/icon/drag/small/icon_group.png new file mode 100644 index 0000000000000000000000000000000000000000..4d8f776bf2f5042f0d90b25a20aaf089052285c2 GIT binary patch literal 2994 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_map_g.png b/dist/icon/drag/small/icon_map_g.png new file mode 100644 index 0000000000000000000000000000000000000000..b5326977f1ff31a5bc6529a7a8c3c97dfd1f6bdc GIT binary patch literal 3083 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 Y0Iv=!*A)lA7ytkO07*qoM6N<$f}J&|VgLXD literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_multi_pie.png b/dist/icon/drag/small/icon_multi_pie.png new file mode 100644 index 0000000000000000000000000000000000000000..922e66ffe2dcf57c306dd3c00c7a35effd8422a0 GIT binary patch literal 474 zcmV<00VV#4P)RCwBAV4x*9dgq4$5DVZ_!-z$b z0+6Z);sg+1mG{*FVYaUhK;{A<1Ffbgr$;vwa+Lt?ULs*autA}Zx4b=Gj z<6p4g7t!|&f8X9_`1JM3hDQpX3hWFF22iz$=w1i_yX5XqxMmpm!pO9toBhASjj#6% zkkz6a01oZ@Z~mZYzVt)nU=N=F$jJsTf4)IcixG(EfSHAH!wpUo{eOSiaYiMw0Utnw zq6iCIvw||a!oRf0TN&!%?hlqBN#Ne zR30F!MM+4|Xgtrz$Z&v(ol)W9t3L)$Km7yCN%Ju=7>Khlu(SMsz{d6b0R!XTL@geO zVT|ahkei38A32oK0LbZv1`=!!a35n1!#0003702}Fy)%-xj QtN;K207*qoM6N<$f}JzWIsgCw literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_multi_select.png b/dist/icon/drag/small/icon_multi_select.png new file mode 100644 index 0000000000000000000000000000000000000000..92c8c62d35213b66d73869fe24daac46ebeebccc GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X)_S@)hE&{2+VZ~g;sFN<8HPvP4mk~a2bqq1bl5YY(ZWE! zLv#W!o8*TF37ss4>k=4tnF)HlZ7;HCC{*H}^rX(FN}NeIlHmw@!z(q0pR5jdIG)%i zBr3?7G;u6=#+l&FdBf*~_wR{&Kgg$930x7r#8bkktRpsIZdpS}xPf5+$As8`{^nk8 zlLZnCpM^K6c<* M)78&qol`;+0Ix$?rvLx| literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_multi_tree.png b/dist/icon/drag/small/icon_multi_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..9ba37d1e38c14a1ab08cb189877c22d11ae424a6 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XR(QHNhE&{2N?0IZ(8Te3p7>vfQw+ZE4jmNgbdq3Sk!CwV z$RRlR1XF5*iM7Cn97Tck?vL~tq6!*2BbGCX<}(EK8eDJ8VKLmPp?w~0ssbEGm_^u?mc}{wvOi%_IvU6?kiej;YJAsC;L~oPn;AS^{an^L HB{Ts5#>Z8D literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_number_interval.png b/dist/icon/drag/small/icon_number_interval.png new file mode 100644 index 0000000000000000000000000000000000000000..414fe793071a82ccf50c224e163dc9d4573c7e6f GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xu6VjQhE&{2N|4Anz>$38`<@JjAa=fK9x@J(4l_i^XiQ^B z(RMg0$8c24z)|!&^U5lPGKWXU51(Os^fTb>UyrtL%|{{@n6WBYb7vGOPS9$R+9sc( zeZov(FT;uQhDa7B1@VSCb2`q}2TZqcxGKQY{NG`fU`8PQ0y+>Xmr295OG4;HD3Af0#*h_HU^cn%*PwA+8+S=kHOQ`&t;ucLK6Tf C%5Td6 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_pie.png b/dist/icon/drag/small/icon_pie.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c94b6f8c4e4df5cd63a095742f2e595b0c48a5 GIT binary patch literal 3217 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 O4hBzGKbLh*2~7YBcuK|q literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_scatter.png b/dist/icon/drag/small/icon_scatter.png new file mode 100644 index 0000000000000000000000000000000000000000..798a0cfbc133a3be9af0b80b5aab19858b555b50 GIT binary patch literal 2901 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 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_single_slider.png b/dist/icon/drag/small/icon_single_slider.png new file mode 100644 index 0000000000000000000000000000000000000000..a510bc55fcef9000dd874f2b62101b2b9db69678 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XPI|gHhE&{2N|4Anz>$38`<@JjAa=fK9x@J(4l_i^XiQ^B z(RMg0$8c24z)|!&^U5lPGKWXU51(Os^fTb>UyrtL%|{{@n6WBYb7vGOPS9$R+9sc( zeZov(FT;uQhDa7B1@VSCb2`q}2TZqcxGKQY{NG`fU`8PQ0y+>R1`wBcvP+8Km}qtT@x) rdXrV*UxV8A37H4>8hl_-IKXhdGwxi8=Sxwbrx-k4{an^LB{Ts5Ko@Kr literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_string_label.png b/dist/icon/drag/small/icon_string_label.png new file mode 100644 index 0000000000000000000000000000000000000000..0c2a79494f4b5ed7c7e6cd3fe9b718ff0cf83b8a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XiacE$Ln>}1ZFygL@qhzk0@I@kt}n-p8DclgkGZR`*M~=h zNlfMPht{Kw&8kA|AEX#qzOv{X&S$v5=2n#4xGRyN#FKf#T!s`a1kTu;pQc8oN;r<1DMTMt^qZd5{I1Cu>p4W_8w&>v&pzREvu6{1-oD!M< D)>=e9 literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_string_list.png b/dist/icon/drag/small/icon_string_list.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc2e0f5810e9f584843496a84260ee878c7cc89 GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X$~;{hLn>}1ZFygL@qhzk0@I@kt}n-p8DclgkGZR`SLcL` zO_sQv&cuj@)7&DAJGdLnEP_%PE^z;E3{jpE?eC#{!O2a8dBH6H3BtWsIGIh-uM02S z&S)zjc~RAq*CoIzg2O+th56#dWiJyLJ=p>#$!oANFtRah)mGf+>KgGB=mG{$S3j3^ HP6vfQw+ZE4jmNgbaGkkZ>w(sbrn38O~B1Rn1OwnvOAss`VfSE;Eu z#U(g&xk*SrnZ&BIV@|(V2mggRbq#B#bn!Bjre literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_tree_list.png b/dist/icon/drag/small/icon_tree_list.png new file mode 100644 index 0000000000000000000000000000000000000000..d00c4041387f5bc457e07b65e4b47fe42c371cb3 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XYCT;XLn>}1B`gpyXyW)iPyDaLDF)wnhYkvLIytdzaLAmH z#$FV2z-6U)g5HjXCzH4{l8!JZM7&Yg7P!b`(V-&3e}t>zi+PX?n@DwIYeVCWOYBAw zC!7w5Dx77i04hjiF!*YzBstANL4ZF%S8?KN)+;3rehNV{Ul|zL7=)CRL{Ao58~{3m N!PC{xWt~$(69CV8MqK~^ literal 0 HcmV?d00001 diff --git a/dist/icon/drag/small/icon_web.png b/dist/icon/drag/small/icon_web.png new file mode 100644 index 0000000000000000000000000000000000000000..a92c2475379cf92234908be41023b62274e501dc GIT binary patch literal 3058 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 A2><{9 literal 0 HcmV?d00001 diff --git a/dist/icon/drag_helper.png b/dist/icon/drag_helper.png new file mode 100644 index 0000000000000000000000000000000000000000..1552192b675d63a2e2b4ecab4808195194ae4777 GIT binary patch literal 3585 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 literal 0 HcmV?d00001 diff --git a/dist/icon/example.png b/dist/icon/example.png new file mode 100644 index 0000000000000000000000000000000000000000..9de26c690d55174a656a1461f9391328e99de0ed GIT binary patch literal 190645 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

      F8iz zeYFR|4X@mJJ1=#8->z$qg;-oZ-=%hn;FIF5yi_O@}{Q!g*XS|9uvx zs79x5OShrl{btDhQHTmU421jD+NCRB;C=wW7g7{>Dl4J;B`AwDHm|0d%uLAVIT!pq z9G4H{()p6~31pW*3T~aET<802`#n!BxuUCm298L`-r^NfRBN>X`O;hM$2GXjUGM!R z)q)lqyx^0;Ku9y-tJ(_>0Adpmc8CN#QA`-pOvTrJMGE8BC?{SRsvo2rxb@u41n~I< zrQ|q|u60~@zYY9D?Ba9tdyds~!Q&dYTfF%hAjJNW$NRYv#?STXxzpPRxHdx`k!Q5- z<{Ga3Hv$EJ*S8)x21-+wGflr8O>g<%I5twrtI4}aqv4DIqW=An7*Kb|gB#=Yb=s)+ zleu(c0_W5B*L#bZE@CxBJjRJuF*m`@me-bhEER%%HrOWt=G)Fu7D={LSKdtyw`}8T zMqTdV{Rs4Ap;}^xTQIj_Hmf!Up5CnPc$tMMjft@T9tU3YHbHajDKAa zu%8TpVp1a_y||vE=vgHU@oxRA=9VXB^WGaq4;M}75&BYAw6|Y&;q(34M-FKF zhy&C%pVjNk@4n`fm(nNWfAxK?+uyEwriMEzG<@&PpEVer#>7LrU(8nDz3!(a`rw*(ce?i!s_BSIL#ijZoVH(pDqUzq=aHR=Mu=QOI-~r~B3Ukcmxb z@A2&aA*|hf#~eTT)?=BMG5h>}&20xw&p-kPWHtJ}?1mF>H|~z^lIPcIFa7az8N>hu z^}WBvU%2*nT#29;LDqVG1v3d~OpnjMiL&4D{4o2j5l=8>`B)sGXSe=z_P1JdMo7?z z5pB+~7aIk?Mf4YcvwgkSLVGEZ-`#1cq37q%<8Z^jhL!^iCI)_&#P`R7-lww@-p^-$ zjw+uqaN7u&vJ%w8$CeSaLP^lXb3h&7PW?mq6f;tSE4z3d&HeNwAbn_qE*hPkt-BCp z*MTb_cr~<~pa|IdQ)E=Ls4Ke=W>ix@pD*DJ)MA<3H^hde7cOaY3odz2Od^Wp7ZzLv zh@lj61WHoyv>m(|S-r&07g-veq{E3QdOjHH39}+)N@|i*KBR*IJqp;C(S^k5ziIg*|tE zr^sX`ODt({m=cVs*yN@JEGB;60~T_=z&0sYsPth=Pc4u52%Am3TNvpEitzI{PPm;E zF09iPYDtxu<(h5Z)zQQ)ktZPBDeL&K*rm%c+(To|H6va%$^Clm6|m2PUpzMKC21P^ zTyF8Y@Z~MMW;=9`*)3Wfjx!s9GWYmGT#AW2u6|ieK=}FrS?fSR;dpUjPWibORgH4{ z5L>cFP*ORHwCK1nqCO2B-Pz{(-XELgW-CGzPgJYW{TBq&(w~-N_}Ul}`V0K-XAk@F z=Xl)qFrK;P0y5mFe@C`pJwE|KM!Wl^EPmP2Zw+JRYji1eIi*)FPx&RvL`|m&NlUK* zOK@5dA0dfG0h5-}spCD*8`E?W;w$d;PUBGL11iaPU8tmpp+3c-88%+<#)ed%Z^v#Np5`7^gN6TSI;RDD30Kz zH0ONKbR^|4vg|>$0Y&n`R)Gobx!`+@%o*ipkr3BUxM9OiNa)%+-;(uA$VytflKRXl zWXTfKsCglMFR~rknjERVI~X4$#FyvLV`_uK`il*qNpd>U(Vp_3(;$-PGt>3ou_NU+ zEwG7F9_&@2FRQ0VCr}WnHu|E$Whm2QExk{fz_O1-()0fys6EY!R%4Vt1#vDeWxW=uq%6oL~2ZuEM}1KeIs)X z4Ywq57?%!4)T!?u{LDU@cze)#d|fkC8^=!!&6L3-giXDCB;vFVZpEd!JffyN?-H?f zpm~+IvHSJIj>)PLf{GF5(w#J$bW~QelJn?~ZP3iPbOEX;z1n1Dn9pRz6V23(dBu;> z)O?4^6y;O@uHZ$30Ms^`20_;~B1{QNoA7s`8p>!E|HXTv`tJR~8 za=$b-EosFSTrQPD)PzCH88k1@4) zM_(ve19OCH#933nJ=TE#e=Ib}NTyQeV`siGD&lgke!%1`7*Wr~+oB(y0Er-*QhxWYzuE z9LS^_V`y|*%-^r1(7b*Vrf)#};BckO1(j4c#sCqk+neS+CdkWjBA5s=PY5HoL}i51 z{N5MaHdf-i^2YtpK{vP5*fEm>@R z`d+btMi`ndq|cu((-Pt8R)aWuu5aeHdj<1?T&Py+E;C8Bna$TFKGO3C&TsdO*(^r3 zlXDfrsJL$q>Td}&xS44QxSB3@t9tEl3Y4IVu-z51qSvgrT>A?O%W~9}JC4D;69Z}@ zr30}Eh)l7AslV(rLWndWk2DB>3oLZc|MFfq;(WsT^XDNl1GCc9R7|dY43_f^rw3UV zx-gVsLPXtOuo|SMN8krPcN016AK|kzj|HAywJQBb3p6=OQLR)-x~@M3@T&6F@65Xi z1*kt5f9o!lmTv*tVlZ$=(ID8hnXWbLm2On8UImv!y)d-{vb6cc; za0ZrWg!z9Ij-f_5`X}W&o8L*hx=Z}rx#GgKi3jrXH4>VNpTu;mEDnDI5UH{+^08OHDlwH^y-%T(jVTG zss-uwOA&R>V&e4`M~0`?w(76e=s}04KbIK3g_WDBs#n@Y*rr#|`ddupui+5I>8q*{)VpniCKIrpnQ3PBl? z3B2$Jy-Fp`4>xdR>*7Oh`=zkx26z_K4ef|>Hvc2xHQqr~ueEjP!*z^8k5R-7 zD7G7LgxD2WKM0(E`lpxc8$-l;>hfgUTd{FwZ$rIGy~W`AYD=Fa2`%g=PpRjz`Wg-bI#^{;Bir1XVGk-5j_N)yyD)#RjXsI59` z+S0Zq*N#TL?ZxxTWp$HH1Z!oxoP2YItI4U`Jx7zBAy)^f0luiT->t<@1G$pEEH2LI zdYi$}Oti8FtPdgpa3fh zUiWshNwsT!1T(62Z0?r5R0V>T`xhfJyOp8tXKxyQ2rhhvP~i71hRqxci8*C2YVeLC$BVq&*dYEqA$xExd|6?HFf!rNEb%Dz4M?}vN= zIrA@f z;s!5u{e|jgoKs1g=70Z6k*l<=nB%8crJ)YdvvF@65b5G8Fw7 z%41gy)nL{eld^_5#H?IPK8 zb*W&Kn;$?)Y7${#)R%nyR^4cEBAcjPdK(^N$c;`xB0^+?LLr5g5H>LMp$OZLAalLi zNL_?JOHkP!i89YYmd)NMV5=+`rTE8x{DSTqES2gKu@Z4G%7_P#J)k6QvIcjHl}!>~ zMH<-SNh{bFycP%`sIC1A)q{q z)UD3hOP6$nmQggzC4Q?!8|~h6)$V9SB}WxZ*bT)GE0pt0d1!g*LPXM9w)s9D=15XK zsvSv(G*_4z?igJZjDsEZ(YSpKfmpt%h4#EpL z9H_8e>;I)ut~|6=7?TPoK?jq`L2hbSAiPwzjaZw!? ze9EMEV02V-r%8hK>K&1(!mQkq%o_xv?_r%9O)ZZUWI+zk)j^l;9!=Ph%J__ZLH=9* zE^t4Qwfyl-(nrzQ0UyD~y0n&Sa!!*!j_8lE!SFmqqAIIc=xvH=B!M~22Exb9O|aZ3 zVcfzh(OAo96RY=B<8+J`+cafR*f8@#nn;RmYvN2Y2S*?)6)U~>OtdH%m8dBO*kH+E z{LIY#LP?<_lqfJor$Ds(%);u=pp>s6oJ$k!&_iFkew!yh^M>;MpoS?j!iJDm}A~X#=9XDjnE|8G4+p~kH>mPB{o;b_ zscIVCi5dzX?vLLE1l?&5=GfdRavQzl6zoLlVCl)NAuv61x-_` zWm;F01b@WE=Zy2}yOh{qK2&;sDAow@rwb<&Vx&|z`cl12&SgLw8aFhA@+>Sb>>sf= z?u;>rFgPAM4)v#&><9VoBux2DYer(E8Mf4FZW1iQO^T0xo+sd_4spuD3&IFI{rr(d zYb-$&0hXwb{soJU^Cp}B8_v|7m{#5Me3-0ClG?iRO6_GvP2AqIr2o-!Rij4*C%61N zj9FG`;awGEUgZul2aLpbDdl%X=!^wsz2T)aNw>4Hoy(2DvQ)5f$BeZaW>ZU$7{UsT z*k#^0-dHASLv~J?X&RfRej?11i`FO*!?q+T$!|v!jyY2emh51W6`ZzwGlA7RTP3jr z^R_BmVcOPHjby>PpR}gn$*H%M+RX+uZr=1xXEcIVD{(ftGY!O?)V=`5q|kAkj#ll*t>YOLI)W6c zY#-uj|8Fel((-)aPc2~xyd^R`?PAuhvphkO1KR7nmmC6$%J43`~;wNUzKc7+7sJ9T9^6&!{v?<8!R z@&cBULLO%VA)y1=#gn{;c2jt47l%Mp1XgQJN_Na9;_7v@^~lTh@#63YQSnQIgb88c zuJmy^F*bT8XGQzwv^G;bF}Zow{zyZJfE&tc^F`s%^bMjwmtv_VhUw$W;DA(BX;^Yf zh!z!kV`73^GC<0AQpb>=!#WIQzg`d=EZtQHTG5?#_en}&`Z|0U= zN~cAYBf!h+%yvK_qnMT?YeER}jM1wK`ml_nVW~A`!qIR!NFk9TFK^D6JY-0r+hE&R zGY}Hyd*YrI^Cr$3c?v2Z;xvepV&+(Yf`J5yh!Os*gYrAdq?h0IhYJi({G2m6IppY% zUn1WSPZpU?PHpMzO@a@Ti;4VrtZ`tl(d(4j_sq!@8kpoaqSY46GYkcA`z5L|FK*?i zn&6)7h7wWLU+N}*QWExQM<~G*>4N3^;@m2eCZ~Dnr1NaH1somH1{MWXe=|`SYqdJ_ zPs1}2nOa%T{Q2A%4u?ZwGg`2FFbk2B7IPCPD@N{97HAoYLSC%$t-semS&Ugk1GdOi zC}QC|B*kbHegQcvCuI;{t@96opsbWk`2_e3chcxP@sv`kXq5c^%AXUSS`|5AbS$oz zyM(zqyj>JYp18O#w5t63y>RLoY_B$7Z(I!o@L_;q7xn2fA!C@(jx9#6H!#m2M!%4vZ~NXZqU#ONJ?Dm2FW8~ zV9EE-*Fb=UBh*A3$_tzz?zW{iJY?EdHhhH_(R|tdpcN7<%X!ivwPgD6NIj z2VxM&&iAS;rs)OxY!L+O983|>%1KKq5%kID*pZU=tvDtv;#QB_q<9-%lvG z=#W_UwOH5?w5dwijC!rcA2WO>;t=3w+E6QAIi2>X8fej!(yk-8H{sDyGD^9ilVEqU zLzrQ;j(x_8aL*kMfWUy(T1ESStPWeh7Eobd|yL;f6Ip%cY z%qV>EET`4h^XZNl&SYXJ}ag@y@l&<9=UBVt#_EO<}K z^WcNXjAH@B+zi(K|~r-gGD-pjBY~M34*+wE2)jS|*f6VG7u? z6fDFsBl}G-sM9;MENT+r5G682P&~||(p0GSYJrYTprbQE`{7Qj7=A+U)NP}IoRVn$ zm`is&0s^a-koln|#$cAzh;fU?V#})V{m$em18=1_FrtG$2X+Cv7oeWk1|;uzZ!cB#~(|khGCEo)py$(rE4o6{M&+&o)C5EqHvxTNpg-omkJG?vFbsvOtkyD1x2ZO z2Jfl}e0kXwO~ejiu>FS4e9%M(j`B2Vso56BM+_|+U8OYC3T~{QuYleTysLCcLn47h z4%|GEtvF`}a-bZF2iyqGs1nbln`lWy`*09IcQoSA{x04}@>fn}3AwnjYKTIanO5Ek zYBsZ^NG+`ew3j9bkw_H+yzB~2y}tCe(3wI$0SaBzP($7BdP@*U5CV(jwq2>C&iDQ? zyVGai;&Taj)gBhSlMgbA?k?=O^bgCXu^4dU&a$2c(c_WvW^1(<@@hL95Q=|EIY%L3 zkM6@y239;G~TPcZUfQ0`AB-3eK~o^SuFR_*|rmc65o`TdBO(&vs$CEXT)_ zIZe4t=f{$%^(5L=QaB?RSqguzgPUC@{dSJ=33heFgO8P4^l(GI_c<>`aWZ8@Yb|I} zK}h{zeyV+cdibq?9zZ6A##|o^B0Fvx|M9WYHy>KX3xOo3&{kzT`NE1`BG>74wg{XH zg`QqiS$XXe;mFFA#~p@7#e*2>`uvQ+)Hb7sjYNpz|4Ys^ddG*|?{0I!X3(kwqO{}F z83EzTF)7T4h2wPCbQg*7tc%jmw;Tc z%T*USl$Xqa-1{3bVga8)}0zIG_ z0avq4c(!i|4dD|f@ZQ+60#LCFkS1Y=B36?bPTUjH$QxfG1dF03iawj&m;5cUovsKY zZCm=S;$V+xLj4RFE_CYLGhl^*$`zE!Rm*RPG&Y7clpi5|(k^EWF?OVBh(!EcPJ1aA zfm%9vT#QXSACUXQiaBgvcc}wX8~4jS)9oHePgTJh#pm1#Z;i}5xq>zt*479%-~>;h zogdRCL2h8-3_`wI?7gmi5*58D%aKb{Aj+`c*dkrLA;a$v#@^wXTI;MAEEI)4Im%*? z`a~}u-mZNTjwJ$JRJe9X?OWg%v&B_vzW4mIh9KoqVEn$sk!Whv=}gvbI)aqoE1$)M z%WqHMI6PM*b$EOX{%qLcZWm9q>0~Js7G!P~nZ3ogWH9?BVgO<2b%u3=ZXBB#PM>|f z(6zpx_~CMO5kSPq=LJx-z3;aOgpZ;IpaXCL{ck^HB~x2*K=P5iXB@Gx6OI)pJQlO( zO&>JiOM=_KSZrJ9?t05==J4FAcROzeyfA@hXZK#wA-^{}JS;uQ(#E^E_o?Nyx_+dR zO^n17bvaL_uDjc%Qk;h2U*qzdpFJD)AU2!%k8ZPIGen@Eyi{C2JrO!*ZW~vW7phnK zw|@n_DH23~US4(d4YH|;#2*BOtoQ$(%(w4k%H}oB(&!JUUk_?yju4qU#iUr)-h(~` zb9mYVhZ!V#&z2k1SAc&3G2z%$GKGDeYQg?69?ZzukmTMLKs*v^`VPR&|2Elg)2R_8 z;XylpASyBNS>5z1YWQU~8nwXf-Z8P~ZvVXcn@MHZP^divCI>ZvU9>@%muO$Oo4~&M}Bbp0xrDXv|$Nd%#&c=MuT|b?w|M z_9F%|i={aSFar-p>(LePc*!`!d=W={8{7SbiPh||{W*f~px5kbz2Dg>>2(=~gez1Q zuasBGLzfGtw`|EjVV5U-v>%XVb zql!S-xHz3P#JrCnpXCx+^LoxlQhsqGgoB(4d-$#Sa;`3*5@?g5B%|X9JG|cc=A$L! zyk-yGbxYhY7j3BI+s}&Ph4vtrQrYzEl^hW_rFWPpsp87dv%qw|^)4%^r{Z!ec3T_- zD)xM|ai|?}gx>oY+&$dKGrt1REj+H7R8{gXPeQD}%0t)5Ii3Dk?F$(Zf~W{HxC@sf zQ@fV_8`)rXBC1YVI7|2{l*rQ=?$W0X!av*1-x5oNo(8{SaoH`#&AkAn0%BvDd=3jJ zw2b!sov_~2z3*6o9pK9w{S%PWXnX3?DfZzz$L}%aZSfUJWZ_pOn~v}xWSe;TD3o04ok zJ*SFqxdF0sHdutUx_d{1I^>eNW8_!-D(5Ky{zgX%u(3tO{bRlUv@%x|X@=Hnpy2*g z5CScFL5U`_#S8-B6scl@x5u$~SJ?9Pkq8qWN5GquoejSSX#n_wZvaX_J}0kGFL|9^WYee@4JWLn9rWn4jtgFvI`j2Ga6E_7fHVg8POv z0%`iIIIt}+qwK^L8Nh7x27U^5An))(MCF!{(gq?%hZFf)-TX30(g=en7`#amJSLzu ziPUdEQht$d#R)MjOd_MsRj|C>)pt3XMEx_0ZPV=6^!o31f28I4FnB2D-iPqwb8kMr<2s>;Ew2V~Koh6Wpbpz_!l1<0CV=tGZpu4%yJJHR+ zwqOewI+&8SFTv=9B2FAfEc*@PpeaiK*OlBw$xFv?@@q62A zaJ%X{&f9*?^%>Ve`IbQe>yeT?a6%$p=cJI1E~JjO6Bwsh9>5I;mK-LrgaIkZ;r(#3 zO6<2-CW9`o-mTqQ=k1nKS+n0uj?@wCq|bC&qF0I=A+>sWGkS^4OQ=E0%PS~2W7|Wd zTF{?Bs%Q&%gm=TQo;){hoo;>pGHf<|h)mgE5Oa4<)hu&uq;JE5=v!5A` z1u}t-cge#Cq6C0{3eo13px2%Fhc_aFMheZuEr-;K#EKr+{DRN(g^=sbZ2O;V+%(VY zkLR=H+8)cV?j!lEZb2tmARIvwffyAd#0F4G_dI|6>3A$NpoCOH`MGZen!V&-bPU~O zxHO*Hz1{5hZW`aVX+Mt;YoV+rnhftbL-#{x_I~{oKR?@KTj1G~$f%^X4w?QOn`Jt$MaHvI$iKZ_sToTtYN%Qf1%N*Rpk znO1rHF??QR9meRTKO6h0=tfYYEA6Ek!(rs2dhadVD|+F7!9a+DFo2H5Ikg3<v-f>pmobj`Nhu!7&%Y}l#5hK- zVGy`svda{g#z!v>MvQ84vWpeIzlF=HaXvnO|Mh2n;}D5P_Mity7+|sxp^3@y`%ZtQ zbPGYNASb}!vp8-49&l|V>`UQSOnJR7p2}dVBpWhoOv;w&^^w6hVnbp;?V^W_e=hky zc)aTmYO86Fxt=GXfj^SVA0K1!R*CWPF?r+g%Hb;XAS*WX8aM?02`6y^r^c|zQP}pt zU>_&vH>fA0mmN^1RI7N;tvT*_+MdE#mB;TrL<=flbEs?z9 zO9-UZ+niA>R@pKdV302?6FW7nPzwnI;xiLF4v(t^w3Jp=AXyS&euJHW!nS%0AOLP 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 literal 0 HcmV?d00001 diff --git a/dist/icon/half_selected.png b/dist/icon/half_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..298dd91a64573983b1217cd9cf2414db90fed104 GIT binary patch literal 2881 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 literal 0 HcmV?d00001 diff --git a/dist/icon/icon_down_arrow.png b/dist/icon/icon_down_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..b77c3309045e2e000764e46990b449f20bd344da GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xay?xfLn>}1r5s@X_y4~>!xEl`AI!?ik6GD*7%woi{}HcqhOkJsw3 ysZ0=Bz?d=X{A6M6-xGNX7N|rOx=A}UFfs(aex_siB#8-VF@vY8pUXO@geCxO{XCFT1cO%%jO7g6imZE7S8Hr~V8DF1zDtII z>Hpa~CpOLbctvlICC?OZx621sFuTbD)dsTnSS4IxY+mf>wBjq*s_U807@Xdg1$4KC xo&9#v#NZXfqUfVXzI;5v+QWR;mYu_ZA>xVr+$>|6-9UFSc)I$ztaD0e0sv~~T}S`` literal 0 HcmV?d00001 diff --git a/dist/icon/left-join.png b/dist/icon/left-join.png new file mode 100644 index 0000000000000000000000000000000000000000..40f3a324ac620181b46557a585cdff1d1e811f48 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNC@5Lt z8c`CQpH@ym+MOSnzI+Rf$Ow2?nnk7|R*BO@)N)3cmdK_+P}bVNwiJ z(VoV6a(+L#r|b1DYYb%Xu}ZkYxR_6(^uP*cHqYjkfW^(1+&JUd1+um`N16PP5?!1L qRA7=n?QqokElfSkcWv1@3>fx0DHr~U^EUuGiNVv=&t;ucLK6VxMpiZe literal 0 HcmV?d00001 diff --git a/dist/icon/loading.gif b/dist/icon/loading.gif index e8c289293b11c889703d83dce6631fce90da4630..d04fdd21277e90469d8ef930254c69b23dc75bea 100644 GIT binary patch literal 1810 zcmZ?wbhEHblw*)%Sj58c|Ns9pXU@!=IWsLS4ajDI0mc8^ey$r5%(GQ`zk9!uLS~AsQn;zFfp39xYDT6>~zjAN>wn`Gt*5rFf&&$x70Hx^| z#0uTKVr7^KE~&-IMVSR9nfZANAQKal@=Hr>m4GgVcpix%w4} z1^R}12Ku?VAb){X7ncO3BAkI$b#X{#L8^XGYH@yPQF1C!xiU;MFzoPK1X2iejg@~< zCNNSGb6oP1OLJ56N<3X`m4GsODVZr&mKG+)X~yQ3x@jqC#=0iPX34siNr_3i=H^Cb zCP@a#$wr1IFmtf!H?=f&GO%zmHM2A~GcP;hnz$GU=sZ(?$09!O9V z6j2a=yQCInmZhe+73JqDfJ53U6N@W|3jv7!6mmmQALuB3P;x;^J}@C*nglW7nE}Xw zXQ$LWU>+(0W){Z(|Nj2@{p;tC@87({PcxqRv3h4bgmo;iK$# zu35cm<%;FYmM&SmXyJnS^XAT(J!|HS>C>i8nLKIYg#NzXp6;&Bj`p_Jmgc6$hWfhN zn(C^`it@73lH#Jmg8aPPob0U3jP$hBl;otug!s7FnCPg;i14t`kl>)e0DnJUA8#*D z4|g|L7iT9&2YWkP8*5;4GdD9eF*Y(Z(AU$|(bm$`P*+n`QC3n^ke8E{k(QE_5El~_ z5f%~@;OFDz;pXDxU}s}xVP*mrIf_47SUDJ27<53T5~#ppV9xf~b?2YKDbLk=!#I47 zKj2|7iBk@1Fw=XgG%tA7rum-^ZB$z`t2Ta9@5`f}tTHYWiYhO@RB2ox^5~80lHg@! z-92UD2O1vSn9!ujP?+#kb;;uA9#uSfyU%7=9IlIB{HP|cP@*xqHKwDptCJI9KMMmZ zgBXJ#(0(J2T{?#hoYY^}@J72%m$+rtm?TiUFvZPLYu|>gTANw!RK&Vl$o+Si_jYSA zL&rhaz$r-HU}a!u5M>Ym8l&SOvhbh4HnI6DHm_Qp`7}zSFXgAf84aE{3Jd0K+qNL{ zz6B?P<;KrDf~8G64T~QUcmM2)S?f@ zZU?2$_8Z&~YItoU*vByEhl1AQ3q>}jsz^R!2l_|==okiOeUDut2L*O{+)g%5`jW7>m>%!z643vChKE^Xx4=Em45eu~Q&^Bgg##KY#=uyS(sR=gpKMMC>(~HuZzg@ru69Sx24i;|*pgzv}adI52~O!5RRo Cf`a1! literal 381 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 Dl)1NK literal 0 HcmV?d00001 diff --git a/dist/icon/no_auth.png b/dist/icon/no_auth.png new file mode 100644 index 0000000000000000000000000000000000000000..757eee805169713df38c523fb16f2c9b53e2bf84 GIT binary patch literal 1864 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 DB?pu~ literal 0 HcmV?d00001 diff --git a/dist/icon/radio-disable2.png b/dist/icon/radio-disable2.png new file mode 100644 index 0000000000000000000000000000000000000000..f5a71f34cabc811841e5490eeaaf17598a26c3a6 GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|+Dr7srr_TSsWZRl)t zI?$w7@a0D#tHM==Ba9Ab_(lJ59FcZ-bZy!+{s~u&m8uz6++^^Ob-2{Q=fGykz`L^{ zk>ScS?g|rS=_H0?&LRmDfrT>}S1n_VmS9m>J!$gP)Cp53GH#Z)uRQeO#m8i}oUEA_ zeA<|2q?MTMit1WCkyE$e0mGA=oSc%aClVRDo>xe)KS?*KH(szZ^?(?+d}qN|_a_kz z(hR-f>`ZM3gf20!Y2@%tTySNFz}W@;0fx*^LOLc+VOKF{Vv%5A5_35a;VCi;=r0CO LS3j3^P6%09yO+j=Ip2zSOJw~&J0!4G*P z5@eZdgr4-QX!G#tIly53*Ll_x&HqpHYd8!TX1!c4yeMq_E}-ujJYD@<);T3K0RY*+ Bi*o<~ literal 0 HcmV?d00001 diff --git a/dist/icon/real_time.png b/dist/icon/real_time.png new file mode 100644 index 0000000000000000000000000000000000000000..0a27475b563af9b4b34c2ae87acd634c0c288c08 GIT binary patch literal 4802 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 A4FCWD literal 0 HcmV?d00001 diff --git a/dist/icon/right-join.png b/dist/icon/right-join.png new file mode 100644 index 0000000000000000000000000000000000000000..27540b6fbc152c7b1c94dc736cf048f07dfc9592 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNC@5Lt z8c`CQpH@CFT1cO%%jO7g6imZE7S8Hreyx99+#FByK z-|U?eQ_UZ*jIH?E^u+!0ffdYdvOtxA>^)WqR~VZYJ36iS%C%~H<}(JTw`Bp{ZFksC sW=KhtGK9{0y5$^e5A$7Hb`ArE&n}AGYumqm1Gun zRwfsqvvcbr5RQS``at2*k+GQW$pAQoeod}j87Bn#pp<&bvaAw9Jo?sIYyIAJovNzp zjl9&jCIk%SJy}0n=yRUuFGW$XG)=u5-1j|enufJ)d$I6Wd+F2qbuK%1^jJWqp-?b5 z2j?LUY1e4n^6 literal 0 HcmV?d00001 diff --git a/dist/icon/slider-normal.png b/dist/icon/slider-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..8a611ffc9c6dcac5b568adfaeb1bfbc25466fb87 GIT binary patch literal 425 zcmV;a0apHrP)+h#?>6;X#}R{`i=y~Qk|bA3UH8seYyI8#eUaz+ z7hBY9RH`sdgDGW?Xkj6vn&&7nhKY|I;=+>wq1gQ zXCD@h*A+_PcAF&sPUOb#-$b zZJI{7!m$qPQHOYHSh6IO5sL%(>Kifk;{u`uZzKbrB!;ac43NWf literal 0 HcmV?d00001 diff --git a/dist/icon/table_style_1.png b/dist/icon/table_style_1.png new file mode 100644 index 0000000000000000000000000000000000000000..6fb6e2cda1d372854d25030f3599b623a8272c7f GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq6AMD$B>F!Nq_$Tw`bO66lU&a zJgb|)D41Cte?etVnx(e^-(Ll(Ut$JMpBdL0F)Le$+Wz@7J45!-e$=3JZn}IIl0)eMVNs_g5g`DhU!1rUHw427(8A5T-G@yGywqb CYeX6V literal 0 HcmV?d00001 diff --git a/dist/icon/table_style_2.png b/dist/icon/table_style_2.png new file mode 100644 index 0000000000000000000000000000000000000000..0c216d52cf14b2a4e71ddb8221a285ff0fc9ada6 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6Jlq6AMD$B>F!Nq_$Tw`bO66lU&a zJgb|)D41Cte?etVnx(e^-(LkOwTU$!uPRGP>K{D7a4I7_@9y7z?f?yQsgunInA`$f zV)oYdtGTvrTP5^3Lrconb;@$3V;8;V3ovjPFhp#=)Wwm&I1OkQgQu&X%Q~loCIF1P BL3scG literal 0 HcmV?d00001 diff --git a/dist/icon/table_style_3.png b/dist/icon/table_style_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8bd26632929e3530177355b86fbc752907c25431 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-g=C3q zL`iUdT1k0gQ7VIDN`6wRf@f}GdTLN=VoGJ<$y6JlqKTd^jv*DdlK%YvZ_ljDD9qf; zcvd%oQE+|y{$o;p>+NdN1cV zFrDPQC`s~~PIOPOvEt8PzpC6eu*UDNJDPQ{IbB~;WXX|2DF=^vvuDpPG@0b?pq0cB z`9Yq2N73td^)(F>Y)-tn=pm<>dND)h0W$+58$(Lia)Wz4%Xoo~WAJqKb6Mw<&;$S% Ckz7;& literal 0 HcmV?d00001 diff --git a/dist/icon/test_fail.png b/dist/icon/test_fail.png new file mode 100644 index 0000000000000000000000000000000000000000..0e4b1917eba3f27019aefe1833d661c18c1d18c3 GIT binary patch literal 3724 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 literal 0 HcmV?d00001 diff --git a/dist/icon/test_success.png b/dist/icon/test_success.png new file mode 100644 index 0000000000000000000000000000000000000000..0c6ff57918222e186cbbaf4f5517e1026456ac92 GIT binary patch literal 1201 zcmV;i1Wx;jP)gBfpJH;|IxOC)$$f?#6Zpf1BEI8Pr5wAgsmQ%EI2#V(w!g z8@;LXea$_+sjld;K=b4kfSi83raF!pJZQ@PT7 z5lo4A2FTv+Emw*&W%!;A55t3K|6lU=Fdkbh_Tfg!OoBT1pRnhXJEp zFb$)CPi2dbX=-zBWj||4bD9PWkd#bI^aXJ+VF4&T#cIOmNp;2|okvPY}T(?F^BW^4W^752F0-penuT5Rq( z1O6oqlYvU{a-`#ChzhHGiXk(jYM9H08}U?i?-dx!X=s(k{E(r!C6iHMf??6?a__~t z;?$Uu@3?ONzqf8QYp2xwwRD~lRPqE zm|H4LwGQzRpu4eMQS#C2c=||BU6P?iac%u(d{!7snPSi9V6|kXEbK0MJ_E9mvx8g! zs0PA_o&}}<3R6+)glQlZL!QyYe$cbROV=QbG#QvU%dRG;YK5^VFw0aiopbMhQOx!ziw8UBW@FovOF z;e@gi8%QGAkr5+dL)hmSUz=u6hPlZsE-Te=EoBoAP@G~qNRoY`v2Fezj@@eakg|4< zbUhC&6SZ&vPO_T&Tp&*bYU|^Q-3viS#Gj&!F0{5j+_}$WWBtteM}PqUx9?KPQZDiC P00000NkvXXu0mjfa&<8E literal 0 HcmV?d00001 diff --git a/dist/icon/union.png b/dist/icon/union.png new file mode 100644 index 0000000000000000000000000000000000000000..0085abc0e294196395910cf68740830127ee075f GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNC@5Lt z8c`CQpH@pEvgCvu_FKH?+Ul2>upRsE(BHqTF_68- z3amz=^uP+{h=i+;8Y~~YpX|Q)>?fd9nsY&xjK+Z<|Nl39J15D&#KX{IBG#*T!ipPc OHG`+CpUXO@geCy~rB3(& literal 0 HcmV?d00001 From c407eb91cac2b8cffbd24fb279f6a86f862cafb3 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 15:46:21 +0800 Subject: [PATCH 10/19] add --- demo.html | 2 + src/css/base/segment/segment.css | 1 + .../base/single/editor/editor.textarea.css | 1 + src/css/base/single/text.css | 1 + src/css/lib/animate.css | 4 +- src/css/utils/overflow.css | 1 + .../toolbar/toolbar.progress.processor.css | 1 + .../dynamicnumber.sequencetable.css | 1 + .../listnumber.sequencetable.css | 1 + .../treenumber.sequencetable.css | 1 + src/less/typographic.less | 3 + src/less/visual.less | 175 +++++++++++++++--- 12 files changed, 169 insertions(+), 23 deletions(-) diff --git a/demo.html b/demo.html index 20808e0f0..42110f141 100644 --- a/demo.html +++ b/demo.html @@ -8,6 +8,8 @@ href="./dist/core.css"/> + diff --git a/src/css/base/segment/segment.css b/src/css/base/segment/segment.css index f00f80ed6..11ddb87d9 100644 --- a/src/css/base/segment/segment.css +++ b/src/css/base/segment/segment.css @@ -2,6 +2,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-segment > .center-element { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; background: #ffffff; diff --git a/src/css/base/single/editor/editor.textarea.css b/src/css/base/single/editor/editor.textarea.css index 8544a6b47..150d4a224 100644 --- a/src/css/base/single/editor/editor.textarea.css +++ b/src/css/base/single/editor/editor.textarea.css @@ -2,6 +2,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-textarea-editor { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; } diff --git a/src/css/base/single/text.css b/src/css/base/single/text.css index 0128c7c7c..34613e8aa 100644 --- a/src/css/base/single/text.css +++ b/src/css/base/single/text.css @@ -4,6 +4,7 @@ .bi-text { text-overflow: ellipsis; overflow-x: hidden; + overflow-y: hidden; white-space: nowrap; word-break: break-all; } diff --git a/src/css/lib/animate.css b/src/css/lib/animate.css index 6f71778c1..05756ce92 100644 --- a/src/css/lib/animate.css +++ b/src/css/lib/animate.css @@ -2201,14 +2201,14 @@ } } @-webkit-keyframes zoomInUp { - from { + from { opacity: 0; -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); } - 60% { + 60% { opacity: 1; -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); diff --git a/src/css/utils/overflow.css b/src/css/utils/overflow.css index a8687e25f..c7feb6550 100644 --- a/src/css/utils/overflow.css +++ b/src/css/utils/overflow.css @@ -36,5 +36,6 @@ .overflow-dot { text-overflow: ellipsis; overflow-x: hidden; + overflow-y: hidden; white-space: nowrap; } diff --git a/src/css/widget/base/toolbar/toolbar.progress.processor.css b/src/css/widget/base/toolbar/toolbar.progress.processor.css index 552b25476..85df88113 100644 --- a/src/css/widget/base/toolbar/toolbar.progress.processor.css +++ b/src/css/widget/base/toolbar/toolbar.progress.processor.css @@ -6,6 +6,7 @@ -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; + overflow: hidden; overflow-x: hidden; overflow-y: hidden; } diff --git a/src/css/widget/sequencetable/dynamicnumber.sequencetable.css b/src/css/widget/sequencetable/dynamicnumber.sequencetable.css index 059def484..fed0aa1c3 100644 --- a/src/css/widget/sequencetable/dynamicnumber.sequencetable.css +++ b/src/css/widget/sequencetable/dynamicnumber.sequencetable.css @@ -2,6 +2,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-dynamic-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; diff --git a/src/css/widget/sequencetable/listnumber.sequencetable.css b/src/css/widget/sequencetable/listnumber.sequencetable.css index bd987fced..dace5ccd1 100644 --- a/src/css/widget/sequencetable/listnumber.sequencetable.css +++ b/src/css/widget/sequencetable/listnumber.sequencetable.css @@ -2,6 +2,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-list-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; diff --git a/src/css/widget/sequencetable/treenumber.sequencetable.css b/src/css/widget/sequencetable/treenumber.sequencetable.css index 616a45cfc..be1c1be2a 100644 --- a/src/css/widget/sequencetable/treenumber.sequencetable.css +++ b/src/css/widget/sequencetable/treenumber.sequencetable.css @@ -2,6 +2,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-tree-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; diff --git a/src/less/typographic.less b/src/less/typographic.less index 4a2149c3f..f2cb38f7e 100644 --- a/src/less/typographic.less +++ b/src/less/typographic.less @@ -9,17 +9,20 @@ } .overflow-auto(){ + overflow: auto; overflow-x: auto; overflow-y: auto; } .overflow-hidden(){ + overflow: hidden; overflow-x: hidden; overflow-y: hidden; } .overflow-dot(){ text-overflow:ellipsis; overflow-x: hidden; + overflow-y: hidden; white-space:nowrap; } .user-select(@select){ diff --git a/src/less/visual.less b/src/less/visual.less index 0e943dc42..8865353bb 100644 --- a/src/less/visual.less +++ b/src/less/visual.less @@ -1,37 +1,49 @@ -.text-shadow(none){ +.text-shadow(none) { text-shadow: none; -moz-text-shadow: none; -webkit-text-shadow: none; } -.text-shadow(@x, @y, @blur, @color) when not (@x = none){ + +.text-shadow(@x, @y, @blur, @color) when not (@x = none) { text-shadow: @arguments; -moz-text-shadow: @arguments; -webkit-text-shadow: @arguments; } -.box-shadow(none){ + +.box-shadow(none) { box-shadow: none; -webkit-box-shadow: none; -moz-box-shadow: none; } + .box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; -moz-box-shadow: @style @c; box-shadow: @style @c; } + .box-shadow(@x, @y, @blur, @spreed: 0px, @color, @inset: outset) when (iscolor(@color)) and (isnumber(unit(@spreed))){ box-shadow: @arguments; -webkit-box-shadow: @arguments; -moz-box-shadow: @arguments; } -.opacity(@opa){ +.opacity(@opa) { opacity: @opa; - @opa-ie:@opa*100; + @opa-ie: @opa*100; filter: ~'alpha(opacity=@{opa-ie})'; } + +.transition(@transition) { + -webkit-transition: @transition; + -moz-transition: @transition; + -o-transition: @transition; + transition: @transition; +} + //渐变 -.gradient(@start, @end){ - background: @start; //不支持的用这个 +.gradient(@start, @end) { + background: @start; //不支持的用这个 background: -webkit-gradient(linear, 0 0, 0 100%, from(@start) to(@end)); /*old webkit*/ background: -webkit-linear-gradient(@start, @end); /*new webkit*/ background: -moz-linear-gradient(@start, @end); /*gecko*/ @@ -40,49 +52,170 @@ background: linear-gradient(@start, @end); /*future CSS3 browsers*/ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='@{start}', endColorstr='@{end}', GradientType='0'); } -.border-radius(@radius: 5px){ + +.border-radius(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } -.border-corner-top-radius(@leftTop, @rightTop){ + +.border-corner-top-radius(@leftTop, @rightTop) { -moz-border-radius-topleft: @leftTop; -webkit-border-top-left-radius: @leftTop; -moz-border-radius-topright: @rightTop; -webkit-border-top-right-radius: @rightTop; - border-top-left-radius:@leftTop; - border-top-right-radius:@rightTop; + border-top-left-radius: @leftTop; + border-top-right-radius: @rightTop; } -.border-corner-bottom-radius(@leftBottom, @rightBottom){ + +.border-corner-bottom-radius(@leftBottom, @rightBottom) { -moz-border-radius-bottomleft: @rightBottom; -webkit-border-bottom-left-radius: @rightBottom; -moz-border-radius-bottomright: @leftBottom; -webkit-border-bottom-right-radius: @rightBottom; - border-bottom-right-radius:@rightBottom; - border-bottom-left-radius:@leftBottom; + border-bottom-right-radius: @rightBottom; + border-bottom-left-radius: @leftBottom; } -.border-corner-left-radius(@leftTop, @leftBottom){ + +.border-corner-left-radius(@leftTop, @leftBottom) { -moz-border-radius-topleft: @leftTop; -webkit-border-top-left-radius: @leftTop; -moz-border-radius-bottomleft: @leftBottom; -webkit-border-bottom-left-radius: @leftBottom; - border-top-left-radius:@leftTop; - border-bottom-left-radius:@leftBottom; + border-top-left-radius: @leftTop; + border-bottom-left-radius: @leftBottom; } -.border-corner-right-radius(@rightTop, @rightBottom){ + +.border-corner-right-radius(@rightTop, @rightBottom) { -moz-border-radius-topright: @rightTop; -webkit-border-top-right-radius: @rightTop; -moz-border-radius-bottomright: @rightBottom; -webkit-border-bottom-right-radius: @rightBottom; - border-top-right-radius:@rightTop; - border-bottom-right-radius:@rightBottom; + border-top-right-radius: @rightTop; + border-bottom-right-radius: @rightBottom; } -.border-corner-radius(@leftTop, @rightTop, @rightBottom, @leftBottom){ + +.border-corner-radius(@leftTop, @rightTop, @rightBottom, @leftBottom) { -webkit-border-radius: @arguments; -moz-border-radius: @arguments; border-radius: @arguments; +} + +@sideHeight: 6px; +@sideLength: 12px; +.solid-triangle-up(@color) { + width: 0; + height: 0; + border-left: (@sideLength/2) solid transparent; + border-right: (@sideLength/2) solid transparent; + border-bottom: @sideHeight solid @color; +} + +.solid-triangle-down(@color) { + width: 0; + height: 0; + border-left: (@sideLength/2) solid transparent; + border-right: (@sideLength/2) solid transparent; + border-top: @sideHeight solid @color; +} + +.solid-triangle-left(@color) { + width: 0; + height: 0; + border-top: (@sideLength/2) solid transparent; + border-right: @sideHeight solid @color; + border-bottom: (@sideLength/2) solid transparent; +} + +.solid-triangle-right(@color) { + width: 0; + height: 0; + border-top: (@sideLength/2) solid transparent; + border-left: @sideHeight solid @color; + border-bottom: (@sideLength/2) solid transparent; +} + +.solid-triangle-top-left(@color) { + width: 0; + height: 0; + border-top: @sideHeight solid @color; + border-right: @sideHeight solid transparent; +} + +.solid-triangle-top-right(@color) { + width: 0; + height: 0; + border-top: @sideHeight solid @color; + border-left: @sideHeight solid transparent; +} + +.solid-triangle-bottom-left(@color) { + width: 0; + height: 0; + border-bottom: @sideHeight solid @color; + border-right: @sideHeight solid transparent; +} + +.solid-triangle-bottom-right(@color) { + width: 0; + height: 0; + border-bottom: @sideHeight solid @color; + border-left: @sideHeight solid transparent; +} + +.triangle-top() { + position: absolute; + width: 16px; + height: 10px; + border-bottom: 1px solid #f5f5f5; + + &:before { + position: absolute; + top: 0px; + right: 0px; + bottom: 0px; + border-bottom: 10px solid #ccc; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + content: ""; + } + &:after { + position: absolute; + right: 1px; + top: 1px; + bottom: 0px; + border-bottom: 9px solid #f5f5f5; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + content: ""; + } +} + +.triangle-bottom() { + position: absolute; + width: 16px; + height: 10px; + border-top: 1px solid #f5f5f5; + + &:after { + position: absolute; + right: 1px; + top: -1px; + border-top: 9px solid #f5f5f5; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + content: ""; + } + &:before { + position: absolute; + border-top: 10px solid #cccccc; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + content: ""; + } + } \ No newline at end of file From e1ca98c4bb6bcf1f2e216ecab4fd7902abc0f0ae Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 15:47:39 +0800 Subject: [PATCH 11/19] add --- demo.html | 1 - dist/base.css | 34 ++++++++++++++++++++++++++++++++++ dist/core.css | 1 + dist/core.js | 4 ++-- dist/widget.css | 4 ++++ src/core/func/function.js | 4 ++-- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/demo.html b/demo.html index 42110f141..ffc2d3dfb 100644 --- a/demo.html +++ b/demo.html @@ -21,7 +21,6 @@

      -
      diff --git a/dist/base.css b/dist/base.css index 867afd467..534ea1ebe 100644 --- a/dist/base.css +++ b/dist/base.css @@ -73,6 +73,37 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ +.bi-bubble-combo .bubble-combo-triangle-left { + width: 0; + height: 0; + border-top: 6px solid transparent; + border-left: 6px solid #009de3; + border-bottom: 6px solid transparent; +} +.bi-bubble-combo .bubble-combo-triangle-right { + width: 0; + height: 0; + border-top: 6px solid transparent; + border-right: 6px solid #009de3; + border-bottom: 6px solid transparent; +} +.bi-bubble-combo .bubble-combo-triangle-top { + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid #009de3; +} +.bi-bubble-combo .bubble-combo-triangle-bottom { + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #009de3; +} +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ .bi-bubble-popup-view { -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); @@ -736,6 +767,7 @@ li.CodeMirror-hint-active { /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-segment > .center-element { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; background: #ffffff; @@ -931,6 +963,7 @@ li.CodeMirror-hint-active { /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-textarea-editor { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; } @@ -982,6 +1015,7 @@ li.CodeMirror-hint-active { .bi-text { text-overflow: ellipsis; overflow-x: hidden; + overflow-y: hidden; white-space: nowrap; word-break: break-all; } diff --git a/dist/core.css b/dist/core.css index c533d6120..30b90d3c5 100644 --- a/dist/core.css +++ b/dist/core.css @@ -9745,6 +9745,7 @@ textarea::-webkit-scrollbar-thumb { .overflow-dot { text-overflow: ellipsis; overflow-x: hidden; + overflow-y: hidden; white-space: nowrap; } /****添加计算宽度的--运算符直接需要space****/ diff --git a/dist/core.js b/dist/core.js index 918dffeab..eeff4ed0b 100644 --- a/dist/core.js +++ b/dist/core.js @@ -22117,7 +22117,7 @@ $(function () { }, getTextSizeWidth: function (text, fontSize) { - var span = $("").addClass("text-width-span").appendTo($("#container")); + var span = $("").addClass("text-width-span").appendTo($("body")); if (fontSize == null) { fontSize = 12; @@ -22139,7 +22139,7 @@ $(function () { position: "absolute", top: "-9999px", overflow: "scroll" - }).appendTo($("#container")); + }).appendTo($("body")); this._scrollWidth = ul[0].offsetWidth - ul[0].clientWidth; ul.destroy(); } diff --git a/dist/widget.css b/dist/widget.css index e7217f5dc..e8ed9dbd0 100644 --- a/dist/widget.css +++ b/dist/widget.css @@ -205,6 +205,7 @@ -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; + overflow: hidden; overflow-x: hidden; overflow-y: hidden; } @@ -1324,6 +1325,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-dynamic-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; @@ -1353,6 +1355,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-list-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; @@ -1385,6 +1388,7 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ .bi-sequence-table-tree-number .sequence-table-title-cell { + overflow: hidden; overflow-x: hidden; overflow-y: hidden; -webkit-box-sizing: border-box; diff --git a/src/core/func/function.js b/src/core/func/function.js index 6fbcfa0e3..b59c8eb32 100644 --- a/src/core/func/function.js +++ b/src/core/func/function.js @@ -298,7 +298,7 @@ $(function () { }, getTextSizeWidth: function (text, fontSize) { - var span = $("").addClass("text-width-span").appendTo($("#container")); + var span = $("").addClass("text-width-span").appendTo($("body")); if (fontSize == null) { fontSize = 12; @@ -320,7 +320,7 @@ $(function () { position: "absolute", top: "-9999px", overflow: "scroll" - }).appendTo($("#container")); + }).appendTo($("body")); this._scrollWidth = ul[0].offsetWidth - ul[0].clientWidth; ul.destroy(); } From c223d6c178ac236832ac6cc8c8f565211e0d14f6 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 15:47:53 +0800 Subject: [PATCH 12/19] add --- src/css/base/combo/combo.bubble.css | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/css/base/combo/combo.bubble.css diff --git a/src/css/base/combo/combo.bubble.css b/src/css/base/combo/combo.bubble.css new file mode 100644 index 000000000..0c7ee8d0e --- /dev/null +++ b/src/css/base/combo/combo.bubble.css @@ -0,0 +1,31 @@ +/****添加计算宽度的--运算符直接需要space****/ +/****** common color(常用颜色,可用于普遍场景) *****/ +/**** custom color(自定义颜色,用于特定场景) ****/ +.bi-bubble-combo .bubble-combo-triangle-left { + width: 0; + height: 0; + border-top: 6px solid transparent; + border-left: 6px solid #009de3; + border-bottom: 6px solid transparent; +} +.bi-bubble-combo .bubble-combo-triangle-right { + width: 0; + height: 0; + border-top: 6px solid transparent; + border-right: 6px solid #009de3; + border-bottom: 6px solid transparent; +} +.bi-bubble-combo .bubble-combo-triangle-top { + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid #009de3; +} +.bi-bubble-combo .bubble-combo-triangle-bottom { + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #009de3; +} From d927eb54a6333f82818e2dafebfc10dd39880627 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 15:52:09 +0800 Subject: [PATCH 13/19] add --- dist/core.js | 127 ++-------------------------------------------- src/core/base.js | 28 +--------- src/core/cache.js | 98 ----------------------------------- 3 files changed, 5 insertions(+), 248 deletions(-) delete mode 100644 src/core/cache.js diff --git a/dist/core.js b/dist/core.js index eeff4ed0b..859c9f544 100644 --- a/dist/core.js +++ b/dist/core.js @@ -12883,7 +12883,7 @@ if (!window.BI) { ; !(function ($, undefined) { _.extend(BI, { - version: "4.0" + version: "2.0" }); var traverse = function (func, context) { return function (value, key, obj) { @@ -12906,7 +12906,7 @@ if (!window.BI) { //Utility _.extend(BI, { i18nText: function (key) { - var localeText = ""; + var localeText = (BI.i18n && BI.i18n[key]) || ""; if (!localeText) { localeText = key; } @@ -12954,30 +12954,6 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, - createWidget: function (item, options) { - var el; - options || (options = {}); - if (BI.isEmpty(item) && BI.isEmpty(options)) { - return BI.Plugin.getObject("bi.layout", BI.createWidget({ - type: "bi.layout" - })); - } - if (BI.isWidget(item)) { - return item; - } - if (item && (item.type || options.type)) { - el = BI.extend({}, options, item); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && item.el && (item.el.type || options.type)) { - el = BI.extend({}, options, item.el); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && BI.isWidget(item.el)) { - return item.el; - } - }, - createWidgets: function (items, options) { if (!BI.isArray(items)) { throw new Error("cannot create Widgets") @@ -19726,104 +19702,7 @@ BI.RedMarkBehavior = BI.inherit(BI.Behavior, { } }) } -});/* - * 前端缓存 - */ -window.localStorage || (window.localStorage = { - items: {}, - setItem: function (k, v) { - BI.Cache.addCookie(k, v); - }, - getItem: function (k) { - return BI.Cache.getCookie(k); - }, - removeItem: function (k) { - BI.Cache.deleteCookie(k); - }, - key: function () { - - }, - clear: function () { - this.items = {}; - } -}); -BI.Cache = { - _prefix: "bi", - setUsername: function (username) { - localStorage.setItem(BI.Cache._prefix + ".username", (username + "" || "").toUpperCase()); - }, - getUsername: function () { - return localStorage.getItem(BI.Cache._prefix + ".username") || ""; - }, - _getKeyPrefix: function () { - return BI.Cache.getUsername() + "." + BI.Cache._prefix + "."; - }, - _generateKey: function (key) { - return BI.Cache._getKeyPrefix() + (key || ""); - }, - getItem: function (key) { - return localStorage.getItem(BI.Cache._generateKey(key)); - }, - setItem: function (key, value) { - localStorage.setItem(BI.Cache._generateKey(key), value); - }, - removeItem: function (key) { - localStorage.removeItem(BI.Cache._generateKey(key)); - }, - clear: function () { - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - if (key.indexOf(BI.Cache._getKeyPrefix()) === 0) { - localStorage.removeItem(key); - } - } - } - }, - keys: function () { - var result = []; - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - var prefix = BI.Cache._getKeyPrefix(); - if (key.indexOf(prefix) === 0) { - result[result.length] = key.substring(prefix.length); - } - } - } - return result; - }, - - addCookie: function (name, value, path, expiresHours) { - var cookieString = name + "=" + escape(value); - // 判断是否设置过期时间 - if (expiresHours && expiresHours > 0) { - var date = new Date(); - date.setTime(date.getTime() + expiresHours * 3600 * 1000); - cookieString = cookieString + "; expires=" + date.toGMTString(); - } - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - }, - getCookie: function (name) { - var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); - if (arr = document.cookie.match(reg)) - return unescape(arr[2]); - else - return null; - }, - deleteCookie: function (name, path) { - var date = new Date(); - date.setTime(date.getTime() - 10000); - var cookieString = name + "=v; expires=" + date.toGMTString(); - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - } -};/** +});/** * guy * 控制器 * Controller层超类 diff --git a/src/core/base.js b/src/core/base.js index aa33e64a3..3b0656e96 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -10,7 +10,7 @@ if (!window.BI) { ; !(function ($, undefined) { _.extend(BI, { - version: "4.0" + version: "2.0" }); var traverse = function (func, context) { return function (value, key, obj) { @@ -33,7 +33,7 @@ if (!window.BI) { //Utility _.extend(BI, { i18nText: function (key) { - var localeText = ""; + var localeText = (BI.i18n && BI.i18n[key]) || ""; if (!localeText) { localeText = key; } @@ -81,30 +81,6 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, - createWidget: function (item, options) { - var el; - options || (options = {}); - if (BI.isEmpty(item) && BI.isEmpty(options)) { - return BI.Plugin.getObject("bi.layout", BI.createWidget({ - type: "bi.layout" - })); - } - if (BI.isWidget(item)) { - return item; - } - if (item && (item.type || options.type)) { - el = BI.extend({}, options, item); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && item.el && (item.el.type || options.type)) { - el = BI.extend({}, options, item.el); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && BI.isWidget(item.el)) { - return item.el; - } - }, - createWidgets: function (items, options) { if (!BI.isArray(items)) { throw new Error("cannot create Widgets") diff --git a/src/core/cache.js b/src/core/cache.js deleted file mode 100644 index b529bfeee..000000000 --- a/src/core/cache.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 前端缓存 - */ -window.localStorage || (window.localStorage = { - items: {}, - setItem: function (k, v) { - BI.Cache.addCookie(k, v); - }, - getItem: function (k) { - return BI.Cache.getCookie(k); - }, - removeItem: function (k) { - BI.Cache.deleteCookie(k); - }, - key: function () { - - }, - clear: function () { - this.items = {}; - } -}); -BI.Cache = { - _prefix: "bi", - setUsername: function (username) { - localStorage.setItem(BI.Cache._prefix + ".username", (username + "" || "").toUpperCase()); - }, - getUsername: function () { - return localStorage.getItem(BI.Cache._prefix + ".username") || ""; - }, - _getKeyPrefix: function () { - return BI.Cache.getUsername() + "." + BI.Cache._prefix + "."; - }, - _generateKey: function (key) { - return BI.Cache._getKeyPrefix() + (key || ""); - }, - getItem: function (key) { - return localStorage.getItem(BI.Cache._generateKey(key)); - }, - setItem: function (key, value) { - localStorage.setItem(BI.Cache._generateKey(key), value); - }, - removeItem: function (key) { - localStorage.removeItem(BI.Cache._generateKey(key)); - }, - clear: function () { - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - if (key.indexOf(BI.Cache._getKeyPrefix()) === 0) { - localStorage.removeItem(key); - } - } - } - }, - keys: function () { - var result = []; - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - var prefix = BI.Cache._getKeyPrefix(); - if (key.indexOf(prefix) === 0) { - result[result.length] = key.substring(prefix.length); - } - } - } - return result; - }, - - addCookie: function (name, value, path, expiresHours) { - var cookieString = name + "=" + escape(value); - // 判断是否设置过期时间 - if (expiresHours && expiresHours > 0) { - var date = new Date(); - date.setTime(date.getTime() + expiresHours * 3600 * 1000); - cookieString = cookieString + "; expires=" + date.toGMTString(); - } - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - }, - getCookie: function (name) { - var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); - if (arr = document.cookie.match(reg)) - return unescape(arr[2]); - else - return null; - }, - deleteCookie: function (name, path) { - var date = new Date(); - date.setTime(date.getTime() - 10000); - var cookieString = name + "=v; expires=" + date.toGMTString(); - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - } -}; \ No newline at end of file From 208c832597ba594a325f34ac22d4d86c2964ee4b Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 16:06:48 +0800 Subject: [PATCH 14/19] add --- demo/js/widget/demo.multiselectcombo.js | 8 ++++++-- dist/core.js | 6 +++++- src/core/widget.js | 6 +++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/demo/js/widget/demo.multiselectcombo.js b/demo/js/widget/demo.multiselectcombo.js index f1441fa7b..e725573e5 100644 --- a/demo/js/widget/demo.multiselectcombo.js +++ b/demo/js/widget/demo.multiselectcombo.js @@ -45,10 +45,14 @@ Demo.MultiSelectCombo = BI.inherit(BI.Widget, { _itemsCreator: function (options, callback) { var self = this; var items = ITEMS; + var keywords = (options.keywords || []).slice(); if (options.keyword) { - var search = BI.Func.getSearchResult(items, options.keyword); - items = search.matched.concat(search.finded); + keywords.push(options.keyword); } + BI.each(keywords, function (i, kw) { + var search = BI.Func.getSearchResult(items, kw); + items = search.matched.concat(search.finded); + }); if (options.selected_values) {//过滤 var filter = BI.makeObject(options.selected_values, true); items = BI.filter(items, function (i, ob) { diff --git a/dist/core.js b/dist/core.js index 859c9f544..38b9bea06 100644 --- a/dist/core.js +++ b/dist/core.js @@ -14518,6 +14518,7 @@ BI.Widget = BI.inherit(BI.OB, { this.options.invisible = true; this.element.hide(); } + this.fireEvent(BI.Events.VIEW, visible); }, setValid: function (valid) { @@ -14663,7 +14664,10 @@ BI.Widget = BI.inherit(BI.OB, { }, destroy: function () { - this._unMount(); + this.empty(); + this._isMounted = false; + this._parent = null; + this.destroyed(); this.element.destroy(); this.fireEvent(BI.Events.DESTROY); } diff --git a/src/core/widget.js b/src/core/widget.js index 541c98699..54de57d74 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -220,6 +220,7 @@ BI.Widget = BI.inherit(BI.OB, { this.options.invisible = true; this.element.hide(); } + this.fireEvent(BI.Events.VIEW, visible); }, setValid: function (valid) { @@ -365,7 +366,10 @@ BI.Widget = BI.inherit(BI.OB, { }, destroy: function () { - this._unMount(); + this.empty(); + this._isMounted = false; + this._parent = null; + this.destroyed(); this.element.destroy(); this.fireEvent(BI.Events.DESTROY); } From fcafbde14c7785f5456941b1a43bdf2000f0f00a Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Wed, 22 Mar 2017 16:39:01 +0800 Subject: [PATCH 15/19] update --- Gruntfile.js | 3 +- demo/config.js | 2 +- demo/js/component/demo.treevaluechooser.js | 39 + demo/js/component/demo.valuechooser.js | 29 + demo/js/config/component.js | 15 + demo/js/widget/demo.multiselecttree.js | 14 - dist/base.css | 58 +- dist/base.js | 40 +- dist/case.js | 14 +- dist/core.js | 645 +++++++++++++++- .../base/third => dist}/farbtastic/marker.png | Bin .../base/third => dist}/farbtastic/mask.png | Bin .../base/third => dist}/farbtastic/wheel.png | Bin dist/widget.js | 728 +++++++++++++++++- .../third => dist}/ztree/img/line_conn.gif | Bin .../base/third => dist}/ztree/img/loading.gif | Bin .../ztree/img/zTreeStandard.gif | Bin .../ztree/img/zTreeStandard.png | Bin src/base/farbtastic/farbtastic.js | 4 +- src/base/foundation/bi.message.js | 2 +- src/base/single/input/file.js | 16 +- src/base/tree/synctree.js | 2 +- src/base/tree/treeview.js | 16 +- src/case/logintimeout/login.timeout.js | 10 +- src/case/zclip/zclip.js | 4 +- src/component/combo.treevaluechooser.js | 599 ++++++++++++++ src/component/combo.valuechooser.js | 127 +++ src/core/alias.js | 591 ++++++++++++++ src/core/base.js | 47 +- src/core/func/function.js | 2 +- src/core/model.js | 2 +- src/core/utils/load.js | 2 +- src/css/base/third/farbtastic/farbtastic.css | 6 +- src/css/base/third/ztree/zTreeStyle.css | 50 +- src/css/base/view/popupview.css | 2 +- .../base/third/farbtastic/farbtastic.less | 8 +- src/less/base/third/ztree/zTreeStyle.less | 46 +- src/less/base/view/popupview.less | 2 +- src/widget/image/uploadimage.js | 2 +- 39 files changed, 2891 insertions(+), 236 deletions(-) create mode 100644 demo/js/component/demo.treevaluechooser.js create mode 100644 demo/js/component/demo.valuechooser.js create mode 100644 demo/js/config/component.js delete mode 100644 demo/js/widget/demo.multiselecttree.js rename {src/less/base/third => dist}/farbtastic/marker.png (100%) rename {src/less/base/third => dist}/farbtastic/mask.png (100%) rename {src/less/base/third => dist}/farbtastic/wheel.png (100%) rename {src/less/base/third => dist}/ztree/img/line_conn.gif (100%) rename {src/less/base/third => dist}/ztree/img/loading.gif (100%) rename {src/less/base/third => dist}/ztree/img/zTreeStandard.gif (100%) rename {src/less/base/third => dist}/ztree/img/zTreeStandard.png (100%) create mode 100644 src/component/combo.treevaluechooser.js create mode 100644 src/component/combo.valuechooser.js create mode 100644 src/core/alias.js diff --git a/Gruntfile.js b/Gruntfile.js index 65acb4824..9e758f414 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -62,7 +62,8 @@ module.exports = function (grunt) { src: [ 'src/widget/paramsettingcombo/popup.param.js', 'src/widget/sequencetable/treenumber.sequencetable.js', - 'src/widget/**/*.js' + 'src/widget/**/*.js', + 'src/component/**/*.js' ], dest: "dist/widget.js" }, diff --git a/demo/config.js b/demo/config.js index ad42d6618..abd87a41e 100644 --- a/demo/config.js +++ b/demo/config.js @@ -1 +1 @@ -Demo.CONFIG = Demo.LAYOUT_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG); \ No newline at end of file +Demo.CONFIG = Demo.LAYOUT_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG).concat(Demo.COMPONENT_CONFIG); \ No newline at end of file diff --git a/demo/js/component/demo.treevaluechooser.js b/demo/js/component/demo.treevaluechooser.js new file mode 100644 index 000000000..eb3673a3c --- /dev/null +++ b/demo/js/component/demo.treevaluechooser.js @@ -0,0 +1,39 @@ +Demo.TreeValueChooser = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-tree-value-chooser" + }, + render: function () { + + var tree = []; + for (var i = 0; i < 21; i++) { + tree.push({ + value: i + "", + text: i + "", + id: i + "", + pId: null + }); + for (var j = 0; j < 9; j++) { + tree.push({ + value: i + "-" + j, + text: j + "", + id: i + "-" + j, + pId: i + "" + }) + } + } + var widget = BI.createWidget({ + type: "bi.tree_value_chooser_combo", + items: tree, + itemsCreator: function (op, callback) { + callback(tree); + } + }); + return { + type: "bi.vertical", + hgap: 200, + vgap: 10, + items: [widget] + }; + } +}); +$.shortcut("demo.tree_value_chooser", Demo.TreeValueChooser); diff --git a/demo/js/component/demo.valuechooser.js b/demo/js/component/demo.valuechooser.js new file mode 100644 index 000000000..dbb36aa36 --- /dev/null +++ b/demo/js/component/demo.valuechooser.js @@ -0,0 +1,29 @@ +var _strings = " 柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 "; +//各种通用数据 +var ITEMS = BI.map(_strings.match(/[^\s]+/g), function (i, v) { + return { + text: v, + value: v, + title: v + } +}); +Demo.ValueChooserCombo = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-value-chooser-combo" + }, + render: function () { + var widget = BI.createWidget({ + type: "bi.value_chooser_combo", + itemsCreator: function (op, callback) { + callback(BI.deepClone(ITEMS)); + } + }); + return { + type: "bi.vertical", + hgap: 200, + vgap: 10, + items: [widget] + }; + } +}); +$.shortcut("demo.value_chooser_combo", Demo.ValueChooserCombo); \ No newline at end of file diff --git a/demo/js/config/component.js b/demo/js/config/component.js new file mode 100644 index 000000000..fe90fe901 --- /dev/null +++ b/demo/js/config/component.js @@ -0,0 +1,15 @@ +/** + * Created by User on 2017/3/22. + */ +Demo.COMPONENT_CONFIG = [{ + id: 15, + text: "部件" +}, { + pId: 15, + text: "bi.value_chooser_combo", + value: "demo.value_chooser_combo" +}, { + pId: 15, + text: "bi.tree_value_chooser_combo", + value: "demo.tree_value_chooser" +}]; \ No newline at end of file diff --git a/demo/js/widget/demo.multiselecttree.js b/demo/js/widget/demo.multiselecttree.js deleted file mode 100644 index 437f12162..000000000 --- a/demo/js/widget/demo.multiselecttree.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.MultiSelectTree = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-multi-select-tree" - }, - render: function () { - return { - type: "bi.vertical", - } - } -}); -$.shortcut("demo.multi_select_tree", Demo.MultiSelectTree); \ No newline at end of file diff --git a/dist/base.css b/dist/base.css index 867afd467..0dd7e1c55 100644 --- a/dist/base.css +++ b/dist/base.css @@ -1310,19 +1310,19 @@ li.CodeMirror-hint-active { height: 101px; } .farbtastic .wheel { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/wheel.png) no-repeat; + background: url(farbtastic/wheel.png) no-repeat; width: 195px; height: 195px; } .farbtastic .overlay { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/mask.png) no-repeat; + background: url(farbtastic/mask.png) no-repeat; } .farbtastic .marker { width: 17px; height: 17px; margin: -8px 0 0 -8px; overflow: hidden; - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/marker.png) no-repeat; + background: url(farbtastic/marker.png) no-repeat; } /* required styles */ .leaflet-pane, @@ -1846,7 +1846,7 @@ website: http://code.google.com/p/jquerytree/ padding: 0 0 0 18px; } .ztree li ul.line { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y; + background: url(icon/tree-vertical-line-1.png) 0 0 repeat-y; } .ztree li a { padding: 1px 3px 0 0; @@ -1901,8 +1901,8 @@ website: http://code.google.com/p/jquerytree/ background-color: transparent; background-repeat: no-repeat; background-attachment: scroll; - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); - *background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif"); + background-image: url("ztree/img/zTreeStandard.png"); + *background-image: url("ztree/img/zTreeStandard.gif"); } .ztree li span.button.chk { width: 16px; @@ -1911,31 +1911,31 @@ website: http://code.google.com/p/jquerytree/ cursor: auto; } .ztree li span.button.chk.checkbox_false_full { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image: url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image: url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable { background-position: 0 -56px; } .ztree li span.button.chk.checkbox_true_full { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image: url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image: url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable { background-position: -14px -56px; @@ -1975,28 +1975,28 @@ website: http://code.google.com/p/jquerytree/ height: 25px; } .ztree li span.button.root_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); + background-image: url("icon/tree-expand-1.png"); } .ztree li span.button.root_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); + background-image: url("icon/tree-collapse-1.png"); } .ztree li span.button.roots_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); + background-image: url("icon/tree-expand-2.png"); } .ztree li span.button.roots_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); + background-image: url("icon/tree-collapse-2.png"); } .ztree li span.button.center_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); + background-image: url("icon/tree-expand-3.png"); } .ztree li span.button.center_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); + background-image: url("icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); + background-image: url("icon/tree-expand-4.png"); } .ztree li span.button.bottom_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); + background-image: url("icon/tree-collapse-4.png"); } .ztree li span.button.noline_open { background-position: -92px -72px; @@ -2008,13 +2008,13 @@ website: http://code.google.com/p/jquerytree/ background: none; } .ztree li span.button.roots_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); + background-image: url("icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); + background-image: url("icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); + background-image: url("icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu { background: none; @@ -2052,7 +2052,7 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.ico_loading { width: 0px; margin-right: 2px; - background: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif") no-repeat scroll 0 0 transparent; + background: url("ztree/img/loading.gif") no-repeat scroll 0 0 transparent; vertical-align: top; *vertical-align: middle; } @@ -2073,8 +2073,8 @@ span.tmpzTreeMove_arrow { background-repeat: no-repeat; background-attachment: scroll; background-position: -110px -80px; - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); - *background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif"); + background-image: url("ztree/img/zTreeStandard.png"); + *background-image: url("ztree/img/zTreeStandard.gif"); } ul.ztree.zTreeDragUL { margin: 0; @@ -2226,7 +2226,7 @@ ul.ztree.zTreeDragUL { /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -/**********FR.BIListView*************/ +/**********BI.BIListView*************/ .bi-list-view { position: fixed !important; overflow-y: visible !important; diff --git a/dist/base.js b/dist/base.js index 5b491a786..bbb5ca2a2 100644 --- a/dist/base.js +++ b/dist/base.js @@ -21851,9 +21851,9 @@ BI.TreeView = BI.inherit(BI.Pane, { }, _init: function () { BI.TreeView.superclass._init.apply(this, arguments); - FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.core-3.5.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.excheck-3.5.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/css/base/third/ztree/zTreeStyle.css', 'css'); + + + this._stop = false; this.container = BI.createWidget(); @@ -21908,7 +21908,7 @@ BI.TreeView = BI.inherit(BI.Pane, { enable: true, url: getUrl, autoParam: ["id", "name"], - otherParam: FR.cjkEncodeDO(paras) + otherParam: BI.cjkEncodeDO(paras) }, check: { enable: true @@ -21950,10 +21950,10 @@ BI.TreeView = BI.inherit(BI.Pane, { treeNode.times = treeNode.times || 1; var param = "id=" + treeNode.id + "×=" + (treeNode.times++) - + "&parent_values= " + window.encodeURIComponent(FR.jsonEncode(parentNode)) - + "&check_state=" + window.encodeURIComponent(FR.jsonEncode(treeNode.getCheckStatus())); + + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode)) + + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus())); - return FR.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; + return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; } function beforeExpand(treeId, treeNode) { @@ -22002,7 +22002,7 @@ BI.TreeView = BI.inherit(BI.Pane, { function ajaxGetNodes(treeNode, reloadType) { var zTree = self.nodes; if (reloadType == "refresh") { - //treeNode.icon = FR.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; + //treeNode.icon = BI.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; zTree.updateNode(treeNode); } zTree.reAsyncChildNodes(treeNode, reloadType, true); @@ -22362,7 +22362,7 @@ BI.SyncTree = BI.inherit(BI.TreeView, { var setting = { async: { enable: false, - otherParam: FR.cjkEncodeDO(paras) + otherParam: BI.cjkEncodeDO(paras) }, check: { enable: true @@ -25091,8 +25091,8 @@ BI.Farbtastic = BI.inherit(BI.Widget, { _init: function () { BI.Farbtastic.superclass._init.apply(this, arguments); var self = this; - FR.$defaultImport('/com/fr/bi/web/js/third/farbtastic.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/css/base/third/farbtastic/farbtastic.css', 'css'); + + this.farbtastic = $.farbtastic(this.element, function (v) { self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); @@ -34693,7 +34693,7 @@ $.extend(BI, { this._show(true, title, message, callback); }, prompt: function (title, message, value, callback, min_width) { - FR.Msg.prompt(title, message, value, callback, min_width); + BI.Msg.prompt(title, message, value, callback, min_width); }, toast: function (message, level, context) { context = context || $("body"); @@ -38815,7 +38815,7 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** var multipart = function (boundary, name, file) { return "--".concat( boundary, CRLF, - 'Content-Disposition: form-data; name="', name, '"; filename="', FR.cjkEncode(file.fileName), '"', CRLF, + 'Content-Disposition: form-data; name="', name, '"; filename="', BI.cjkEncode(file.fileName), '"', CRLF, "Content-Type: application/octet-stream", CRLF, CRLF, file.getAsBinary(), CRLF, @@ -38884,7 +38884,7 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** }, false ); - xhr.open("post", handler.url + '&filename=' + FR.cjkEncode(handler.file.fileName), true); + xhr.open("post", handler.url + '&filename=' + BI.cjkEncode(handler.file.fileName), true); if (!xhr.upload) { var rpe = {loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true}; rpe.interval = setInterval(function () { @@ -38915,8 +38915,8 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** upload.onprogress(rpe); if (199 < xhr.status && xhr.status < 400) { upload["onload"]({}); - var attachO = FR.jsonDecode(xhr.responseText); - attachO.filename = FR.cjkDecode(handler.file.fileName); + var attachO = BI.jsonDecode(xhr.responseText); + attachO.filename = BI.cjkDecode(handler.file.fileName); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } @@ -38932,7 +38932,7 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** xhr.onreadystatechange = function () { switch (xhr.readyState) { case 4: - var attachO = FR.jsonDecode(xhr.responseText); + var attachO = BI.jsonDecode(xhr.responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } @@ -38982,13 +38982,13 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** //rpe.loaded = rpe.total; try { var responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; - var attachO = FR.jsonDecode(responseText); + var attachO = BI.jsonDecode(responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } //attachO.fileSize = responseText.length; - attachO.filename = FR.cjkDecode(handler.file.fileName); + attachO.filename = BI.cjkDecode(handler.file.fileName); if (handler.maxlength == 1) { handler.attach_array[0] = attachO; } else { @@ -39205,7 +39205,7 @@ $.shortcut("bi.checkbox", BI.Checkbox);/** // enable again the submit button/element }, 1000); }; - _wrap.url = o.url ? o.url : FR.servletURL + _wrap.url = o.url ? o.url : BI.servletURL + '?op=fr_attach&cmd=ah_upload'; _wrap.fileType = o.accept; //文件类型限制 _wrap.attach_array = []; diff --git a/dist/case.js b/dist/case.js index 94545560f..8b80badc9 100644 --- a/dist/case.js +++ b/dist/case.js @@ -5622,9 +5622,9 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { } //反正是登录直接用FR的登录了 - FR.ajax({ - url: FR.servletURL + '?op=fs_load&cmd=login', - data: FR.cjkEncodeDO({ + BI.ajax({ + url: BI.servletURL + '?op=fs_load&cmd=login', + data: BI.cjkEncodeDO({ fr_username: encodeURIComponent(userNameInput.getValue()), fr_password: encodeURIComponent(passwordInput.getValue()), fr_remember: self.keepLoginState.isSelected() @@ -5639,7 +5639,7 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { self._showMes(userNameMask, BI.i18nText("BI-Authentication_Failed")); return; } - var signResult = FR.jsonDecode(res.responseText); + var signResult = BI.jsonDecode(res.responseText); if (signResult.fail) { //用户名和密码不匹配 self._showMes(userNameMask, BI.i18nText("BI-Username_Password_Not_Correct")); @@ -5663,7 +5663,7 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { type: "bi.center_adapt", items: [{ type: "bi.img", - src: FR.servletURL + (logo ? + src: BI.servletURL + (logo ? '?op=fr_attach&cmd=ah_image&id=' + logo + '&isAdjust=false' : '?op=resource&resource=/com/fr/bi/web/images/login/bi_logo.png'), width: 120, @@ -9322,10 +9322,10 @@ BI.ZeroClip = BI.inherit(BI.BasicButton, { _init: function () { BI.ZeroClip.superclass._init.apply(this, arguments); var self = this, o = this.options; - FR.$defaultImport('/com/fr/bi/web/js/third/jquery.zclip.js', 'js'); + BI.nextTick(function () { self.element.zclip({ - path: FR.servletURL + "?op=resource&resource=/com/fr/bi/web/resources/ZeroClipboard.swf", + path: BI.servletURL + "?op=resource&resource=/com/fr/bi/web/resources/ZeroClipboard.swf", copy: o.copy, beforeCopy: o.beforeCopy, afterCopy: o.afterCopy diff --git a/dist/core.js b/dist/core.js index 918dffeab..04bfb6cd4 100644 --- a/dist/core.js +++ b/dist/core.js @@ -12954,30 +12954,6 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, - createWidget: function (item, options) { - var el; - options || (options = {}); - if (BI.isEmpty(item) && BI.isEmpty(options)) { - return BI.Plugin.getObject("bi.layout", BI.createWidget({ - type: "bi.layout" - })); - } - if (BI.isWidget(item)) { - return item; - } - if (item && (item.type || options.type)) { - el = BI.extend({}, options, item); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && item.el && (item.el.type || options.type)) { - el = BI.extend({}, options, item.el); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && BI.isWidget(item.el)) { - return item.el; - } - }, - createWidgets: function (items, options) { if (!BI.isArray(items)) { throw new Error("cannot create Widgets") @@ -13802,10 +13778,6 @@ if (!window.BI) { return BI.isString(str) && BI.isEmpty(str); }, - contentFormat: function () { - return FR.contentFormat.apply(FR, arguments); - }, - /** * 对字符串进行加密 {@link #decrypt} * @static @@ -13999,7 +13971,12 @@ if (!window.BI) { } timeoutToast.addReq(option); - FR.ajax({ + + option.data = BI.cjkEncodeDO(option.data); + + + + $.ajax({ url: option.url, type: "POST", data: option.data, @@ -14054,10 +14031,10 @@ if (!window.BI) { loading.showError(); } else if (status === "success" && BI.isFunction(option.success)) { - option.success(FR.jsonDecode(res.responseText)); + option.success(BI.jsonDecode(res.responseText)); } if (BI.isFunction(option.complete)) { - option.complete(FR.jsonDecode(res.responseText), status); + option.complete(BI.jsonDecode(res.responseText), status); } } }); @@ -14069,7 +14046,7 @@ if (!window.BI) { function encodeBIParam(data) { for (var key in data) { if (_.isObject(data[key])) { - data[key] = window.encodeURIComponent(FR.jsonEncode(data[key])); + data[key] = window.encodeURIComponent(BI.jsonEncode(data[key])); } else { data[key] = window.encodeURIComponent(data[key]); } @@ -14080,7 +14057,7 @@ if (!window.BI) { for (var key in data) { data[key] = window.decodeURIComponent(data[key]); if (_.isObject(data[key])) { - data[key] = FR.jsonDecode(data[key]); + data[key] = BI.jsonDecode(data[key]); } } } @@ -14103,7 +14080,7 @@ if (!window.BI) { if (op === "fr_bi_dezi" || op === "fr_bi_configure") { data.sessionID = Data.SharingPool.get("sessionID"); } - var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); + var url = BI.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); return (BI.ajax)({ url: url, type: 'POST', @@ -14139,7 +14116,7 @@ if (!window.BI) { if (op === "fr_bi_dezi") { data.sessionID = Data.SharingPool.get("sessionID"); } - var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); + var url = BI.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); var result = {}; (BI.ajax)({ url: url, @@ -15070,7 +15047,7 @@ BI.Widget = BI.inherit(BI.OB, { }, urlRoot: function () { - return FR.servletURL; + return BI.servletURL; }, parse: function (data) { @@ -17500,7 +17477,7 @@ $.extend(BI, { type: null, must: false }, options); - config.url = FR.servletURL + '?op=' + config.op + '&resource=' + config.path; + config.url = BI.servletURL + '?op=' + config.op + '&resource=' + config.path; this.$import(config.url, config.type,config.must); }, $import: function () { @@ -19660,7 +19637,597 @@ BI.PopoverSection = BI.inherit(BI.Widget, { } }); -BI.PopoverSection.EVENT_CLOSE = "EVENT_CLOSE";/** +BI.PopoverSection.EVENT_CLOSE = "EVENT_CLOSE";BI.cjkEncode = function (text) { + // alex:如果非字符串,返回其本身(cjkEncode(234) 返回 ""是不对的) + if (typeof text !== 'string') { + return text; + } + + var newText = ""; + for (var i = 0; i < text.length; i++) { + var code = text.charCodeAt(i); + if (code >= 128 || code === 91 || code === 93) {//91 is "[", 93 is "]". + newText += "[" + code.toString(16) + "]"; + } else { + newText += text.charAt(i); + } + } + + return newText +}; + +BI.cjkEncodeDO = function (o) { + if (BI.isPlainObject(o)) { + var result = {}; + $.each(o, function (k, v) { + if (!(typeof v == "string")) { + v = BI.jsonEncode(v); + } + //wei:bug 43338,如果key是中文,cjkencode后o的长度就加了1,ie9以下版本死循环,所以新建对象result。 + k = BI.cjkEncode(k); + result[k] = BI.cjkEncode(v); + }); + return result; + } + return o; +}; + +BI.jsonEncode = function (o) { + //james:这个Encode是抄的EXT的 + var useHasOwn = {}.hasOwnProperty ? true : false; + + // crashes Safari in some instances + //var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/; + + var m = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"': '\\"', + "\\": '\\\\' + }; + + var encodeString = function (s) { + if (/["\\\x00-\x1f]/.test(s)) { + return '"' + s.replace(/([\x00-\x1f\\"])/g, function (a, b) { + var c = m[b]; + if (c) { + return c; + } + c = b.charCodeAt(); + return "\\u00" + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }) + '"'; + } + return '"' + s + '"'; + }; + + var encodeArray = function (o) { + var a = ["["], b, i, l = o.length, v; + for (i = 0; i < l; i += 1) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "function": + case "unknown": + break; + default: + if (b) { + a.push(','); + } + a.push(v === null ? "null" : BI.jsonEncode(v)); + b = true; + } + } + a.push("]"); + return a.join(""); + }; + + if (typeof o == "undefined" || o === null) { + return "null"; + } else if (BI.isArray(o)) { + return encodeArray(o); + } else if (o instanceof Date) { + /* + * alex:原来只是把年月日时分秒简单地拼成一个String,无法decode + * 现在这么处理就可以decode了,但是JS.jsonDecode和Java.JSONObject也要跟着改一下 + */ + return BI.jsonEncode({ + __time__: o.getTime() + }) + } else if (typeof o == "string") { + return encodeString(o); + } else if (typeof o == "number") { + return isFinite(o) ? String(o) : "null"; + } else if (typeof o == "boolean") { + return String(o); + } else if (BI.isFunction(o)) { + return String(o); + } else { + var a = ["{"], b, i, v; + for (i in o) { + if (!useHasOwn || o.hasOwnProperty(i)) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "unknown": + break; + default: + if (b) { + a.push(','); + } + a.push(BI.jsonEncode(i), ":", + v === null ? "null" : BI.jsonEncode(v)); + b = true; + } + } + } + a.push("}"); + return a.join(""); + } +}; + +BI.contentFormat = function (cv, fmt) { + if (BI.isEmpty(cv)) { + //原值为空,返回空字符 + return ''; + } + var text = cv.toString(); + if (BI.isEmpty(fmt)) { + //格式为空,返回原字符 + return text; + } + if (fmt.match(/^T/)) { + //T - 文本格式 + return text; + } else if (fmt.match(/^D/)) { + //D - 日期(时间)格式 + if (!(cv instanceof Date)) { + if (typeof cv === 'number') { + //毫秒数类型 + cv = new Date(cv); + } else { + //字符串类型,如yyyyMMdd、MMddyyyy等这样无分隔符的结构 + cv = Date.parseDate(cv + "", Date.patterns.ISO8601Long); + } + } + if (!BI.isNull(cv)) { + var needTrim = fmt.match(/^DT/); + text = BI.date2Str(cv, fmt.substring(needTrim ? 2 : 1)); + } + } else if (fmt.match(/E/)) { + //科学计数格式 + text = BI._eFormat(text, fmt); + } else { + //数字格式 + text = BI._numberFormat(text, fmt); + } + //¤ - 货币格式 + text = text.replace(/¤/g, '¥'); + return text; +}; + +/** + * 把日期对象按照指定格式转化成字符串 + * + * @example + * var date = new Date('Thu Dec 12 2013 00:00:00 GMT+0800'); + * var result = BI.date2Str(date, 'yyyy-MM-dd');//2013-12-12 + * + * @class BI.date2Str + * @param date 日期 + * @param format 日期格式 + * @returns {String} + */ +date2Str = function (date, format) { + if (!date) { + return ''; + } + // O(len(format)) + var len = format.length, result = ''; + if (len > 0) { + var flagch = format.charAt(0), start = 0, str = flagch; + for (var i = 1; i < len; i++) { + var ch = format.charAt(i); + if (flagch !== ch) { + result += compileJFmt({ + 'char': flagch, + 'str': str, + 'len': i - start + }, date); + flagch = ch; + start = i; + str = flagch; + } else { + str += ch; + } + } + result += compileJFmt({ + 'char': flagch, + 'str': str, + 'len': len - start + }, date); + } + return result; + + function compileJFmt(jfmt, date) { + var str = jfmt.str, len = jfmt.len, ch = jfmt['char']; + switch (ch) { + case 'E': //星期 + str = Date._DN[date.getDay()]; + break; + case 'y': //年 + if (len <= 3) { + str = (date.getFullYear() + '').slice(2, 4); + } else { + str = date.getFullYear(); + } + break; + case 'M': //月 + if (len > 2) { + str = Date._MN[date.getMonth()]; + } else if (len < 2) { + str = date.getMonth() + 1; + } else { + str = String.leftPad(date.getMonth() + 1 + '', 2, '0'); + } + break; + case 'd': //日 + if (len > 1) { + str = String.leftPad(date.getDate() + '', 2, '0'); + } else { + str = date.getDate(); + } + break; + case 'h': //时(12) + var hour = date.getHours() % 12; + if (hour === 0) { + hour = 12; + } + if (len > 1) { + str = String.leftPad(hour + '', 2, '0'); + } else { + str = hour; + } + break; + case 'H': //时(24) + if (len > 1) { + str = String.leftPad(date.getHours() + '', 2, '0'); + } else { + str = date.getHours(); + } + break; + case 'm': + if (len > 1) { + str = String.leftPad(date.getMinutes() + '', 2, '0'); + } else { + str = date.getMinutes(); + } + break; + case 's': + if (len > 1) { + str = String.leftPad(date.getSeconds() + '', 2, '0'); + } else { + str = date.getSeconds(); + } + break; + case 'a': + str = date.getHours() < 12 ? 'am' : 'pm'; + break; + case 'z': + str = date.getTimezone(); + break; + default: + str = jfmt.str; + break; + } + return str; + } +}; + +/** + * 数字格式 + */ +BI._numberFormat = function (text, format) { + var text = text + ''; + //数字格式,区分正负数 + var numMod = format.indexOf(';'); + if (numMod > -1) { + if (text >= 0) { + return BI._numberFormat(text + "", format.substring(0, numMod)); + } else { + return BI._numberFormat((-text) + "", format.substr(numMod + 1)); + } + } + var tp = text.split('.'), fp = format.split('.'), + tleft = tp[0] || '', fleft = fp[0] || '', + tright = tp[1] || '', fright = fp[1] || ''; + //百分比,千分比的小数点移位处理 + if (/[%‰]$/.test(format)) { + var paddingZero = /[%]$/.test(format) ? '00' : '000'; + tright += paddingZero; + tleft += tright.substr(0, paddingZero.length); + tleft = tleft.replace(/^0+/gi, ''); + tright = tright.substr(paddingZero.length).replace(/0+$/gi, ''); + } + var right = BI._dealWithRight(tright, fright); + if (right.leftPlus) { + //小数点后有进位 + tleft = parseInt(tleft) + 1 + ''; + + tleft = isNaN(tleft) ? '1' : tleft; + } + right = right.num; + var left = BI._dealWithLeft(tleft, fleft); + if (!(/[0-9]/.test(left))) { + left = left + '0'; + } + if (!(/[0-9]/.test(right))) { + return left + right; + } else { + return left + '.' + right; + } +}; +/** + * 处理小数点右边小数部分 + * @param tright 右边内容 + * @param fright 右边格式 + * @returns {JSON} 返回处理结果和整数部分是否需要进位 + * @private + */ +BI._dealWithRight = function (tright, fright) { + var right = '', j = 0, i = 0; + for (var len = fright.length; i < len; i++) { + var ch = fright.charAt(i); + var c = tright.charAt(j); + switch (ch) { + case '0': + if (BI.isEmpty(c)) { + c = '0'; + } + right += c; + j++; + break; + case '#': + right += c; + j++; + break; + default : + right += ch; + break; + } + } + var rll = tright.substr(j); + var result = {}; + if (!BI.isEmpty(rll) && rll.charAt(0) > 4) { + //有多余字符,需要四舍五入 + result.leftPlus = true; + var numReg = right.match(/^[0-9]+/); + if (numReg) { + var num = numReg[0]; + var orilen = num.length; + var newnum = BI.parseINT(num) + 1 + ''; + //进位到整数部分 + if (newnum.length > orilen) { + newnum = newnum.substr(1); + } else { + newnum = BI.leftPad(newnum, orilen, '0'); + result.leftPlus = false; + } + right = right.replace(/^[0-9]+/, newnum); + } + } + result.num = right; + return result; +}; + +BI.parseINT = function (str) { + return parseInt(str, 10); +}; + +BI.leftPad = function (val, size, ch) { + var result = String(val); + if (!ch) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result.toString(); +}; + +/** + * 处理小数点左边整数部分 + * @param tleft 左边内容 + * @param fleft 左边格式 + * @returns {string} 返回处理结果 + * @private + */ +BI._dealWithLeft = function (tleft, fleft) { + var left = ''; + var j = tleft.length - 1; + var combo = -1, last = -1; + var i = fleft.length - 1; + for (; i >= 0; i--) { + var ch = fleft.charAt(i); + var c = tleft.charAt(j); + switch (ch) { + case '0': + if (BI.isEmpty(c)) { + c = '0'; + } + last = -1; + left = c + left; + j--; + break; + case '#': + last = i; + left = c + left; + j--; + break; + case ',': + if (!BI.isEmpty(c)) { + //计算一个,分隔区间的长度 + var com = fleft.match(/,[#0]+/); + if (com) { + combo = com[0].length - 1; + } + left = ',' + left; + } + break; + default : + left = ch + left; + break; + } + } + if (last > -1) { + //处理剩余字符 + var tll = tleft.substr(0, j + 1); + left = left.substr(0, last) + tll + left.substr(last); + } + if (combo > 0) { + //处理,分隔区间 + var res = left.match(/[0-9]+,/); + if (res) { + res = res[0]; + var newstr = '', n = res.length - 1 - combo; + for (; n >= 0; n = n - combo) { + newstr = res.substr(n, combo) + ',' + newstr; + } + var lres = res.substr(0, n + combo); + if (!BI.isEmpty(lres)) { + newstr = lres + ',' + newstr; + } + } + left = left.replace(/[0-9]+,/, newstr); + } + return left; +}; + +BI.object2Number = function (value) { + if (value == null) { + return 0; + } + if (typeof value == 'number') { + return value; + } else { + var str = value + ""; + if (str.indexOf(".") === -1) { + return parseInt(str); + } else { + return parseFloat(str); + } + } +}; + +BI.object2Date = function (obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } else if (typeof obj == 'number') { + return new Date(obj); + } else { + var str = obj + ""; + str = str.replace(/-/g, '/'); + var dt = new Date(str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + + return new Date(); + } +}; + +BI.isArray = function (a) { + return Object.prototype.toString.call(a) == '[object Array]'; +}; + +BI.object2Time = function (obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } else { + var str = obj + ""; + str = str.replace(/-/g, '/'); + var dt = new Date(str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + if (str.indexOf('/') === -1 && str.indexOf(':') !== -1) { + dt = new Date("1970/01/01 " + str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + } + dt = BI.str2Date(str, "HH:mm:ss"); + if (!BI.isInvalidDate(dt)) { + return dt; + } + return new Date(); + } +}; + +// 判断是否是无效的日期 +BI.isInvalidDate = function (date) { + return date == "Invalid Date" || date == "NaN"; +}; + + +/** + * 科学计数格式 + */ +BI._eFormat = function (text, fmt) { + var e = fmt.indexOf("E"); + var eleft = fmt.substr(0, e), eright = fmt.substr(e + 1); + if (/^[0\.-]+$/.test(text)) { + text = BI._numberFormat(0.0, eleft) + 'E' + BI._numberFormat(0, eright) + } else { + var isNegative = text < 0; + if (isNegative) { + text = text.substr(1); + } + var elvl = (eleft.split('.')[0] || '').length; + var point = text.indexOf("."); + if (point < 0) { + point = text.length; + } + var i = 0; //第一个不为0的数的位置 + text = text.replace('.', ''); + for (var len = text.length; i < len; i++) { + var ech = text.charAt(i); + if (ech <= '9' && ech >= '1') { + break; + } + } + var right = point - i - elvl; + var left = text.substr(i, elvl); + var dis = i + elvl - text.length; + if (dis > 0) { + //末位补全0 + for (var k = 0; k < dis; k++) { + left += '0'; + } + } else { + left += '.' + text.substr(i + elvl); + } + left = left.replace(/^[0]+/, ''); + if (right < 0 && eright.indexOf('-') < 0) { + eright += ';-' + eright; + } + text = BI._numberFormat(left, eleft) + 'E' + BI._numberFormat(right, eright); + if (isNegative) { + text = '-' + text; + } + } + return text; +};/** * guy * * @class BI.HighlightBehavior @@ -21940,7 +22507,7 @@ $(function () { }, getCompleteImageUrl: function (url) { - return FR.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + url; + return BI.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + url; } }); diff --git a/src/less/base/third/farbtastic/marker.png b/dist/farbtastic/marker.png similarity index 100% rename from src/less/base/third/farbtastic/marker.png rename to dist/farbtastic/marker.png diff --git a/src/less/base/third/farbtastic/mask.png b/dist/farbtastic/mask.png similarity index 100% rename from src/less/base/third/farbtastic/mask.png rename to dist/farbtastic/mask.png diff --git a/src/less/base/third/farbtastic/wheel.png b/dist/farbtastic/wheel.png similarity index 100% rename from src/less/base/third/farbtastic/wheel.png rename to dist/farbtastic/wheel.png diff --git a/dist/widget.js b/dist/widget.js index 057bfed2b..d3839ccaa 100644 --- a/dist/widget.js +++ b/dist/widget.js @@ -12981,7 +12981,7 @@ BI.UploadImage = BI.inherit(BI.Widget, { BI.extend(BI.UploadImage, { getImageSrc: function (src) { - return FR.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + src; + return BI.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + src; } }); @@ -30143,4 +30143,728 @@ BI.YearQuarterCombo = BI.inherit(BI.Widget, { } }); BI.YearQuarterCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -$.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo); \ No newline at end of file +$.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo);/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserCombo + * @extends BI.Widget + */ +BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { + + _const: { + perPage: 10 + }, + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: 'bi.multi_tree_combo', + element: this.element, + itemsCreator: BI.bind(this._itemsCreator, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); + }); + }, + + _initData: function (items) { + this.items = items; + var nodes = BI.Tree.transformToTreeFormat(items); + this.tree = new BI.Tree(); + this.tree.initTree(nodes); + this._initMap(); + this._initFloors(); + }, + + _initMap: function () { + var map = this.map = {}; + BI.each(this.items, function (i, item) { + map[item.value] = item; + }); + }, + + _initFloors: function () { + this.floors = -1; + var root = this.tree.getRoot(); + while (root) { + this.floors++; + root = root.getChildren()[0]; + } + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!this.items) { + o.itemsCreator({}, function (items) { + self._initData(items); + call(); + }); + } else { + call(); + } + function call() { + switch (options.type) { + case BI.TreeView.REQ_TYPE_INIT_DATA: + self._reqInitTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_ADJUST_DATA: + self._reqAdjustTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA: + self._reqSelectedTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_SELECTED_DATA: + self._reqDisplayTreeNode(options, callback); + break; + default : + self._reqTreeNode(options, callback); + break; + } + } + }, + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = []; + var selected_values = op.selected_values; + + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + + doCheck(0, [], selected_values); + + callback({ + items: result + }); + + function doCheck(floor, parent_values, selected) { + if (floor >= self.floors) { + return; + } + if (selected == null || BI.isEmpty(selected)) { + var children = self._getChildren(parent_values); + BI.each(children, function (i, child) { + var newParents = BI.clone(parent_values); + newParents.push(child.value); + var llen = self._getChildCount(newParents); + createOneJson(child, llen); + doCheck(floor + 1, newParents, {}); + }); + return; + } + BI.each(selected, function (k) { + var node = self._getNode(k); + var newParents = BI.clone(parent_values); + newParents.push(node.value); + createOneJson(node, getCount(selected[k], newParents)); + doCheck(floor + 1, newParents, selected[k]); + }) + } + + function getCount(jo, parent_values) { + if (jo == null) { + return 0; + } + if (BI.isEmpty(jo)) { + return self._getChildCount(parent_values); + } + + return BI.size(jo); + } + + function createOneJson(node, llen) { + result.push({ + id: node.id, + pId: node.pId, + text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), + value: node.value, + open: true + }); + } + }, + + _reqSelectedTreeNode: function (op, callback) { + var self = this; + var selected_values = op.selected_values; + var not_selected_value = op.not_selected_value || {}; + var keyword = op.keyword || ""; + var parent_values = op.parent_values || []; + + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + + dealWithSelectedValues(selected_values); + callback(selected_values); + + + function dealWithSelectedValues(selected_values) { + var p = BI.clone(parent_values); + p.push(not_selected_value); + + if (isChild(selected_values, p)) { + var result = []; + var finded = search(parent_values.length + 1, parent_values, not_selected_value, result); + + if (finded === true) { + var next = selected_values; + BI.each(p, function (i, v) { + var t = next[v]; + if (t == null) { + if (BI.isEmpty(next)) { + var split = p.slice(0, i); + var expanded = self._getChildren(split); + BI.each(expanded, function (m, child) { + if (i === p.length - 1 && child.value === not_selected_value) { + return true; + } + next[child.value] = {}; + }); + next = next[v]; + } else { + next = {}; + next[v] = {}; + } + } else { + next = t; + } + }); + + if (result.length > 0) { + BI.each(result, function (i, strs) { + self._buildTree(selected_values, strs); + }) + } + } + } + + } + + function search(deep, parents, current, result) { + var newParents = BI.clone(parents); + newParents.push(current); + if (self._isMatch(current, keyword)) { + return true; + } + if (deep >= self.floors) { + return false; + } + + var children = self._getChildren(newParents); + + var notSearch = []; + var can = false; + + BI.each(children, function (i, child) { + if (search(deep + 1, newParents, child.value, result)) { + can = true; + } else { + notSearch.push(child.value); + } + }); + if (can === true) { + BI.each(notSearch, function (i, v) { + var next = BI.clone(newParents); + next.push(v); + result.push(next); + }); + } + return can; + } + + function isChild(selected_values, parents) { + var t = selected_values; + for (var i = 0; i < parents.length; i++) { + var v = parents[i]; + if (!BI.has(t, v)) { + return false; + } + t = t[v]; + if (t == null || BI.isEmpty(t)) { + return true; + } + } + return true; + } + }, + + _reqAdjustTreeNode: function (op, callback) { + var self = this; + var result = []; + var selected_values = op.selected_values; + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + BI.each(selected_values, function (k, v) { + result.push([k]); + }); + + dealWithSelectedValues(selected_values, []); + + var jo = {}; + BI.each(result, function (i, strs) { + self._buildTree(jo, strs); + }); + callback(jo); + + function dealWithSelectedValues(selected, parents) { + if (selected == null || BI.isEmpty(selected)) { + return true; + } + var can = true; + BI.each(selected, function (k, v) { + var p = BI.clone(parents); + p.push(k); + if (!dealWithSelectedValues(selected[k], p)) { + BI.each(selected[k], function (nk, nv) { + var t = BI.clone(p); + t.push(nk); + result.push(t); + }); + can = false; + } + }); + return can && isAllSelected(selected, parents); + } + + function isAllSelected(selected, parents) { + return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selected_values = op.selected_values; + var last_search_value = op.last_search_value || ""; + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + last_search_value: BI.last(output) + }) + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (last_search_value !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === last_search_value) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + return output; + } + + function nodeSearch(deep, parent_values, current, isAllSelect, result) { + if (self._isMatch(current, keyword)) { + var checked = isAllSelect || isSelected(parent_values, current); + createOneJson(parent_values, current, false, checked, !isAllSelect && isHalf(parent_values, current), true, result); + return [true, checked]; + } + if (deep >= self.floors) { + return [false, false]; + } + var newParents = BI.clone(parent_values); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + var isCurAllSelected = isAllSelect || isAllSelected(parent_values, current); + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isCurAllSelected || (isSelected(parent_values, current) && checked); + createOneJson(parent_values, current, true, checked, false, false, result); + } + return [can, checked]; + } + + function createOneJson(parent_values, value, isOpen, checked, half, flag, result) { + var node = self.map[value]; + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: parent_values.length + 1 < self.floors, + open: isOpen, + checked: checked, + halfCheck: half, + flag: flag + }); + } + + function isHalf(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return false; + } + return BI.any(find, function (v) { + if (v === value) { + return true; + } + }); + } + + function findSelectedObj(parent_values) { + var find = selected_values; + if (find == null) { + return null; + } + BI.every(parent_values, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var check_state = op.check_state || {}; + var parent_values = op.parent_values || []; + var selected_values = op.selected_values; + var valueMap = {}; + if (judgeState(parent_values, selected_values, check_state)) { + valueMap = dealWidthSelectedValue(parent_values, selected_values); + } + var nodes = this._getChildren(parent_values); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var state = getCheckState(nodes[i].value, parent_values, valueMap, check_state); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: parent_values.length + 1 < this.floors, + checked: state[0], + halfCheck: state[1] + }) + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function judgeState(parent_values, selected_value, check_state) { + var checked = check_state.checked, half = check_state.half; + if (parent_values.length > 0 && !checked) { + return false; + } + return (parent_values.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); + } + + function dealWidthSelectedValue(parent_values, selected_values) { + var valueMap = {}; + BI.each(parent_values, function (i, v) { + selected_values = selected_values[v]; + }); + BI.each(selected_values, function (value, obj) { + if (BI.isNull(obj)) { + valueMap[value] = [0, 0]; + return; + } + if (BI.isEmpty(obj)) { + valueMap[value] = [2, 0]; + return; + } + var nextNames = {}; + BI.each(obj, function (t, o) { + if (BI.isNull(o) || BI.isEmpty(o)) { + nextNames[t] = true; + } + }); + valueMap[value] = [1, BI.size(nextNames)]; + }); + return valueMap; + } + + function getCheckState(current, parent_values, valueMap, check_state) { + var checked = check_state.checked, half = check_state.half; + var hasChild = parent_values.length + 1 < self.floors; + var tempCheck = false, halfCheck = false; + if (BI.has(valueMap, current)) { + //可能是半选 + if (valueMap[current][0] === 1) { + var values = BI.clone(parent_values); + values.push(current); + if (hasChild && self._getChildCount(values) != valueMap[current][1]) { + halfCheck = true; + } + } else if (valueMap[current][0] === 2) { + tempCheck = true; + } + } + var check; + if (!checked && !halfCheck && !tempCheck) { + check = BI.has(valueMap, current); + } else { + check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); + } + return [check, halfCheck]; + } + }, + + + _buildTree: function (jo, values) { + var t = jo; + BI.each(values, function (i, v) { + if (!BI.has(t, v)) { + t[v] = {}; + } + t = t[v]; + }); + }, + + _isMatch: function (value, keyword) { + var finded = BI.Func.getSearchResult([value], keyword); + return finded.finded.length > 0 || finded.matched.length > 0; + }, + + _getNode: function (v) { + return this.tree.search(v, "value"); + }, + + _getChildren: function (parent_values) { + if (parent_values.length > 0) { + var value = BI.last(parent_values); + var parent = this.tree.search(value, "value"); + } else { + var parent = this.tree.getRoot(); + } + return parent.getChildren(); + }, + + _getChildCount: function (parent_values) { + return this._getChildren(parent_values).length; + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function () { + this.combo.populate.apply(this, arguments); + } +}); +BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; +$.shortcut('bi.tree_value_chooser_combo', BI.TreeValueChooserCombo);/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserCombo + * @extends BI.Widget + */ +BI.ValueChooserCombo = BI.inherit(BI.Widget, { + + _const: { + perPage: 10 + }, + _defaultConfig: function () { + return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_combo', + element: this.element, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(self.items)) { + BI.some(self.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; + } + }); + } + return text; + }, + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); + }); + }, + + _getItemsByTimes: function (items, times) { + var res = []; + for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { + res.push(items[i]); + } + return res; + }, + + _hasNextByTimes: function (items, times) { + return times * this._const.perPage < items.length; + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, function (items) { + self.items = items; + call(items); + }); + } else { + call(this.items); + } + function call(items) { + var keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + BI.each(keywords, function (i, kw) { + var search = BI.Func.getSearchResult(items, kw); + items = search.matched.concat(search.finded); + }); + if (options.selected_values) {//过滤 + var filter = BI.makeObject(options.selected_values, true); + items = BI.filter(items, function (i, ob) { + return !filter[ob.value]; + }); + } + if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: items + }); + return; + } + if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({count: items.length}); + return; + } + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + } + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + var val = this.combo.getValue() || {}; + return { + type: val.type, + value: val.value + } + }, + + populate: function () { + this.combo.populate.apply(this, arguments); + } +}); +BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; +$.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo); \ No newline at end of file diff --git a/src/less/base/third/ztree/img/line_conn.gif b/dist/ztree/img/line_conn.gif similarity index 100% rename from src/less/base/third/ztree/img/line_conn.gif rename to dist/ztree/img/line_conn.gif diff --git a/src/less/base/third/ztree/img/loading.gif b/dist/ztree/img/loading.gif similarity index 100% rename from src/less/base/third/ztree/img/loading.gif rename to dist/ztree/img/loading.gif diff --git a/src/less/base/third/ztree/img/zTreeStandard.gif b/dist/ztree/img/zTreeStandard.gif similarity index 100% rename from src/less/base/third/ztree/img/zTreeStandard.gif rename to dist/ztree/img/zTreeStandard.gif diff --git a/src/less/base/third/ztree/img/zTreeStandard.png b/dist/ztree/img/zTreeStandard.png similarity index 100% rename from src/less/base/third/ztree/img/zTreeStandard.png rename to dist/ztree/img/zTreeStandard.png diff --git a/src/base/farbtastic/farbtastic.js b/src/base/farbtastic/farbtastic.js index a243d31ee..ad49b5439 100644 --- a/src/base/farbtastic/farbtastic.js +++ b/src/base/farbtastic/farbtastic.js @@ -18,8 +18,8 @@ BI.Farbtastic = BI.inherit(BI.Widget, { _init: function () { BI.Farbtastic.superclass._init.apply(this, arguments); var self = this; - FR.$defaultImport('/com/fr/bi/web/js/third/farbtastic.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/css/base/third/farbtastic/farbtastic.css', 'css'); + + this.farbtastic = $.farbtastic(this.element, function (v) { self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); diff --git a/src/base/foundation/bi.message.js b/src/base/foundation/bi.message.js index e79e1bae7..1c17c2e1e 100644 --- a/src/base/foundation/bi.message.js +++ b/src/base/foundation/bi.message.js @@ -16,7 +16,7 @@ $.extend(BI, { this._show(true, title, message, callback); }, prompt: function (title, message, value, callback, min_width) { - FR.Msg.prompt(title, message, value, callback, min_width); + BI.Msg.prompt(title, message, value, callback, min_width); }, toast: function (message, level, context) { context = context || $("body"); diff --git a/src/base/single/input/file.js b/src/base/single/input/file.js index 2aa47b878..d1faf94d0 100644 --- a/src/base/single/input/file.js +++ b/src/base/single/input/file.js @@ -84,7 +84,7 @@ var multipart = function (boundary, name, file) { return "--".concat( boundary, CRLF, - 'Content-Disposition: form-data; name="', name, '"; filename="', FR.cjkEncode(file.fileName), '"', CRLF, + 'Content-Disposition: form-data; name="', name, '"; filename="', BI.cjkEncode(file.fileName), '"', CRLF, "Content-Type: application/octet-stream", CRLF, CRLF, file.getAsBinary(), CRLF, @@ -153,7 +153,7 @@ }, false ); - xhr.open("post", handler.url + '&filename=' + FR.cjkEncode(handler.file.fileName), true); + xhr.open("post", handler.url + '&filename=' + BI.cjkEncode(handler.file.fileName), true); if (!xhr.upload) { var rpe = {loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true}; rpe.interval = setInterval(function () { @@ -184,8 +184,8 @@ upload.onprogress(rpe); if (199 < xhr.status && xhr.status < 400) { upload["onload"]({}); - var attachO = FR.jsonDecode(xhr.responseText); - attachO.filename = FR.cjkDecode(handler.file.fileName); + var attachO = BI.jsonDecode(xhr.responseText); + attachO.filename = BI.cjkDecode(handler.file.fileName); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } @@ -201,7 +201,7 @@ xhr.onreadystatechange = function () { switch (xhr.readyState) { case 4: - var attachO = FR.jsonDecode(xhr.responseText); + var attachO = BI.jsonDecode(xhr.responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } @@ -251,13 +251,13 @@ //rpe.loaded = rpe.total; try { var responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; - var attachO = FR.jsonDecode(responseText); + var attachO = BI.jsonDecode(responseText); if (handler.file.type.indexOf('image') != -1) { attachO.attach_type = "image"; } //attachO.fileSize = responseText.length; - attachO.filename = FR.cjkDecode(handler.file.fileName); + attachO.filename = BI.cjkDecode(handler.file.fileName); if (handler.maxlength == 1) { handler.attach_array[0] = attachO; } else { @@ -474,7 +474,7 @@ // enable again the submit button/element }, 1000); }; - _wrap.url = o.url ? o.url : FR.servletURL + _wrap.url = o.url ? o.url : BI.servletURL + '?op=fr_attach&cmd=ah_upload'; _wrap.fileType = o.accept; //文件类型限制 _wrap.attach_array = []; diff --git a/src/base/tree/synctree.js b/src/base/tree/synctree.js index 52486fa83..a0d04cfc3 100644 --- a/src/base/tree/synctree.js +++ b/src/base/tree/synctree.js @@ -19,7 +19,7 @@ BI.SyncTree = BI.inherit(BI.TreeView, { var setting = { async: { enable: false, - otherParam: FR.cjkEncodeDO(paras) + otherParam: BI.cjkEncodeDO(paras) }, check: { enable: true diff --git a/src/base/tree/treeview.js b/src/base/tree/treeview.js index c65c5e730..f39a22c70 100644 --- a/src/base/tree/treeview.js +++ b/src/base/tree/treeview.js @@ -14,9 +14,9 @@ BI.TreeView = BI.inherit(BI.Pane, { }, _init: function () { BI.TreeView.superclass._init.apply(this, arguments); - FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.core-3.5.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/js/third/ztree/jquery.ztree.excheck-3.5.js', 'js'); - FR.$defaultImport('/com/fr/bi/web/css/base/third/ztree/zTreeStyle.css', 'css'); + + + this._stop = false; this.container = BI.createWidget(); @@ -71,7 +71,7 @@ BI.TreeView = BI.inherit(BI.Pane, { enable: true, url: getUrl, autoParam: ["id", "name"], - otherParam: FR.cjkEncodeDO(paras) + otherParam: BI.cjkEncodeDO(paras) }, check: { enable: true @@ -113,10 +113,10 @@ BI.TreeView = BI.inherit(BI.Pane, { treeNode.times = treeNode.times || 1; var param = "id=" + treeNode.id + "×=" + (treeNode.times++) - + "&parent_values= " + window.encodeURIComponent(FR.jsonEncode(parentNode)) - + "&check_state=" + window.encodeURIComponent(FR.jsonEncode(treeNode.getCheckStatus())); + + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode)) + + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus())); - return FR.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; + return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param; } function beforeExpand(treeId, treeNode) { @@ -165,7 +165,7 @@ BI.TreeView = BI.inherit(BI.Pane, { function ajaxGetNodes(treeNode, reloadType) { var zTree = self.nodes; if (reloadType == "refresh") { - //treeNode.icon = FR.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; + //treeNode.icon = BI.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif"; zTree.updateNode(treeNode); } zTree.reAsyncChildNodes(treeNode, reloadType, true); diff --git a/src/case/logintimeout/login.timeout.js b/src/case/logintimeout/login.timeout.js index 17dbafd01..075d5c740 100644 --- a/src/case/logintimeout/login.timeout.js +++ b/src/case/logintimeout/login.timeout.js @@ -130,9 +130,9 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { } //反正是登录直接用FR的登录了 - FR.ajax({ - url: FR.servletURL + '?op=fs_load&cmd=login', - data: FR.cjkEncodeDO({ + BI.ajax({ + url: BI.servletURL + '?op=fs_load&cmd=login', + data: BI.cjkEncodeDO({ fr_username: encodeURIComponent(userNameInput.getValue()), fr_password: encodeURIComponent(passwordInput.getValue()), fr_remember: self.keepLoginState.isSelected() @@ -147,7 +147,7 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { self._showMes(userNameMask, BI.i18nText("BI-Authentication_Failed")); return; } - var signResult = FR.jsonDecode(res.responseText); + var signResult = BI.jsonDecode(res.responseText); if (signResult.fail) { //用户名和密码不匹配 self._showMes(userNameMask, BI.i18nText("BI-Username_Password_Not_Correct")); @@ -171,7 +171,7 @@ BI.LoginTimeOut = BI.inherit(BI.BarPopoverSection, { type: "bi.center_adapt", items: [{ type: "bi.img", - src: FR.servletURL + (logo ? + src: BI.servletURL + (logo ? '?op=fr_attach&cmd=ah_image&id=' + logo + '&isAdjust=false' : '?op=resource&resource=/com/fr/bi/web/images/login/bi_logo.png'), width: 120, diff --git a/src/case/zclip/zclip.js b/src/case/zclip/zclip.js index ee4b724f2..c2c527f03 100644 --- a/src/case/zclip/zclip.js +++ b/src/case/zclip/zclip.js @@ -16,10 +16,10 @@ BI.ZeroClip = BI.inherit(BI.BasicButton, { _init: function () { BI.ZeroClip.superclass._init.apply(this, arguments); var self = this, o = this.options; - FR.$defaultImport('/com/fr/bi/web/js/third/jquery.zclip.js', 'js'); + BI.nextTick(function () { self.element.zclip({ - path: FR.servletURL + "?op=resource&resource=/com/fr/bi/web/resources/ZeroClipboard.swf", + path: BI.servletURL + "?op=resource&resource=/com/fr/bi/web/resources/ZeroClipboard.swf", copy: o.copy, beforeCopy: o.beforeCopy, afterCopy: o.afterCopy diff --git a/src/component/combo.treevaluechooser.js b/src/component/combo.treevaluechooser.js new file mode 100644 index 000000000..e0011cbf7 --- /dev/null +++ b/src/component/combo.treevaluechooser.js @@ -0,0 +1,599 @@ +/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserCombo + * @extends BI.Widget + */ +BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { + + _const: { + perPage: 10 + }, + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: 'bi.multi_tree_combo', + element: this.element, + itemsCreator: BI.bind(this._itemsCreator, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); + }); + }, + + _initData: function (items) { + this.items = items; + var nodes = BI.Tree.transformToTreeFormat(items); + this.tree = new BI.Tree(); + this.tree.initTree(nodes); + this._initMap(); + this._initFloors(); + }, + + _initMap: function () { + var map = this.map = {}; + BI.each(this.items, function (i, item) { + map[item.value] = item; + }); + }, + + _initFloors: function () { + this.floors = -1; + var root = this.tree.getRoot(); + while (root) { + this.floors++; + root = root.getChildren()[0]; + } + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!this.items) { + o.itemsCreator({}, function (items) { + self._initData(items); + call(); + }); + } else { + call(); + } + function call() { + switch (options.type) { + case BI.TreeView.REQ_TYPE_INIT_DATA: + self._reqInitTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_ADJUST_DATA: + self._reqAdjustTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA: + self._reqSelectedTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_SELECTED_DATA: + self._reqDisplayTreeNode(options, callback); + break; + default : + self._reqTreeNode(options, callback); + break; + } + } + }, + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = []; + var selected_values = op.selected_values; + + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + + doCheck(0, [], selected_values); + + callback({ + items: result + }); + + function doCheck(floor, parent_values, selected) { + if (floor >= self.floors) { + return; + } + if (selected == null || BI.isEmpty(selected)) { + var children = self._getChildren(parent_values); + BI.each(children, function (i, child) { + var newParents = BI.clone(parent_values); + newParents.push(child.value); + var llen = self._getChildCount(newParents); + createOneJson(child, llen); + doCheck(floor + 1, newParents, {}); + }); + return; + } + BI.each(selected, function (k) { + var node = self._getNode(k); + var newParents = BI.clone(parent_values); + newParents.push(node.value); + createOneJson(node, getCount(selected[k], newParents)); + doCheck(floor + 1, newParents, selected[k]); + }) + } + + function getCount(jo, parent_values) { + if (jo == null) { + return 0; + } + if (BI.isEmpty(jo)) { + return self._getChildCount(parent_values); + } + + return BI.size(jo); + } + + function createOneJson(node, llen) { + result.push({ + id: node.id, + pId: node.pId, + text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), + value: node.value, + open: true + }); + } + }, + + _reqSelectedTreeNode: function (op, callback) { + var self = this; + var selected_values = op.selected_values; + var not_selected_value = op.not_selected_value || {}; + var keyword = op.keyword || ""; + var parent_values = op.parent_values || []; + + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + + dealWithSelectedValues(selected_values); + callback(selected_values); + + + function dealWithSelectedValues(selected_values) { + var p = BI.clone(parent_values); + p.push(not_selected_value); + + if (isChild(selected_values, p)) { + var result = []; + var finded = search(parent_values.length + 1, parent_values, not_selected_value, result); + + if (finded === true) { + var next = selected_values; + BI.each(p, function (i, v) { + var t = next[v]; + if (t == null) { + if (BI.isEmpty(next)) { + var split = p.slice(0, i); + var expanded = self._getChildren(split); + BI.each(expanded, function (m, child) { + if (i === p.length - 1 && child.value === not_selected_value) { + return true; + } + next[child.value] = {}; + }); + next = next[v]; + } else { + next = {}; + next[v] = {}; + } + } else { + next = t; + } + }); + + if (result.length > 0) { + BI.each(result, function (i, strs) { + self._buildTree(selected_values, strs); + }) + } + } + } + + } + + function search(deep, parents, current, result) { + var newParents = BI.clone(parents); + newParents.push(current); + if (self._isMatch(current, keyword)) { + return true; + } + if (deep >= self.floors) { + return false; + } + + var children = self._getChildren(newParents); + + var notSearch = []; + var can = false; + + BI.each(children, function (i, child) { + if (search(deep + 1, newParents, child.value, result)) { + can = true; + } else { + notSearch.push(child.value); + } + }); + if (can === true) { + BI.each(notSearch, function (i, v) { + var next = BI.clone(newParents); + next.push(v); + result.push(next); + }); + } + return can; + } + + function isChild(selected_values, parents) { + var t = selected_values; + for (var i = 0; i < parents.length; i++) { + var v = parents[i]; + if (!BI.has(t, v)) { + return false; + } + t = t[v]; + if (t == null || BI.isEmpty(t)) { + return true; + } + } + return true; + } + }, + + _reqAdjustTreeNode: function (op, callback) { + var self = this; + var result = []; + var selected_values = op.selected_values; + if (selected_values == null || BI.isEmpty(selected_values)) { + callback({}); + return; + } + BI.each(selected_values, function (k, v) { + result.push([k]); + }); + + dealWithSelectedValues(selected_values, []); + + var jo = {}; + BI.each(result, function (i, strs) { + self._buildTree(jo, strs); + }); + callback(jo); + + function dealWithSelectedValues(selected, parents) { + if (selected == null || BI.isEmpty(selected)) { + return true; + } + var can = true; + BI.each(selected, function (k, v) { + var p = BI.clone(parents); + p.push(k); + if (!dealWithSelectedValues(selected[k], p)) { + BI.each(selected[k], function (nk, nv) { + var t = BI.clone(p); + t.push(nk); + result.push(t); + }); + can = false; + } + }); + return can && isAllSelected(selected, parents); + } + + function isAllSelected(selected, parents) { + return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selected_values = op.selected_values; + var last_search_value = op.last_search_value || ""; + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + last_search_value: BI.last(output) + }) + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (last_search_value !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === last_search_value) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + return output; + } + + function nodeSearch(deep, parent_values, current, isAllSelect, result) { + if (self._isMatch(current, keyword)) { + var checked = isAllSelect || isSelected(parent_values, current); + createOneJson(parent_values, current, false, checked, !isAllSelect && isHalf(parent_values, current), true, result); + return [true, checked]; + } + if (deep >= self.floors) { + return [false, false]; + } + var newParents = BI.clone(parent_values); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + var isCurAllSelected = isAllSelect || isAllSelected(parent_values, current); + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isCurAllSelected || (isSelected(parent_values, current) && checked); + createOneJson(parent_values, current, true, checked, false, false, result); + } + return [can, checked]; + } + + function createOneJson(parent_values, value, isOpen, checked, half, flag, result) { + var node = self.map[value]; + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: parent_values.length + 1 < self.floors, + open: isOpen, + checked: checked, + halfCheck: half, + flag: flag + }); + } + + function isHalf(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parent_values, value) { + var find = findSelectedObj(parent_values); + if (find == null) { + return false; + } + return BI.any(find, function (v) { + if (v === value) { + return true; + } + }); + } + + function findSelectedObj(parent_values) { + var find = selected_values; + if (find == null) { + return null; + } + BI.every(parent_values, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var check_state = op.check_state || {}; + var parent_values = op.parent_values || []; + var selected_values = op.selected_values; + var valueMap = {}; + if (judgeState(parent_values, selected_values, check_state)) { + valueMap = dealWidthSelectedValue(parent_values, selected_values); + } + var nodes = this._getChildren(parent_values); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var state = getCheckState(nodes[i].value, parent_values, valueMap, check_state); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: parent_values.length + 1 < this.floors, + checked: state[0], + halfCheck: state[1] + }) + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function judgeState(parent_values, selected_value, check_state) { + var checked = check_state.checked, half = check_state.half; + if (parent_values.length > 0 && !checked) { + return false; + } + return (parent_values.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); + } + + function dealWidthSelectedValue(parent_values, selected_values) { + var valueMap = {}; + BI.each(parent_values, function (i, v) { + selected_values = selected_values[v]; + }); + BI.each(selected_values, function (value, obj) { + if (BI.isNull(obj)) { + valueMap[value] = [0, 0]; + return; + } + if (BI.isEmpty(obj)) { + valueMap[value] = [2, 0]; + return; + } + var nextNames = {}; + BI.each(obj, function (t, o) { + if (BI.isNull(o) || BI.isEmpty(o)) { + nextNames[t] = true; + } + }); + valueMap[value] = [1, BI.size(nextNames)]; + }); + return valueMap; + } + + function getCheckState(current, parent_values, valueMap, check_state) { + var checked = check_state.checked, half = check_state.half; + var hasChild = parent_values.length + 1 < self.floors; + var tempCheck = false, halfCheck = false; + if (BI.has(valueMap, current)) { + //可能是半选 + if (valueMap[current][0] === 1) { + var values = BI.clone(parent_values); + values.push(current); + if (hasChild && self._getChildCount(values) != valueMap[current][1]) { + halfCheck = true; + } + } else if (valueMap[current][0] === 2) { + tempCheck = true; + } + } + var check; + if (!checked && !halfCheck && !tempCheck) { + check = BI.has(valueMap, current); + } else { + check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); + } + return [check, halfCheck]; + } + }, + + + _buildTree: function (jo, values) { + var t = jo; + BI.each(values, function (i, v) { + if (!BI.has(t, v)) { + t[v] = {}; + } + t = t[v]; + }); + }, + + _isMatch: function (value, keyword) { + var finded = BI.Func.getSearchResult([value], keyword); + return finded.finded.length > 0 || finded.matched.length > 0; + }, + + _getNode: function (v) { + return this.tree.search(v, "value"); + }, + + _getChildren: function (parent_values) { + if (parent_values.length > 0) { + var value = BI.last(parent_values); + var parent = this.tree.search(value, "value"); + } else { + var parent = this.tree.getRoot(); + } + return parent.getChildren(); + }, + + _getChildCount: function (parent_values) { + return this._getChildren(parent_values).length; + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function () { + this.combo.populate.apply(this, arguments); + } +}); +BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; +$.shortcut('bi.tree_value_chooser_combo', BI.TreeValueChooserCombo); \ No newline at end of file diff --git a/src/component/combo.valuechooser.js b/src/component/combo.valuechooser.js new file mode 100644 index 000000000..30ffa1a02 --- /dev/null +++ b/src/component/combo.valuechooser.js @@ -0,0 +1,127 @@ +/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserCombo + * @extends BI.Widget + */ +BI.ValueChooserCombo = BI.inherit(BI.Widget, { + + _const: { + perPage: 10 + }, + _defaultConfig: function () { + return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_combo', + element: this.element, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(self.items)) { + BI.some(self.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; + } + }); + } + return text; + }, + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); + }); + }, + + _getItemsByTimes: function (items, times) { + var res = []; + for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { + res.push(items[i]); + } + return res; + }, + + _hasNextByTimes: function (items, times) { + return times * this._const.perPage < items.length; + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, function (items) { + self.items = items; + call(items); + }); + } else { + call(this.items); + } + function call(items) { + var keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + BI.each(keywords, function (i, kw) { + var search = BI.Func.getSearchResult(items, kw); + items = search.matched.concat(search.finded); + }); + if (options.selected_values) {//过滤 + var filter = BI.makeObject(options.selected_values, true); + items = BI.filter(items, function (i, ob) { + return !filter[ob.value]; + }); + } + if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: items + }); + return; + } + if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({count: items.length}); + return; + } + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + } + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + var val = this.combo.getValue() || {}; + return { + type: val.type, + value: val.value + } + }, + + populate: function () { + this.combo.populate.apply(this, arguments); + } +}); +BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; +$.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo); \ No newline at end of file diff --git a/src/core/alias.js b/src/core/alias.js new file mode 100644 index 000000000..5ec5cd1c6 --- /dev/null +++ b/src/core/alias.js @@ -0,0 +1,591 @@ +BI.cjkEncode = function (text) { + // alex:如果非字符串,返回其本身(cjkEncode(234) 返回 ""是不对的) + if (typeof text !== 'string') { + return text; + } + + var newText = ""; + for (var i = 0; i < text.length; i++) { + var code = text.charCodeAt(i); + if (code >= 128 || code === 91 || code === 93) {//91 is "[", 93 is "]". + newText += "[" + code.toString(16) + "]"; + } else { + newText += text.charAt(i); + } + } + + return newText +}; + +BI.cjkEncodeDO = function (o) { + if (BI.isPlainObject(o)) { + var result = {}; + $.each(o, function (k, v) { + if (!(typeof v == "string")) { + v = BI.jsonEncode(v); + } + //wei:bug 43338,如果key是中文,cjkencode后o的长度就加了1,ie9以下版本死循环,所以新建对象result。 + k = BI.cjkEncode(k); + result[k] = BI.cjkEncode(v); + }); + return result; + } + return o; +}; + +BI.jsonEncode = function (o) { + //james:这个Encode是抄的EXT的 + var useHasOwn = {}.hasOwnProperty ? true : false; + + // crashes Safari in some instances + //var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/; + + var m = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"': '\\"', + "\\": '\\\\' + }; + + var encodeString = function (s) { + if (/["\\\x00-\x1f]/.test(s)) { + return '"' + s.replace(/([\x00-\x1f\\"])/g, function (a, b) { + var c = m[b]; + if (c) { + return c; + } + c = b.charCodeAt(); + return "\\u00" + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }) + '"'; + } + return '"' + s + '"'; + }; + + var encodeArray = function (o) { + var a = ["["], b, i, l = o.length, v; + for (i = 0; i < l; i += 1) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "function": + case "unknown": + break; + default: + if (b) { + a.push(','); + } + a.push(v === null ? "null" : BI.jsonEncode(v)); + b = true; + } + } + a.push("]"); + return a.join(""); + }; + + if (typeof o == "undefined" || o === null) { + return "null"; + } else if (BI.isArray(o)) { + return encodeArray(o); + } else if (o instanceof Date) { + /* + * alex:原来只是把年月日时分秒简单地拼成一个String,无法decode + * 现在这么处理就可以decode了,但是JS.jsonDecode和Java.JSONObject也要跟着改一下 + */ + return BI.jsonEncode({ + __time__: o.getTime() + }) + } else if (typeof o == "string") { + return encodeString(o); + } else if (typeof o == "number") { + return isFinite(o) ? String(o) : "null"; + } else if (typeof o == "boolean") { + return String(o); + } else if (BI.isFunction(o)) { + return String(o); + } else { + var a = ["{"], b, i, v; + for (i in o) { + if (!useHasOwn || o.hasOwnProperty(i)) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "unknown": + break; + default: + if (b) { + a.push(','); + } + a.push(BI.jsonEncode(i), ":", + v === null ? "null" : BI.jsonEncode(v)); + b = true; + } + } + } + a.push("}"); + return a.join(""); + } +}; + +BI.contentFormat = function (cv, fmt) { + if (BI.isEmpty(cv)) { + //原值为空,返回空字符 + return ''; + } + var text = cv.toString(); + if (BI.isEmpty(fmt)) { + //格式为空,返回原字符 + return text; + } + if (fmt.match(/^T/)) { + //T - 文本格式 + return text; + } else if (fmt.match(/^D/)) { + //D - 日期(时间)格式 + if (!(cv instanceof Date)) { + if (typeof cv === 'number') { + //毫秒数类型 + cv = new Date(cv); + } else { + //字符串类型,如yyyyMMdd、MMddyyyy等这样无分隔符的结构 + cv = Date.parseDate(cv + "", Date.patterns.ISO8601Long); + } + } + if (!BI.isNull(cv)) { + var needTrim = fmt.match(/^DT/); + text = BI.date2Str(cv, fmt.substring(needTrim ? 2 : 1)); + } + } else if (fmt.match(/E/)) { + //科学计数格式 + text = BI._eFormat(text, fmt); + } else { + //数字格式 + text = BI._numberFormat(text, fmt); + } + //¤ - 货币格式 + text = text.replace(/¤/g, '¥'); + return text; +}; + +/** + * 把日期对象按照指定格式转化成字符串 + * + * @example + * var date = new Date('Thu Dec 12 2013 00:00:00 GMT+0800'); + * var result = BI.date2Str(date, 'yyyy-MM-dd');//2013-12-12 + * + * @class BI.date2Str + * @param date 日期 + * @param format 日期格式 + * @returns {String} + */ +date2Str = function (date, format) { + if (!date) { + return ''; + } + // O(len(format)) + var len = format.length, result = ''; + if (len > 0) { + var flagch = format.charAt(0), start = 0, str = flagch; + for (var i = 1; i < len; i++) { + var ch = format.charAt(i); + if (flagch !== ch) { + result += compileJFmt({ + 'char': flagch, + 'str': str, + 'len': i - start + }, date); + flagch = ch; + start = i; + str = flagch; + } else { + str += ch; + } + } + result += compileJFmt({ + 'char': flagch, + 'str': str, + 'len': len - start + }, date); + } + return result; + + function compileJFmt(jfmt, date) { + var str = jfmt.str, len = jfmt.len, ch = jfmt['char']; + switch (ch) { + case 'E': //星期 + str = Date._DN[date.getDay()]; + break; + case 'y': //年 + if (len <= 3) { + str = (date.getFullYear() + '').slice(2, 4); + } else { + str = date.getFullYear(); + } + break; + case 'M': //月 + if (len > 2) { + str = Date._MN[date.getMonth()]; + } else if (len < 2) { + str = date.getMonth() + 1; + } else { + str = String.leftPad(date.getMonth() + 1 + '', 2, '0'); + } + break; + case 'd': //日 + if (len > 1) { + str = String.leftPad(date.getDate() + '', 2, '0'); + } else { + str = date.getDate(); + } + break; + case 'h': //时(12) + var hour = date.getHours() % 12; + if (hour === 0) { + hour = 12; + } + if (len > 1) { + str = String.leftPad(hour + '', 2, '0'); + } else { + str = hour; + } + break; + case 'H': //时(24) + if (len > 1) { + str = String.leftPad(date.getHours() + '', 2, '0'); + } else { + str = date.getHours(); + } + break; + case 'm': + if (len > 1) { + str = String.leftPad(date.getMinutes() + '', 2, '0'); + } else { + str = date.getMinutes(); + } + break; + case 's': + if (len > 1) { + str = String.leftPad(date.getSeconds() + '', 2, '0'); + } else { + str = date.getSeconds(); + } + break; + case 'a': + str = date.getHours() < 12 ? 'am' : 'pm'; + break; + case 'z': + str = date.getTimezone(); + break; + default: + str = jfmt.str; + break; + } + return str; + } +}; + +/** + * 数字格式 + */ +BI._numberFormat = function (text, format) { + var text = text + ''; + //数字格式,区分正负数 + var numMod = format.indexOf(';'); + if (numMod > -1) { + if (text >= 0) { + return BI._numberFormat(text + "", format.substring(0, numMod)); + } else { + return BI._numberFormat((-text) + "", format.substr(numMod + 1)); + } + } + var tp = text.split('.'), fp = format.split('.'), + tleft = tp[0] || '', fleft = fp[0] || '', + tright = tp[1] || '', fright = fp[1] || ''; + //百分比,千分比的小数点移位处理 + if (/[%‰]$/.test(format)) { + var paddingZero = /[%]$/.test(format) ? '00' : '000'; + tright += paddingZero; + tleft += tright.substr(0, paddingZero.length); + tleft = tleft.replace(/^0+/gi, ''); + tright = tright.substr(paddingZero.length).replace(/0+$/gi, ''); + } + var right = BI._dealWithRight(tright, fright); + if (right.leftPlus) { + //小数点后有进位 + tleft = parseInt(tleft) + 1 + ''; + + tleft = isNaN(tleft) ? '1' : tleft; + } + right = right.num; + var left = BI._dealWithLeft(tleft, fleft); + if (!(/[0-9]/.test(left))) { + left = left + '0'; + } + if (!(/[0-9]/.test(right))) { + return left + right; + } else { + return left + '.' + right; + } +}; +/** + * 处理小数点右边小数部分 + * @param tright 右边内容 + * @param fright 右边格式 + * @returns {JSON} 返回处理结果和整数部分是否需要进位 + * @private + */ +BI._dealWithRight = function (tright, fright) { + var right = '', j = 0, i = 0; + for (var len = fright.length; i < len; i++) { + var ch = fright.charAt(i); + var c = tright.charAt(j); + switch (ch) { + case '0': + if (BI.isEmpty(c)) { + c = '0'; + } + right += c; + j++; + break; + case '#': + right += c; + j++; + break; + default : + right += ch; + break; + } + } + var rll = tright.substr(j); + var result = {}; + if (!BI.isEmpty(rll) && rll.charAt(0) > 4) { + //有多余字符,需要四舍五入 + result.leftPlus = true; + var numReg = right.match(/^[0-9]+/); + if (numReg) { + var num = numReg[0]; + var orilen = num.length; + var newnum = BI.parseINT(num) + 1 + ''; + //进位到整数部分 + if (newnum.length > orilen) { + newnum = newnum.substr(1); + } else { + newnum = BI.leftPad(newnum, orilen, '0'); + result.leftPlus = false; + } + right = right.replace(/^[0-9]+/, newnum); + } + } + result.num = right; + return result; +}; + +BI.parseINT = function (str) { + return parseInt(str, 10); +}; + +BI.leftPad = function (val, size, ch) { + var result = String(val); + if (!ch) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result.toString(); +}; + +/** + * 处理小数点左边整数部分 + * @param tleft 左边内容 + * @param fleft 左边格式 + * @returns {string} 返回处理结果 + * @private + */ +BI._dealWithLeft = function (tleft, fleft) { + var left = ''; + var j = tleft.length - 1; + var combo = -1, last = -1; + var i = fleft.length - 1; + for (; i >= 0; i--) { + var ch = fleft.charAt(i); + var c = tleft.charAt(j); + switch (ch) { + case '0': + if (BI.isEmpty(c)) { + c = '0'; + } + last = -1; + left = c + left; + j--; + break; + case '#': + last = i; + left = c + left; + j--; + break; + case ',': + if (!BI.isEmpty(c)) { + //计算一个,分隔区间的长度 + var com = fleft.match(/,[#0]+/); + if (com) { + combo = com[0].length - 1; + } + left = ',' + left; + } + break; + default : + left = ch + left; + break; + } + } + if (last > -1) { + //处理剩余字符 + var tll = tleft.substr(0, j + 1); + left = left.substr(0, last) + tll + left.substr(last); + } + if (combo > 0) { + //处理,分隔区间 + var res = left.match(/[0-9]+,/); + if (res) { + res = res[0]; + var newstr = '', n = res.length - 1 - combo; + for (; n >= 0; n = n - combo) { + newstr = res.substr(n, combo) + ',' + newstr; + } + var lres = res.substr(0, n + combo); + if (!BI.isEmpty(lres)) { + newstr = lres + ',' + newstr; + } + } + left = left.replace(/[0-9]+,/, newstr); + } + return left; +}; + +BI.object2Number = function (value) { + if (value == null) { + return 0; + } + if (typeof value == 'number') { + return value; + } else { + var str = value + ""; + if (str.indexOf(".") === -1) { + return parseInt(str); + } else { + return parseFloat(str); + } + } +}; + +BI.object2Date = function (obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } else if (typeof obj == 'number') { + return new Date(obj); + } else { + var str = obj + ""; + str = str.replace(/-/g, '/'); + var dt = new Date(str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + + return new Date(); + } +}; + +BI.isArray = function (a) { + return Object.prototype.toString.call(a) == '[object Array]'; +}; + +BI.object2Time = function (obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } else { + var str = obj + ""; + str = str.replace(/-/g, '/'); + var dt = new Date(str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + if (str.indexOf('/') === -1 && str.indexOf(':') !== -1) { + dt = new Date("1970/01/01 " + str); + if (!BI.isInvalidDate(dt)) { + return dt; + } + } + dt = BI.str2Date(str, "HH:mm:ss"); + if (!BI.isInvalidDate(dt)) { + return dt; + } + return new Date(); + } +}; + +// 判断是否是无效的日期 +BI.isInvalidDate = function (date) { + return date == "Invalid Date" || date == "NaN"; +}; + + +/** + * 科学计数格式 + */ +BI._eFormat = function (text, fmt) { + var e = fmt.indexOf("E"); + var eleft = fmt.substr(0, e), eright = fmt.substr(e + 1); + if (/^[0\.-]+$/.test(text)) { + text = BI._numberFormat(0.0, eleft) + 'E' + BI._numberFormat(0, eright) + } else { + var isNegative = text < 0; + if (isNegative) { + text = text.substr(1); + } + var elvl = (eleft.split('.')[0] || '').length; + var point = text.indexOf("."); + if (point < 0) { + point = text.length; + } + var i = 0; //第一个不为0的数的位置 + text = text.replace('.', ''); + for (var len = text.length; i < len; i++) { + var ech = text.charAt(i); + if (ech <= '9' && ech >= '1') { + break; + } + } + var right = point - i - elvl; + var left = text.substr(i, elvl); + var dis = i + elvl - text.length; + if (dis > 0) { + //末位补全0 + for (var k = 0; k < dis; k++) { + left += '0'; + } + } else { + left += '.' + text.substr(i + elvl); + } + left = left.replace(/^[0]+/, ''); + if (right < 0 && eright.indexOf('-') < 0) { + eright += ';-' + eright; + } + text = BI._numberFormat(left, eleft) + 'E' + BI._numberFormat(right, eright); + if (isNegative) { + text = '-' + text; + } + } + return text; +}; \ No newline at end of file diff --git a/src/core/base.js b/src/core/base.js index aa33e64a3..b337e5e67 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -81,30 +81,6 @@ if (!window.BI) { return widget instanceof BI.Widget || (BI.View && widget instanceof BI.View); }, - createWidget: function (item, options) { - var el; - options || (options = {}); - if (BI.isEmpty(item) && BI.isEmpty(options)) { - return BI.Plugin.getObject("bi.layout", BI.createWidget({ - type: "bi.layout" - })); - } - if (BI.isWidget(item)) { - return item; - } - if (item && (item.type || options.type)) { - el = BI.extend({}, options, item); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && item.el && (item.el.type || options.type)) { - el = BI.extend({}, options, item.el); - return BI.Plugin.getObject(el.type, FR.createWidget(BI.Plugin.getWidget(el.type, el), true)); - } - if (item && BI.isWidget(item.el)) { - return item.el; - } - }, - createWidgets: function (items, options) { if (!BI.isArray(items)) { throw new Error("cannot create Widgets") @@ -929,10 +905,6 @@ if (!window.BI) { return BI.isString(str) && BI.isEmpty(str); }, - contentFormat: function () { - return FR.contentFormat.apply(FR, arguments); - }, - /** * 对字符串进行加密 {@link #decrypt} * @static @@ -1126,7 +1098,12 @@ if (!window.BI) { } timeoutToast.addReq(option); - FR.ajax({ + + option.data = BI.cjkEncodeDO(option.data); + + + + $.ajax({ url: option.url, type: "POST", data: option.data, @@ -1181,10 +1158,10 @@ if (!window.BI) { loading.showError(); } else if (status === "success" && BI.isFunction(option.success)) { - option.success(FR.jsonDecode(res.responseText)); + option.success(BI.jsonDecode(res.responseText)); } if (BI.isFunction(option.complete)) { - option.complete(FR.jsonDecode(res.responseText), status); + option.complete(BI.jsonDecode(res.responseText), status); } } }); @@ -1196,7 +1173,7 @@ if (!window.BI) { function encodeBIParam(data) { for (var key in data) { if (_.isObject(data[key])) { - data[key] = window.encodeURIComponent(FR.jsonEncode(data[key])); + data[key] = window.encodeURIComponent(BI.jsonEncode(data[key])); } else { data[key] = window.encodeURIComponent(data[key]); } @@ -1207,7 +1184,7 @@ if (!window.BI) { for (var key in data) { data[key] = window.decodeURIComponent(data[key]); if (_.isObject(data[key])) { - data[key] = FR.jsonDecode(data[key]); + data[key] = BI.jsonDecode(data[key]); } } } @@ -1230,7 +1207,7 @@ if (!window.BI) { if (op === "fr_bi_dezi" || op === "fr_bi_configure") { data.sessionID = Data.SharingPool.get("sessionID"); } - var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); + var url = BI.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); return (BI.ajax)({ url: url, type: 'POST', @@ -1266,7 +1243,7 @@ if (!window.BI) { if (op === "fr_bi_dezi") { data.sessionID = Data.SharingPool.get("sessionID"); } - var url = FR.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); + var url = BI.servletURL + '?op=' + op + '&cmd=' + cmd + "&_=" + Math.random(); var result = {}; (BI.ajax)({ url: url, diff --git a/src/core/func/function.js b/src/core/func/function.js index 6fbcfa0e3..b7e5d248a 100644 --- a/src/core/func/function.js +++ b/src/core/func/function.js @@ -121,7 +121,7 @@ $(function () { }, getCompleteImageUrl: function (url) { - return FR.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + url; + return BI.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + url; } }); diff --git a/src/core/model.js b/src/core/model.js index 3eb719537..3c8554895 100644 --- a/src/core/model.js +++ b/src/core/model.js @@ -377,7 +377,7 @@ BI.Model = BI.inherit(BI.M, { }, urlRoot: function () { - return FR.servletURL; + return BI.servletURL; }, parse: function (data) { diff --git a/src/core/utils/load.js b/src/core/utils/load.js index 0821a48fb..a036152f7 100644 --- a/src/core/utils/load.js +++ b/src/core/utils/load.js @@ -8,7 +8,7 @@ $.extend(BI, { type: null, must: false }, options); - config.url = FR.servletURL + '?op=' + config.op + '&resource=' + config.path; + config.url = BI.servletURL + '?op=' + config.op + '&resource=' + config.path; this.$import(config.url, config.type,config.must); }, $import: function () { diff --git a/src/css/base/third/farbtastic/farbtastic.css b/src/css/base/third/farbtastic/farbtastic.css index 2c4306d8f..76e8942fa 100644 --- a/src/css/base/third/farbtastic/farbtastic.css +++ b/src/css/base/third/farbtastic/farbtastic.css @@ -36,17 +36,17 @@ height: 101px; } .farbtastic .wheel { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/wheel.png) no-repeat; + background: url(farbtastic/wheel.png) no-repeat; width: 195px; height: 195px; } .farbtastic .overlay { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/mask.png) no-repeat; + background: url(farbtastic/mask.png) no-repeat; } .farbtastic .marker { width: 17px; height: 17px; margin: -8px 0 0 -8px; overflow: hidden; - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/marker.png) no-repeat; + background: url(farbtastic/marker.png) no-repeat; } diff --git a/src/css/base/third/ztree/zTreeStyle.css b/src/css/base/third/ztree/zTreeStyle.css index 1ac2cf043..ec763cae5 100644 --- a/src/css/base/third/ztree/zTreeStyle.css +++ b/src/css/base/third/ztree/zTreeStyle.css @@ -29,7 +29,7 @@ website: http://code.google.com/p/jquerytree/ padding: 0 0 0 18px; } .ztree li ul.line { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y; + background: url(icon/tree-vertical-line-1.png) 0 0 repeat-y; } .ztree li a { padding: 1px 3px 0 0; @@ -84,8 +84,8 @@ website: http://code.google.com/p/jquerytree/ background-color: transparent; background-repeat: no-repeat; background-attachment: scroll; - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); - *background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif"); + background-image: url("ztree/img/zTreeStandard.png"); + *background-image: url("ztree/img/zTreeStandard.gif"); } .ztree li span.button.chk { width: 16px; @@ -94,31 +94,31 @@ website: http://code.google.com/p/jquerytree/ cursor: auto; } .ztree li span.button.chk.checkbox_false_full { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image: url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image: url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable { background-position: 0 -56px; } .ztree li span.button.chk.checkbox_true_full { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image: url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image: url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image: url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable { background-position: -14px -56px; @@ -158,28 +158,28 @@ website: http://code.google.com/p/jquerytree/ height: 25px; } .ztree li span.button.root_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); + background-image: url("icon/tree-expand-1.png"); } .ztree li span.button.root_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); + background-image: url("icon/tree-collapse-1.png"); } .ztree li span.button.roots_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); + background-image: url("icon/tree-expand-2.png"); } .ztree li span.button.roots_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); + background-image: url("icon/tree-collapse-2.png"); } .ztree li span.button.center_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); + background-image: url("icon/tree-expand-3.png"); } .ztree li span.button.center_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); + background-image: url("icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); + background-image: url("icon/tree-expand-4.png"); } .ztree li span.button.bottom_close { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); + background-image: url("icon/tree-collapse-4.png"); } .ztree li span.button.noline_open { background-position: -92px -72px; @@ -191,13 +191,13 @@ website: http://code.google.com/p/jquerytree/ background: none; } .ztree li span.button.roots_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); + background-image: url("icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); + background-image: url("icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu { - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); + background-image: url("icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu { background: none; @@ -235,7 +235,7 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.ico_loading { width: 0px; margin-right: 2px; - background: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif") no-repeat scroll 0 0 transparent; + background: url("ztree/img/loading.gif") no-repeat scroll 0 0 transparent; vertical-align: top; *vertical-align: middle; } @@ -256,8 +256,8 @@ span.tmpzTreeMove_arrow { background-repeat: no-repeat; background-attachment: scroll; background-position: -110px -80px; - background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); - *background-image: url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif"); + background-image: url("ztree/img/zTreeStandard.png"); + *background-image: url("ztree/img/zTreeStandard.gif"); } ul.ztree.zTreeDragUL { margin: 0; diff --git a/src/css/base/view/popupview.css b/src/css/base/view/popupview.css index 0294fa968..79efbe2dd 100644 --- a/src/css/base/view/popupview.css +++ b/src/css/base/view/popupview.css @@ -1,7 +1,7 @@ /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ -/**********FR.BIListView*************/ +/**********BI.BIListView*************/ .bi-list-view { position: fixed !important; overflow-y: visible !important; diff --git a/src/less/base/third/farbtastic/farbtastic.less b/src/less/base/third/farbtastic/farbtastic.less index 739bf6f02..a41494966 100644 --- a/src/less/base/third/farbtastic/farbtastic.less +++ b/src/less/base/third/farbtastic/farbtastic.less @@ -34,18 +34,18 @@ height: 101px; } .farbtastic .wheel { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/wheel.png) no-repeat; + background: url(farbtastic/wheel.png) no-repeat; width: 195px; height: 195px; } .farbtastic .overlay { - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/mask.png) no-repeat; + background: url(farbtastic/mask.png) no-repeat; } .farbtastic .marker { width: 17px; height: 17px; margin: -8px 0 0 -8px; - overflow: hidden; - background: url(${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/farbtastic/marker.png) no-repeat; + overflow: hidden; + background: url(farbtastic/marker.png) no-repeat; } diff --git a/src/less/base/third/ztree/zTreeStyle.less b/src/less/base/third/ztree/zTreeStyle.less index 5a94e0230..6e625f2ac 100644 --- a/src/less/base/third/ztree/zTreeStyle.less +++ b/src/less/base/third/ztree/zTreeStyle.less @@ -12,7 +12,7 @@ website: http://code.google.com/p/jquerytree/ .ztree {margin:0; padding:5px; } .ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} .ztree li ul{ margin:0; padding:0 0 0 18px} -.ztree li ul.line{ background:url(${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-1.png) 0 0 repeat-y;} +.ztree li ul.line{ background:url(icon/tree-vertical-line-1.png) 0 0 repeat-y;} .ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:24px; background-color: transparent; text-decoration:none; vertical-align:top; display: inline-block} @@ -28,33 +28,33 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; border:0 none; cursor: pointer;outline:none; background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); *background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif")} + background-image:url("ztree/img/zTreeStandard.png"); *background-image:url("ztree/img/zTreeStandard.gif")} .ztree li span.button.chk {width:16px; height:16px; margin:0 3px 0 0; cursor: auto} .ztree li span.button.chk.checkbox_false_full { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image:url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_full_focus { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-normal.png"); + background-image:url("icon/check-box-normal.png"); } .ztree li span.button.chk.checkbox_false_part { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image:url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_part_focus { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image:url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} .ztree li span.button.chk.checkbox_true_full { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image:url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_full_focus { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/check-box-active.png"); + background-image:url("icon/check-box-active.png"); } .ztree li span.button.chk.checkbox_true_part { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image:url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_part_focus { - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/half_selected.png"); + background-image:url("icon/half_selected.png"); } .ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} .ztree li span.button.chk.radio_false_full {background-position:-28px 0} @@ -70,40 +70,40 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.switch {width:25px; height:25px} .ztree li span.button.root_open{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-1.png"); + background-image:url("icon/tree-expand-1.png"); } .ztree li span.button.root_close{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-1.png"); + background-image:url("icon/tree-collapse-1.png"); } .ztree li span.button.roots_open{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-2.png"); + background-image:url("icon/tree-expand-2.png"); } .ztree li span.button.roots_close{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-2.png"); + background-image:url("icon/tree-collapse-2.png"); } .ztree li span.button.center_open{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-3.png"); + background-image:url("icon/tree-expand-3.png"); } .ztree li span.button.center_close{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-3.png"); + background-image:url("icon/tree-collapse-3.png"); } .ztree li span.button.bottom_open{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-expand-4.png"); + background-image:url("icon/tree-expand-4.png"); } .ztree li span.button.bottom_close{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-collapse-4.png"); + background-image:url("icon/tree-collapse-4.png"); } .ztree li span.button.noline_open{background-position:-92px -72px} .ztree li span.button.noline_close{background-position:-74px -72px} .ztree li span.button.root_docu{ background:none;} .ztree li span.button.roots_docu{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-2.png"); + background-image:url("icon/tree-vertical-line-2.png"); } .ztree li span.button.center_docu{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-3.png"); + background-image:url("icon/tree-vertical-line-3.png"); } .ztree li span.button.bottom_docu{ - background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/images/icon/tree-vertical-line-4.png"); + background-image:url("icon/tree-vertical-line-4.png"); } .ztree li span.button.noline_docu{ background:none;} @@ -113,13 +113,13 @@ website: http://code.google.com/p/jquerytree/ .ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} .ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} -.ztree li span.button.ico_loading{width: 0px;margin-right:2px; background:url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_loading{width: 0px;margin-right:2px; background:url("ztree/img/loading.gif") no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; - background-position:-110px -80px; background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.png"); *background-image:url("${servletURL}?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/zTreeStandard.gif")} + background-position:-110px -80px; background-image:url("ztree/img/zTreeStandard.png"); *background-image:url("ztree/img/zTreeStandard.gif")} ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} .zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} diff --git a/src/less/base/view/popupview.less b/src/less/base/view/popupview.less index 79bc39e2e..74b58045b 100644 --- a/src/less/base/view/popupview.less +++ b/src/less/base/view/popupview.less @@ -1,7 +1,7 @@ @import "../../bibase"; -/**********FR.BIListView*************/ +/**********BI.BIListView*************/ .bi-list-view { position: fixed !important; overflow-y: visible !important; diff --git a/src/widget/image/uploadimage.js b/src/widget/image/uploadimage.js index c9ca03231..7d30adc08 100644 --- a/src/widget/image/uploadimage.js +++ b/src/widget/image/uploadimage.js @@ -268,7 +268,7 @@ BI.UploadImage = BI.inherit(BI.Widget, { BI.extend(BI.UploadImage, { getImageSrc: function (src) { - return FR.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + src; + return BI.servletURL + "?op=fr_bi&cmd=get_uploaded_image&image_id=" + src; } }); From 828d4b04fcdea047f396210eb65961c1905b012f Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 18:09:47 +0800 Subject: [PATCH 16/19] add --- demo.html | 2 -- dist/base.js | 11 ++++++++--- dist/core.js | 16 ++++++++-------- src/base/combination/tab.js | 10 +++++++--- src/base/single/bar/bar.loading.js | 1 + src/core/controller/controller.layer.js | 1 + src/core/widget.js | 5 +++-- src/core/wrapper/layout/layout.card.js | 10 ++++------ 8 files changed, 32 insertions(+), 24 deletions(-) diff --git a/demo.html b/demo.html index ffc2d3dfb..b58f30610 100644 --- a/demo.html +++ b/demo.html @@ -22,7 +22,5 @@
      - \ No newline at end of file diff --git a/dist/base.js b/dist/base.js index bbb5ca2a2..23d126675 100644 --- a/dist/base.js +++ b/dist/base.js @@ -24962,9 +24962,6 @@ BI.Tab = BI.inherit(BI.Widget, { listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); }); - if (o.defaultShowIndex !== false) { - this.setSelect(o.defaultShowIndex); - } }, _assertCard: function (v) { @@ -24975,6 +24972,13 @@ BI.Tab = BI.inherit(BI.Widget, { } }, + mounted: function () { + var o = this.options; + if (o.defaultShowIndex !== false) { + this.setSelect(o.defaultShowIndex); + } + }, + setSelect: function (v) { this.tab && this.tab.setValue(v); this._assertCard(v); @@ -36274,6 +36278,7 @@ BI.LoadingBar = BI.inherit(BI.Single, { this.loading = BI.createWidget({ type: "bi.layout", + width: this.options.height, height:this.options.height, cls: "loading-background cursor-default" }) diff --git a/dist/core.js b/dist/core.js index fc0061fc5..a3529c3a3 100644 --- a/dist/core.js +++ b/dist/core.js @@ -14434,7 +14434,7 @@ BI.Widget = BI.inherit(BI.OB, { }) }) } - if (this._isRoot === true) { + if (this._isRoot === true || (!(this instanceof BI.Layout) && (this._parent && this._parent._isMounted))) { this._mount(); } }, @@ -14446,7 +14446,7 @@ BI.Widget = BI.inherit(BI.OB, { _mount: function () { var self = this; var isMounted = this._isMounted; - if (isMounted) { + if (isMounted || !this.isVisible()) { return; } if (this._isRoot === true) { @@ -14515,6 +14515,7 @@ BI.Widget = BI.inherit(BI.OB, { if (visible === true) { this.options.invisible = false; this.element.show(); + this._mount(); } else if (visible === false) { this.options.invisible = true; this.element.hide(); @@ -20831,6 +20832,7 @@ BI.LayerController = BI.inherit(BI.Controller, { return this; } this._getLayout(name).visible(); + this._getLayout(name)._mount(); this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); return this; }, @@ -26629,7 +26631,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { return widget; }, - showCardByName: function (name, action, callback) { + showCardByName: function (name, action) { var self = this; //name不存在的时候全部隐藏 var exist = this.hasWidget(this._getCardName(name)); @@ -26641,12 +26643,9 @@ BI.CardLayout = BI.inherit(BI.Layout, { BI.each(this._children, function (i, el) { if (self._getCardName(name) != i) { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 - !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.element.hide(); + !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.invisible(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, function () { - el._mount(); - callback && callback(); - }); + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), el._mount()) } }); }, @@ -26659,6 +26658,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { el.element.hide(); } else { el.element.show(); + el._mount(); } }) }, diff --git a/src/base/combination/tab.js b/src/base/combination/tab.js index f12d3a150..68fe75c1a 100644 --- a/src/base/combination/tab.js +++ b/src/base/combination/tab.js @@ -53,9 +53,6 @@ BI.Tab = BI.inherit(BI.Widget, { listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); }); - if (o.defaultShowIndex !== false) { - this.setSelect(o.defaultShowIndex); - } }, _assertCard: function (v) { @@ -66,6 +63,13 @@ BI.Tab = BI.inherit(BI.Widget, { } }, + mounted: function () { + var o = this.options; + if (o.defaultShowIndex !== false) { + this.setSelect(o.defaultShowIndex); + } + }, + setSelect: function (v) { this.tab && this.tab.setValue(v); this._assertCard(v); diff --git a/src/base/single/bar/bar.loading.js b/src/base/single/bar/bar.loading.js index a02c8665e..ae88b834e 100644 --- a/src/base/single/bar/bar.loading.js +++ b/src/base/single/bar/bar.loading.js @@ -32,6 +32,7 @@ BI.LoadingBar = BI.inherit(BI.Single, { this.loading = BI.createWidget({ type: "bi.layout", + width: this.options.height, height:this.options.height, cls: "loading-background cursor-default" }) diff --git a/src/core/controller/controller.layer.js b/src/core/controller/controller.layer.js index ae798aca9..c1625653c 100644 --- a/src/core/controller/controller.layer.js +++ b/src/core/controller/controller.layer.js @@ -127,6 +127,7 @@ BI.LayerController = BI.inherit(BI.Controller, { return this; } this._getLayout(name).visible(); + this._getLayout(name)._mount(); this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); return this; }, diff --git a/src/core/widget.js b/src/core/widget.js index 54de57d74..859e21e1e 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -135,7 +135,7 @@ BI.Widget = BI.inherit(BI.OB, { }) }) } - if (this._isRoot === true) { + if (this._isRoot === true || (!(this instanceof BI.Layout) && (this._parent && this._parent._isMounted))) { this._mount(); } }, @@ -147,7 +147,7 @@ BI.Widget = BI.inherit(BI.OB, { _mount: function () { var self = this; var isMounted = this._isMounted; - if (isMounted) { + if (isMounted || !this.isVisible()) { return; } if (this._isRoot === true) { @@ -216,6 +216,7 @@ BI.Widget = BI.inherit(BI.OB, { if (visible === true) { this.options.invisible = false; this.element.show(); + this._mount(); } else if (visible === false) { this.options.invisible = true; this.element.hide(); diff --git a/src/core/wrapper/layout/layout.card.js b/src/core/wrapper/layout/layout.card.js index 910866da1..aa9db36c3 100644 --- a/src/core/wrapper/layout/layout.card.js +++ b/src/core/wrapper/layout/layout.card.js @@ -86,7 +86,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { return widget; }, - showCardByName: function (name, action, callback) { + showCardByName: function (name, action) { var self = this; //name不存在的时候全部隐藏 var exist = this.hasWidget(this._getCardName(name)); @@ -98,12 +98,9 @@ BI.CardLayout = BI.inherit(BI.Layout, { BI.each(this._children, function (i, el) { if (self._getCardName(name) != i) { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 - !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.element.hide(); + !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.invisible(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : el.element.show(0, function () { - el._mount(); - callback && callback(); - }); + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), el._mount()) } }); }, @@ -116,6 +113,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { el.element.hide(); } else { el.element.show(); + el._mount(); } }) }, From 2f3104fa9882a9d697202e6bb498fd451fbec470 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 20:03:10 +0800 Subject: [PATCH 17/19] add --- dist/core.js | 2 +- dist/widget.js | 2 +- src/core/widget.js | 2 +- src/widget/multitree/multi.tree.popup.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/core.js b/dist/core.js index a3529c3a3..3287c4ace 100644 --- a/dist/core.js +++ b/dist/core.js @@ -14434,7 +14434,7 @@ BI.Widget = BI.inherit(BI.OB, { }) }) } - if (this._isRoot === true || (!(this instanceof BI.Layout) && (this._parent && this._parent._isMounted))) { + if (this._isRoot === true || !(this instanceof BI.Layout)) { this._mount(); } }, diff --git a/dist/widget.js b/dist/widget.js index d3839ccaa..4452fe23e 100644 --- a/dist/widget.js +++ b/dist/widget.js @@ -19927,7 +19927,7 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { baseCls: 'bi-multi-tree-popup', maxWidth: 'auto', minWidth: 100, - maxHeight: 250, + maxHeight: 400, onLoaded: BI.emptyFn }); }, diff --git a/src/core/widget.js b/src/core/widget.js index 859e21e1e..d894fcef5 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -135,7 +135,7 @@ BI.Widget = BI.inherit(BI.OB, { }) }) } - if (this._isRoot === true || (!(this instanceof BI.Layout) && (this._parent && this._parent._isMounted))) { + if (this._isRoot === true || !(this instanceof BI.Layout)) { this._mount(); } }, diff --git a/src/widget/multitree/multi.tree.popup.js b/src/widget/multitree/multi.tree.popup.js index 0cda736ed..35c4f4f5f 100644 --- a/src/widget/multitree/multi.tree.popup.js +++ b/src/widget/multitree/multi.tree.popup.js @@ -10,7 +10,7 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { baseCls: 'bi-multi-tree-popup', maxWidth: 'auto', minWidth: 100, - maxHeight: 250, + maxHeight: 400, onLoaded: BI.emptyFn }); }, From effedd3064409c46f1d43fd0c081447cd3e060dd Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 20:03:45 +0800 Subject: [PATCH 18/19] add --- dist/core.js | 1 - src/core/controller/controller.layer.js | 1 - 2 files changed, 2 deletions(-) diff --git a/dist/core.js b/dist/core.js index 3287c4ace..41fda0c12 100644 --- a/dist/core.js +++ b/dist/core.js @@ -20832,7 +20832,6 @@ BI.LayerController = BI.inherit(BI.Controller, { return this; } this._getLayout(name).visible(); - this._getLayout(name)._mount(); this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); return this; }, diff --git a/src/core/controller/controller.layer.js b/src/core/controller/controller.layer.js index c1625653c..ae798aca9 100644 --- a/src/core/controller/controller.layer.js +++ b/src/core/controller/controller.layer.js @@ -127,7 +127,6 @@ BI.LayerController = BI.inherit(BI.Controller, { return this; } this._getLayout(name).visible(); - this._getLayout(name)._mount(); this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); return this; }, From 06ac37382222577f40712c66d11150d0d05ff84c Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 22 Mar 2017 20:39:05 +0800 Subject: [PATCH 19/19] add --- dist/base.js | 8 ++++---- dist/core.js | 26 ++++++++++++++++++-------- src/base/combination/group.button.js | 8 ++++---- src/core/wrapper/layout.js | 15 +++++++++++++++ src/core/wrapper/layout/layout.card.js | 11 +++-------- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/dist/base.js b/dist/base.js index 23d126675..9eebd0e85 100644 --- a/dist/base.js +++ b/dist/base.js @@ -21353,8 +21353,8 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { return; } - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().prependTo(this.element); + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.prependItems(this._packageLayout(items).items); }, addItems: function (items) { @@ -21369,8 +21369,8 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { return; } - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().appendTo(this.element); + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.addItems(this._packageLayout(items).items); }, removeItemAt: function (indexes) { diff --git a/dist/core.js b/dist/core.js index 41fda0c12..d86dd053a 100644 --- a/dist/core.js +++ b/dist/core.js @@ -19363,6 +19363,14 @@ BI.Layout = BI.inherit(BI.Widget, { return w; }, + prependItem: function (item) { + var w = this._addElement(this.options.items.length, item); + w._mount(); + this.options.items.unshift(item); + w.element.prependTo(this.element); + return w; + }, + addItems: function (items) { var self = this; BI.each(items, function (i, item) { @@ -19370,6 +19378,13 @@ BI.Layout = BI.inherit(BI.Widget, { }) }, + prependItems: function (items) { + var self = this; + BI.each(items, function (i, item) { + self.prependItem(item); + }) + }, + getValue: function () { var value = []; BI.each(this._children, function (i, wi) { @@ -26630,7 +26645,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { return widget; }, - showCardByName: function (name, action) { + showCardByName: function (name, action, callback) { var self = this; //name不存在的时候全部隐藏 var exist = this.hasWidget(this._getCardName(name)); @@ -26644,7 +26659,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.invisible(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), el._mount()) + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), callback && callback()) } }); }, @@ -26653,12 +26668,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { var self = this; this.showIndex = this.lastShowIndex; BI.each(this._children, function (i, el) { - if (self.showIndex != i) { - el.element.hide(); - } else { - el.element.show(); - el._mount(); - } + el.setVisible(self.showIndex == i); }) }, diff --git a/src/base/combination/group.button.js b/src/base/combination/group.button.js index a1f36155e..b6ef3be0b 100644 --- a/src/base/combination/group.button.js +++ b/src/base/combination/group.button.js @@ -126,8 +126,8 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { return; } - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().prependTo(this.element); + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.prependItems(this._packageLayout(items).items); }, addItems: function (items) { @@ -142,8 +142,8 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { return; } - var items = this._packageItems(items, this._packageBtns(btns)); - BI.createWidget(BI.extend(this._packageLayout(items))).element.children().appendTo(this.element); + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.addItems(this._packageLayout(items).items); }, removeItemAt: function (indexes) { diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js index 76b9db127..5c19c92b5 100644 --- a/src/core/wrapper/layout.js +++ b/src/core/wrapper/layout.js @@ -106,6 +106,14 @@ BI.Layout = BI.inherit(BI.Widget, { return w; }, + prependItem: function (item) { + var w = this._addElement(this.options.items.length, item); + w._mount(); + this.options.items.unshift(item); + w.element.prependTo(this.element); + return w; + }, + addItems: function (items) { var self = this; BI.each(items, function (i, item) { @@ -113,6 +121,13 @@ BI.Layout = BI.inherit(BI.Widget, { }) }, + prependItems: function (items) { + var self = this; + BI.each(items, function (i, item) { + self.prependItem(item); + }) + }, + getValue: function () { var value = []; BI.each(this._children, function (i, wi) { diff --git a/src/core/wrapper/layout/layout.card.js b/src/core/wrapper/layout/layout.card.js index aa9db36c3..08869e4ab 100644 --- a/src/core/wrapper/layout/layout.card.js +++ b/src/core/wrapper/layout/layout.card.js @@ -86,7 +86,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { return widget; }, - showCardByName: function (name, action) { + showCardByName: function (name, action, callback) { var self = this; //name不存在的时候全部隐藏 var exist = this.hasWidget(this._getCardName(name)); @@ -100,7 +100,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { //动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.invisible(); } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), el._mount()) + (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), callback && callback()) } }); }, @@ -109,12 +109,7 @@ BI.CardLayout = BI.inherit(BI.Layout, { var self = this; this.showIndex = this.lastShowIndex; BI.each(this._children, function (i, el) { - if (self.showIndex != i) { - el.element.hide(); - } else { - el.element.show(); - el._mount(); - } + el.setVisible(self.showIndex == i); }) },

      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