rsence 2.1.11 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL.rdoc +5 -3
- data/README.rdoc +23 -22
- data/VERSION +1 -1
- data/conf/default_conf.yaml +65 -29
- data/conf/rsence_command_strings.yaml +101 -71
- data/js/comm/autosync/autosync.js +3 -3
- data/js/comm/jsloader/jsloader.js +16 -3
- data/js/comm/queue/queue.js +1 -1
- data/js/comm/transporter/transporter.js +106 -83
- data/js/comm/values/values.js +8 -2
- data/js/controls/button/button.js +9 -4
- data/js/controls/button/themes/default/button.css +1 -1
- data/js/controls/checkbox/themes/default/checkbox.css +1 -1
- data/js/controls/dialogs/sheet/sheet.js +27 -18
- data/js/controls/radiobutton/themes/default/radiobutton.css +1 -1
- data/js/controls/searchfield/searchfield.coffee +2 -0
- data/js/controls/searchfield/themes/default/searchfield.css +96 -0
- data/js/controls/searchfield/themes/default/searchfield.html +12 -0
- data/js/controls/searchfield/themes/default/searchfield_parts1-ie6.gif +0 -0
- data/js/controls/searchfield/themes/default/searchfield_parts1.png +0 -0
- data/js/controls/sliders/slider/slider.js +7 -1
- data/js/controls/stepper/stepper.js +6 -1
- data/js/controls/stringview/stringview.js +50 -39
- data/js/controls/tab/tab.js +103 -7
- data/js/controls/tab/themes/default/tab.css +2 -0
- data/js/controls/textarea/themes/default/textarea.css +4 -0
- data/js/controls/textcontrol/textcontrol.js +32 -2
- data/js/controls/textcontrol/themes/default/textcontrol.css +17 -2
- data/js/controls/uploader/themes/default/uploader.css +3 -3
- data/js/controls/uploader/themes/default/uploader.html +1 -1
- data/js/controls/uploader/uploader.coffee +110 -0
- data/js/controls/window/themes/default/window.css +28 -5
- data/js/controls/window/themes/default/window.html +2 -0
- data/js/controls/window/window.js +5 -1
- data/js/core/class/class.js +22 -4
- data/js/core/elem/elem.coffee +816 -0
- data/js/core/event/event.js +2 -2
- data/js/core/rsence_ns/rsence_ns.coffee +31 -0
- data/js/core/rsence_ns/rsence_ns.js +6 -6
- data/js/datetime/calendar/calendar.coffee +307 -0
- data/js/datetime/calendar/themes/default/calendar.css +90 -9
- data/js/datetime/calendar/themes/default/calendar.html +11 -0
- data/js/datetime/calendar/themes/default/calendar_bg-ie6.gif +0 -0
- data/js/datetime/calendar/themes/default/calendar_bg.png +0 -0
- data/js/datetime/calendar/themes/default/calendar_parts1-ie6.gif +0 -0
- data/js/datetime/calendar/themes/default/calendar_parts1.png +0 -0
- data/js/datetime/calendar/themes/default/calendar_parts2-ie6.gif +0 -0
- data/js/datetime/calendar/themes/default/calendar_parts2.png +0 -0
- data/js/datetime/datetimepicker/datetimepicker.js +217 -0
- data/js/datetime/datetimevalue/datetimevalue.js +22 -5
- data/js/datetime/timesheet/themes/default/timesheet.css +51 -22
- data/js/datetime/timesheet/themes/default/timesheet.html +4 -2
- data/js/datetime/timesheet/timesheet.js +782 -192
- data/js/datetime/timesheet_item/themes/default/timesheet_item.css +42 -11
- data/js/datetime/timesheet_item/themes/default/timesheet_item.html +4 -2
- data/js/datetime/timesheet_item/themes/default/timesheet_item_icons.png +0 -0
- data/js/datetime/timesheet_item/timesheet_item.js +158 -254
- data/js/datetime/timesheet_item_edit/timesheet_item_edit.js +0 -274
- data/js/foundation/application/application.js +52 -9
- data/js/foundation/control/eventresponder/eventresponder.js +7 -4
- data/js/foundation/control/valueaction/valueaction.js +71 -0
- data/js/foundation/eventmanager/eventmanager.js +71 -33
- data/js/foundation/geom/rect/rect.js +39 -7
- data/js/foundation/json_renderer/json_renderer.js +278 -62
- data/js/foundation/locale_settings/locale_settings.js +131 -0
- data/js/foundation/system/system.js +40 -13
- data/js/foundation/thememanager/thememanager.js +21 -0
- data/js/foundation/view/markupview/markupview.js +12 -12
- data/js/foundation/view/view.js +221 -27
- data/js/graphics/svgcontrol/svgcontrol.js +400 -0
- data/js/lists/checkboxlist/checkboxlist.js +18 -7
- data/js/lists/listitems/listitems.js +52 -38
- data/js/lists/radiobuttonlist/radiobuttonlist.js +23 -7
- data/js/menus/menuitem/menuitem.js +5 -0
- data/js/menus/menuitem/themes/default/menuitem.css +45 -0
- data/js/menus/menuitem/themes/default/menuitem.html +4 -0
- data/js/menus/minimenu/minimenu.js +47 -16
- data/js/menus/minimenuitem/minimenuitem.js +62 -0
- data/js/menus/{minimenu/minimenuitem → minimenuitem}/themes/default/minimenuitem.css +2 -2
- data/js/menus/{minimenu/minimenuitem → minimenuitem}/themes/default/minimenuitem.html +0 -0
- data/js/menus/{minimenu/minimenuitem → minimenuitem}/themes/default/minimenuitem_checkmark.png +0 -0
- data/js/menus/popupmenu/popupmenu.js +14 -0
- data/js/menus/popupmenu/themes/default/popupmenu.css +65 -0
- data/js/menus/popupmenu/themes/default/popupmenu.html +7 -0
- data/js/menus/popupmenu/themes/default/popupmenu.png +0 -0
- data/js/no_pkg/no_pkg.js +2 -0
- data/js/util/reloadapp/reloadapp.js +1 -1
- data/js/views/scrollview/scrollview.js +6 -0
- data/lib/rsence.rb +136 -3
- data/lib/rsence/argv.rb +218 -0
- data/lib/rsence/argv/argv_util.rb +58 -0
- data/lib/rsence/argv/env_check.rb +58 -0
- data/lib/rsence/argv/help_argv.rb +15 -0
- data/lib/rsence/argv/initenv_argv.rb +218 -0
- data/lib/rsence/argv/save_argv.rb +92 -0
- data/lib/rsence/argv/startup_argv.rb +118 -0
- data/lib/rsence/argv/status_argv.rb +132 -0
- data/lib/rsence/argv/test_port.rb +32 -0
- data/lib/{daemon → rsence}/daemon.rb +67 -23
- data/lib/{conf/default.rb → rsence/default_config.rb} +18 -10
- data/lib/{plugins → rsence}/dependencies.rb +0 -0
- data/lib/{util → rsence}/gzstring.rb +0 -0
- data/lib/rsence/http.rb +3 -0
- data/lib/{http → rsence/http}/broker.rb +106 -19
- data/lib/{http → rsence/http}/rackup.rb +0 -0
- data/lib/{http → rsence/http}/request.rb +0 -4
- data/lib/{http → rsence/http}/response.rb +0 -1
- data/lib/{session → rsence}/msg.rb +17 -1
- data/lib/{plugins → rsence}/pluginmanager.rb +29 -12
- data/lib/{plugins → rsence}/plugins.rb +7 -7
- data/lib/{plugins → rsence/plugins}/gui_plugin.rb +8 -3
- data/lib/{plugins → rsence/plugins}/guiparser.rb +9 -6
- data/lib/{plugins → rsence/plugins}/plugin.rb +23 -4
- data/lib/{plugins → rsence/plugins}/plugin_base.rb +11 -1
- data/lib/{plugins → rsence/plugins}/plugin_plugins.rb +2 -2
- data/lib/{plugins → rsence/plugins}/plugin_sqlite_db.rb +0 -0
- data/lib/{plugins → rsence/plugins}/servlet.rb +0 -0
- data/lib/{session → rsence}/sessionmanager.rb +101 -39
- data/lib/{session → rsence}/sessionstorage.rb +30 -16
- data/lib/{daemon → rsence}/sigcomm.rb +0 -0
- data/lib/{transporter → rsence}/transporter.rb +13 -11
- data/lib/{values/hvalue.rb → rsence/value.rb} +6 -1
- data/lib/{values → rsence}/valuemanager.rb +1 -1
- data/plugins/client_pkg/client_pkg.rb +14 -4
- data/plugins/client_pkg/info.yaml +2 -2
- data/plugins/client_pkg/lib/client_pkg_build.rb +145 -45
- data/plugins/client_pkg/lib/client_pkg_cache.rb +1 -1
- data/plugins/client_pkg/lib/client_pkg_serve.rb +1 -1
- data/plugins/main/main.rb +43 -3
- data/plugins/main/tmpl/index.html +2 -10
- data/plugins/main/values.yaml +3 -1
- data/plugins/ticket/lib/common.rb +6 -3
- data/plugins/ticket/ticket.rb +11 -3
- metadata +144 -174
- data/js/comm/autosync/js.inc +0 -0
- data/js/comm/js.inc +0 -0
- data/js/comm/jsloader/js.inc +0 -0
- data/js/comm/queue/js.inc +0 -0
- data/js/comm/session/js.inc +0 -0
- data/js/comm/sessionwatcher/js.inc +0 -0
- data/js/comm/transporter/js.inc +0 -0
- data/js/comm/urlresponder/js.inc +0 -0
- data/js/comm/values/js.inc +0 -0
- data/js/controls/button/js.inc +0 -0
- data/js/controls/checkbox/js.inc +0 -0
- data/js/controls/dialogs/alert_sheet/js.inc +0 -0
- data/js/controls/dialogs/confirm_sheet/js.inc +0 -0
- data/js/controls/dialogs/sheet/js.inc +0 -0
- data/js/controls/imageview/js.inc +0 -0
- data/js/controls/passwordcontrol/js.inc +0 -0
- data/js/controls/progress/progressbar/js.inc +0 -0
- data/js/controls/progress/progressindicator/js.inc +0 -0
- data/js/controls/radiobutton/js.inc +0 -0
- data/js/controls/sliders/slider/js.inc +0 -0
- data/js/controls/sliders/vslider/js.inc +0 -0
- data/js/controls/stepper/js.inc +0 -0
- data/js/controls/stringview/js.inc +0 -0
- data/js/controls/tab/js.inc +0 -0
- data/js/controls/textarea/js.inc +0 -0
- data/js/controls/textcontrol/js.inc +0 -0
- data/js/controls/uploader/js.inc +0 -0
- data/js/controls/uploader/uploader.js +0 -154
- data/js/controls/validatorview/js.inc +0 -0
- data/js/controls/window/js.inc +0 -0
- data/js/core/class/js.inc +0 -0
- data/js/core/elem/elem.js +0 -1325
- data/js/core/elem/js.inc +0 -0
- data/js/core/event/js.inc +0 -0
- data/js/core/iefix/js.inc +0 -0
- data/js/core/rsence_ns/js.inc +0 -0
- data/js/datetime/calendar/calendar.js +0 -198
- data/js/datetime/calendar/js.inc +0 -0
- data/js/datetime/datetimevalue/js.inc +0 -0
- data/js/datetime/timesheet/js.inc +0 -0
- data/js/datetime/timesheet/old_timesheet.js +0 -292
- data/js/datetime/timesheet/themes/default/old_timesheet.css +0 -30
- data/js/datetime/timesheet/themes/default/old_timesheet.html +0 -2
- data/js/datetime/timesheet_item/js.inc +0 -0
- data/js/datetime/timesheet_item/old_timesheet_item.js +0 -308
- data/js/datetime/timesheet_item/themes/default/old_timesheet_item.css +0 -42
- data/js/datetime/timesheet_item/themes/default/old_timesheet_item.html +0 -8
- data/js/datetime/timesheet_item_edit/js.inc +0 -0
- data/js/datetime/timesheet_item_edit/old_timesheet_item_edit.js +0 -274
- data/js/foundation/application/js.inc +0 -0
- data/js/foundation/control/controldefaults/js.inc +0 -0
- data/js/foundation/control/dummyvalue/js.inc +0 -0
- data/js/foundation/control/dyncontrol/js.inc +0 -0
- data/js/foundation/control/eventresponder/js.inc +0 -0
- data/js/foundation/control/js.inc +0 -0
- data/js/foundation/control/valuematrix/js.inc +0 -0
- data/js/foundation/control/valueresponder/js.inc +0 -0
- data/js/foundation/eventmanager/js.inc +0 -0
- data/js/foundation/geom/point/js.inc +0 -0
- data/js/foundation/geom/rect/js.inc +0 -0
- data/js/foundation/json_renderer/js.inc +0 -0
- data/js/foundation/system/js.inc +0 -0
- data/js/foundation/thememanager/js.inc +0 -0
- data/js/foundation/value/js.inc +0 -0
- data/js/foundation/view/js.inc +0 -0
- data/js/foundation/view/markupview/js.inc +0 -0
- data/js/foundation/view/morphanimation/js.inc +0 -0
- data/js/foundation/view/viewdefaults/js.inc +0 -0
- data/js/lists/checkboxlist/js.inc +0 -0
- data/js/lists/listitems/js.inc +0 -0
- data/js/lists/propertylist/js.inc +0 -0
- data/js/lists/propertylist/propertylisteditor/js.inc +0 -0
- data/js/lists/radiobuttonlist/js.inc +0 -0
- data/js/menus/minimenu/js.inc +0 -0
- data/js/menus/minimenu/minimenuitem/js.inc +0 -0
- data/js/menus/minimenu/minimenuitem/minimenuitem.js +0 -33
- data/js/util/reloadapp/js.inc +0 -0
- data/js/util/sha/js.inc +0 -0
- data/js/views/centerview/js.inc +0 -0
- data/js/views/inlineview/js.inc +0 -0
- data/js/views/scrollview/js.inc +0 -0
- data/lib/conf/argv.rb +0 -880
|
@@ -275,7 +275,9 @@ EVENT = {
|
|
|
275
275
|
}
|
|
276
276
|
if(_ctrl.drawn){
|
|
277
277
|
_this._updateHoverItems();
|
|
278
|
-
(_this.hovered.length !== 0
|
|
278
|
+
if (_this.hovered.length !== 0 && _this.hovered.indexOf(_ctrl.elemId) === _this.hovered.length-1){
|
|
279
|
+
_this.focus(_ctrl);
|
|
280
|
+
}
|
|
279
281
|
}
|
|
280
282
|
},
|
|
281
283
|
|
|
@@ -581,6 +583,7 @@ EVENT = {
|
|
|
581
583
|
*
|
|
582
584
|
**/
|
|
583
585
|
startDragging: function(_ctrl, _isLeftButton) {
|
|
586
|
+
// console.log('startDragging');
|
|
584
587
|
var _this = EVENT;
|
|
585
588
|
_this.dragItems = [_ctrl.elemId];
|
|
586
589
|
_this.focus(_ctrl);
|
|
@@ -597,20 +600,22 @@ EVENT = {
|
|
|
597
600
|
*
|
|
598
601
|
**/
|
|
599
602
|
mouseDown: function(e, _isLeftButton) {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
603
|
+
// console.log('mouseDown');
|
|
604
|
+
var
|
|
605
|
+
_this = EVENT,
|
|
606
|
+
_didStartDrag = false,
|
|
607
|
+
x = _this.status[_this.crsrX],
|
|
608
|
+
y = _this.status[_this.crsrY],
|
|
609
|
+
i = 0,
|
|
610
|
+
|
|
611
|
+
// Unset the active control when clicking on anything.
|
|
612
|
+
_newActiveControl = null,
|
|
613
|
+
|
|
614
|
+
// The startDrag and mouseDown event receivers are first collected into
|
|
615
|
+
// these arrays and the events are sent after the active control status has
|
|
616
|
+
// been changed.
|
|
617
|
+
_startDragElementIds = [],
|
|
618
|
+
_mouseDownElementIds = [];
|
|
614
619
|
|
|
615
620
|
_this._modifiers(e);
|
|
616
621
|
if (_isLeftButton === undefined) {
|
|
@@ -665,11 +670,15 @@ EVENT = {
|
|
|
665
670
|
Event.stop(e);
|
|
666
671
|
}
|
|
667
672
|
// Stop the event only when we are hovering over some control, allows normal DOM events to co-exist.
|
|
668
|
-
if (
|
|
669
|
-
|
|
673
|
+
if (_this.enableDroppableChecks) {
|
|
674
|
+
// console.log('stopEvent:',_stopEvent,', hoverlen:',(_this.hovered.length !== 0),', newActive:',_newActiveControl);
|
|
675
|
+
if ( (_mouseDownElementIds.length !== 0) && (_stopEvent === 0) && (_this.hovered.length !== 0) && _newActiveControl) {
|
|
670
676
|
Event.stop(e);
|
|
671
677
|
}
|
|
672
678
|
}
|
|
679
|
+
// else {
|
|
680
|
+
// console.log('not enableDroppableChecks');
|
|
681
|
+
// }
|
|
673
682
|
return true;
|
|
674
683
|
},
|
|
675
684
|
|
|
@@ -680,6 +689,13 @@ EVENT = {
|
|
|
680
689
|
*
|
|
681
690
|
**/
|
|
682
691
|
click: function(e, _isLeftButton) {
|
|
692
|
+
// if( new Date().getTime() - EVENT.lastMouseUp < 10 ){
|
|
693
|
+
// console.log('should prevent click?');
|
|
694
|
+
// // return false; // prevent click and mousedown coexistence
|
|
695
|
+
// }
|
|
696
|
+
// else{
|
|
697
|
+
// console.log('click');
|
|
698
|
+
// }
|
|
683
699
|
var _this = EVENT,
|
|
684
700
|
x = _this.status[_this.crsrX],
|
|
685
701
|
y = _this.status[_this.crsrY],
|
|
@@ -717,6 +733,7 @@ EVENT = {
|
|
|
717
733
|
}
|
|
718
734
|
// Handle the active control selection.
|
|
719
735
|
if (_newActiveControl) {
|
|
736
|
+
// console.log('click new active control');
|
|
720
737
|
_this.changeActiveControl(_newActiveControl);
|
|
721
738
|
}
|
|
722
739
|
var _stopEvent = _clickElementIds.length;
|
|
@@ -725,6 +742,9 @@ EVENT = {
|
|
|
725
742
|
_stopEvent--;
|
|
726
743
|
}
|
|
727
744
|
}
|
|
745
|
+
if( _stopEvent === 0 ){
|
|
746
|
+
Event.stop(e);
|
|
747
|
+
}
|
|
728
748
|
return true;
|
|
729
749
|
},
|
|
730
750
|
|
|
@@ -738,18 +758,30 @@ EVENT = {
|
|
|
738
758
|
changeActiveControl: function(_ctrl) {
|
|
739
759
|
var
|
|
740
760
|
_this = EVENT,
|
|
761
|
+
_disAllowLose = true,
|
|
741
762
|
// Store the currently active control so we can inform it,
|
|
742
763
|
// if it's no longer the active control.
|
|
743
764
|
_prevActiveCtrl = _this.activeControl;
|
|
744
765
|
// Did the active control change?
|
|
745
|
-
if (_ctrl && (_ctrl !== _prevActiveCtrl) && (_ctrl._gainedActiveStatus || _prevActiveCtrl._lostActiveStatus)) {
|
|
766
|
+
if (_ctrl && (_ctrl !== _prevActiveCtrl) && (_ctrl._gainedActiveStatus || (_prevActiveCtrl && _prevActiveCtrl._lostActiveStatus))) {
|
|
746
767
|
if (_prevActiveCtrl && _prevActiveCtrl._lostActiveStatus) {
|
|
747
768
|
// Previously active control just lost the active status.
|
|
748
|
-
_prevActiveCtrl
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
769
|
+
if( _prevActiveCtrl ){
|
|
770
|
+
_disAllowLose = _prevActiveCtrl._lostActiveStatus(_ctrl) === false;
|
|
771
|
+
if( _disAllowLose ){
|
|
772
|
+
// console.log('disallow losing focus: ',_prevActiveCtrl.componentName,' -> ',_ctrl.componentName);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
// else{
|
|
776
|
+
// console.log('allow losing focus: ',_prevActiveCtrl.componentName,' -> ',_ctrl.componentName);
|
|
777
|
+
// }
|
|
778
|
+
_prevActiveCtrl.active = false;
|
|
779
|
+
if(_this.focusTrace){
|
|
780
|
+
_prevActiveCtrl.setStyle('border','2px solid green');
|
|
781
|
+
if( _this.prevActiveCtrl ){
|
|
782
|
+
_this.prevActiveCtrl.setStyle('border','2px solid blue');
|
|
783
|
+
}
|
|
784
|
+
}
|
|
753
785
|
}
|
|
754
786
|
_this.prevActiveCtrl = _prevActiveCtrl;
|
|
755
787
|
}
|
|
@@ -779,15 +811,19 @@ EVENT = {
|
|
|
779
811
|
* - endDrag
|
|
780
812
|
*
|
|
781
813
|
**/
|
|
814
|
+
// lastMouseUp: 0,
|
|
782
815
|
mouseUp: function(e) {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
816
|
+
// console.log('mouseUp',EVENT.dragItems.length);
|
|
817
|
+
// EVENT.lastMouseUp = new Date().getTime();
|
|
818
|
+
var
|
|
819
|
+
_this = EVENT,
|
|
820
|
+
_didEndDrag = false,
|
|
821
|
+
_isLeftButton = Event.isLeftClick(e),
|
|
822
|
+
x = _this.status[_this.crsrX],
|
|
823
|
+
y = _this.status[_this.crsrY],
|
|
824
|
+
_elemId,
|
|
825
|
+
_ctrl,
|
|
826
|
+
i = 0;
|
|
791
827
|
_this._modifiers(e);
|
|
792
828
|
// Send endDrag for the currently dragged items even when they don't have focus, and clear the drag item array.
|
|
793
829
|
for (; i !== _this.dragItems.length; i++) {
|
|
@@ -820,7 +856,9 @@ EVENT = {
|
|
|
820
856
|
if (_this.focused[i] === true) {
|
|
821
857
|
_ctrl = _this.focusOptions[i].ctrl;
|
|
822
858
|
if (_this.focusOptions[i].mouseUp === true) {
|
|
823
|
-
_ctrl.mouseUp(x, y, _isLeftButton)
|
|
859
|
+
if( _ctrl.mouseUp(x, y, _isLeftButton) ){
|
|
860
|
+
// Event.stop(e);
|
|
861
|
+
}
|
|
824
862
|
}
|
|
825
863
|
}
|
|
826
864
|
}
|
|
@@ -877,7 +915,7 @@ EVENT = {
|
|
|
877
915
|
else if (e.detail) {
|
|
878
916
|
_delta = 0 - (e.detail / 3);
|
|
879
917
|
}
|
|
880
|
-
if (BROWSER_TYPE.opera || BROWSER_TYPE.safari) {
|
|
918
|
+
if (BROWSER_TYPE.opera || BROWSER_TYPE.safari || BROWSER_TYPE.ie) {
|
|
881
919
|
_delta = 0 - _delta;
|
|
882
920
|
}
|
|
883
921
|
for (; i !== _this.focused.length; i++) {
|
|
@@ -122,9 +122,14 @@ HRect = HClass.extend({
|
|
|
122
122
|
_viewId = _viewIds[i];
|
|
123
123
|
_view = HSystem.views[_viewId];
|
|
124
124
|
if(_view.flexRight || _view.flexBottom){
|
|
125
|
-
ELEM.
|
|
125
|
+
ELEM.flush();
|
|
126
|
+
if( !_view.parent ){
|
|
127
|
+
_this.updateSecondaryValues();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
126
130
|
_parentElemId = _view.parent.elemId;
|
|
127
131
|
_parentSize = _view.parentSize();
|
|
132
|
+
// console.log('parentSize:',JSON.stringify(_parentSize));
|
|
128
133
|
_parentWidth = _parentSize[0];
|
|
129
134
|
if(_view.flexRight){
|
|
130
135
|
_this.right = _parentWidth - _view.flexRightOffset;
|
|
@@ -139,6 +144,13 @@ HRect = HClass.extend({
|
|
|
139
144
|
if(!_view.flexTop){
|
|
140
145
|
_this.top = _this.bottom - _this.height;
|
|
141
146
|
}
|
|
147
|
+
if( _this.bottom-_this.top < 0 ){
|
|
148
|
+
_this.bottom = _this.top;
|
|
149
|
+
}
|
|
150
|
+
if( _this.right-_this.left < 0 ){
|
|
151
|
+
_this.right = _this.left;
|
|
152
|
+
}
|
|
153
|
+
// console.log(_this.left,this.top,this.right-this.left,this.bottom-this.top);
|
|
142
154
|
_this.updateSecondaryValues();
|
|
143
155
|
}
|
|
144
156
|
}
|
|
@@ -383,18 +395,34 @@ HRect = HClass.extend({
|
|
|
383
395
|
* of a side in common with rect, and false if it doesn't.
|
|
384
396
|
*
|
|
385
397
|
* = Parameters
|
|
386
|
-
* +_rect+::
|
|
398
|
+
* +_rect+:: A HRect instance to intersect this rect with
|
|
399
|
+
* +_insetByX+:: Insets +_rect+ by +_insetBy+ pixels, optional
|
|
400
|
+
* +_insetByY+:: Insets +_rect+ by +_insetBy+ pixels, optional. If omitted, but +_insetByX+ is defined, then +_insetByY+ equals +_insetByX+.
|
|
387
401
|
*
|
|
388
402
|
* = Returns
|
|
389
403
|
* A Boolean (true/false) depending on the result.
|
|
390
404
|
*
|
|
391
405
|
**/
|
|
392
|
-
intersects: function(_rect) {
|
|
406
|
+
intersects: function( _rect, _insetByX, _insetByY ) {
|
|
407
|
+
if( _insetByX !== undefined ){
|
|
408
|
+
_rect = HRect.nu( _rect );
|
|
409
|
+
if( _insetByY === undefined ){
|
|
410
|
+
_insetByY = _insetByX;
|
|
411
|
+
}
|
|
412
|
+
_rect.insetBy( _insetByX, _insetByY );
|
|
413
|
+
}
|
|
393
414
|
return (
|
|
394
|
-
((_rect.left >= this.left && _rect.left <= this.right) ||
|
|
395
|
-
(_rect.right >= this.left && _rect.right <= this.right)
|
|
396
|
-
|
|
397
|
-
|
|
415
|
+
( ( _rect.left >= this.left && _rect.left <= this.right ) ||
|
|
416
|
+
( _rect.right >= this.left && _rect.right <= this.right )
|
|
417
|
+
) &&
|
|
418
|
+
( ( _rect.top >= this.top && _rect.top <= this.bottom) ||
|
|
419
|
+
( _rect.bottom >= this.top && _rect.bottom <= this.bottom)
|
|
420
|
+
)
|
|
421
|
+
);
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
overlaps: function( _rect, _insetbyX, _insetByY ){
|
|
425
|
+
return this.intersects( _rect, _insetbyX, _insetByY );
|
|
398
426
|
},
|
|
399
427
|
|
|
400
428
|
/** = Description
|
|
@@ -644,6 +672,10 @@ HRect = HClass.extend({
|
|
|
644
672
|
_viewId = this.viewIds[i];
|
|
645
673
|
HSystem.views[_viewId].drawRect();
|
|
646
674
|
}
|
|
675
|
+
},
|
|
676
|
+
|
|
677
|
+
toString: function(){
|
|
678
|
+
return ('[object Rect left='+this.left+' top='+this.top+' width='+this.width+' height='+this.height+' right='+this.right+' bottom='+this.bottom+']');
|
|
647
679
|
}
|
|
648
680
|
|
|
649
681
|
});
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
//var//RSence.Foundation
|
|
25
25
|
COMM.JSONRenderer = HClass.extend({
|
|
26
26
|
|
|
27
|
-
version: 0
|
|
27
|
+
version: 1.0,
|
|
28
28
|
|
|
29
29
|
/** = Description
|
|
30
30
|
* Renders JSON structured data, see some of the demos for usage examples.
|
|
@@ -37,12 +37,49 @@ COMM.JSONRenderer = HClass.extend({
|
|
|
37
37
|
if((_data['type'] === 'GUITree') && (this.version >= _data['version'])){
|
|
38
38
|
this.data = _data;
|
|
39
39
|
this.parent = _parent;
|
|
40
|
+
this.byId = {};
|
|
41
|
+
this.byName = {};
|
|
40
42
|
this.render();
|
|
43
|
+
var _rndr = this;
|
|
44
|
+
if( this.view.hasAncestor( HApplication ) ){
|
|
45
|
+
this.view.getViewById = function(_id){ return _rndr.getViewById(_id); };
|
|
46
|
+
this.view.getViewsByName = function(_id){ return _rndr.getViewsByName(_id); };
|
|
47
|
+
}
|
|
48
|
+
else if ( this.view.hasAncestor( HView ) ){
|
|
49
|
+
this.view.app.getViewById = function(_id){ return _rndr.getViewById(_id); };
|
|
50
|
+
this.view.app.getViewsByName = function(_id){ return _rndr.getViewsByName(_id); };
|
|
51
|
+
}
|
|
41
52
|
}
|
|
42
53
|
else{
|
|
43
54
|
throw("JSONRenderer: Only GUITree version "+this.version+" or older data can be handled.");
|
|
44
55
|
}
|
|
45
56
|
},
|
|
57
|
+
getViewById: function(_id){
|
|
58
|
+
if( this.byId[_id] !== undefined ){
|
|
59
|
+
return this.byId[_id];
|
|
60
|
+
}
|
|
61
|
+
console.log('JSONRenderer; no such view Id: '+_id);
|
|
62
|
+
return null;
|
|
63
|
+
},
|
|
64
|
+
addViewId: function(_id, _view){
|
|
65
|
+
if( this.byId[_id] !== undefined ){
|
|
66
|
+
console.log('JSONRenderer; already has id: '+_id+' (replacing)');
|
|
67
|
+
}
|
|
68
|
+
this.byId[_id] = _view;
|
|
69
|
+
},
|
|
70
|
+
getViewsByName: function(_name){
|
|
71
|
+
if( this.byName[_id] !== undefined ){
|
|
72
|
+
return this.byName[_name];
|
|
73
|
+
}
|
|
74
|
+
console.log('JSONRenderer; no views named: '+_name);
|
|
75
|
+
return [];
|
|
76
|
+
},
|
|
77
|
+
addViewName: function(_name, _view){
|
|
78
|
+
if( this.byName[_name] === undefined ){
|
|
79
|
+
this.byName[_name] = [];
|
|
80
|
+
}
|
|
81
|
+
this.byName[_name].push(_view);
|
|
82
|
+
},
|
|
46
83
|
render: function(){
|
|
47
84
|
this.scopes = [window];
|
|
48
85
|
this.scopeDepth = 0;
|
|
@@ -52,21 +89,23 @@ COMM.JSONRenderer = HClass.extend({
|
|
|
52
89
|
this.view.die();
|
|
53
90
|
},
|
|
54
91
|
defineInScope: function( _definition ){
|
|
55
|
-
var
|
|
56
|
-
|
|
92
|
+
var
|
|
93
|
+
_isArr = (_definition instanceof Array),
|
|
94
|
+
_isObj = (_definition instanceof Object);
|
|
57
95
|
if( _isArr || !_isObj ){
|
|
58
96
|
console.log("JSONRenderer; definition must be an Object, got: '"+(typeof _definition)+"'. Definition: ",_definition);
|
|
59
97
|
return;
|
|
60
98
|
}
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
99
|
+
var
|
|
100
|
+
_extension = {},
|
|
101
|
+
_reserved = ['class','extend','implement'],
|
|
102
|
+
_className = _definition[_reserved[0]],
|
|
103
|
+
_extendName = _definition[_reserved[1]],
|
|
104
|
+
_implementName = _definition[_reserved[2]],
|
|
105
|
+
_extend = _extendName?this.findInScope(_extendName):false,
|
|
106
|
+
_implement = _implementName?this.findInScope(_implementName):false,
|
|
107
|
+
_scope = this.scopes[ this.scopeDepth ],
|
|
108
|
+
_key, _value;
|
|
70
109
|
if( _className === undefined ) {
|
|
71
110
|
console.log("JSONRenderer; class name missing in definition scope.");
|
|
72
111
|
return;
|
|
@@ -96,10 +135,11 @@ COMM.JSONRenderer = HClass.extend({
|
|
|
96
135
|
return false;
|
|
97
136
|
}
|
|
98
137
|
if(_className.indexOf('.') !== -1){
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
var
|
|
139
|
+
_splitClass = _className.split('.'),
|
|
140
|
+
j = 1,
|
|
141
|
+
_classPart = _splitClass[0],
|
|
142
|
+
_classFull = this.findInScope( _classPart );
|
|
103
143
|
if( !_classFull ){
|
|
104
144
|
return false;
|
|
105
145
|
}
|
|
@@ -130,42 +170,172 @@ COMM.JSONRenderer = HClass.extend({
|
|
|
130
170
|
}
|
|
131
171
|
return _block;
|
|
132
172
|
},
|
|
173
|
+
initStraight: function( _class, _args ){
|
|
174
|
+
if( _args instanceof Array ){
|
|
175
|
+
return HClass.extend().nu.apply( _class, _args );
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
return (new _class(_args));
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
_handleCall: function( _instance, _call ){
|
|
182
|
+
if( _call instanceof Object ){
|
|
183
|
+
var
|
|
184
|
+
_methodName, _arguments;
|
|
185
|
+
for( _methodName in _call ){
|
|
186
|
+
// console.log('methodName:',_methodName);
|
|
187
|
+
if( typeof _instance[_methodName] === 'function' ){
|
|
188
|
+
// console.log('callArguments:',_call[_methodName]);
|
|
189
|
+
try{
|
|
190
|
+
_instance[_methodName].apply( _instance, _call[_methodName] );
|
|
191
|
+
}
|
|
192
|
+
catch(e){
|
|
193
|
+
console.log('JSONRenderer handleCall error:',e.toString()+', method:',_instance[_methodName],', call args:', _call[_methodName],', e:',e);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.log('JSONRenderer handleCall error; undefined method: ',_methodName);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log('JSONRenderer handleCall error, unable to handle call format: ',_call);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
133
205
|
renderNode: function( _dataNode, _parent ){
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
var
|
|
207
|
+
_reserved = [ 'type', 'args', 'version', 'class', 'rect', 'bind', 'extend', 'options', 'subviews', 'define' ],
|
|
208
|
+
_className, _class, _origNode, _straightParams = false, _rect, _hasRect, _hasSubviews, _subViews,
|
|
209
|
+
_hasOptions, _options, _hasExtension, _extension, _hasBind, _bind,
|
|
210
|
+
_hasName, _hasId,
|
|
211
|
+
_isAppClass = false, _isViewClass = false,
|
|
212
|
+
_autoOptionItems = [
|
|
213
|
+
'label', 'style', 'visible', 'theme', 'html',
|
|
214
|
+
'value', 'enabled', 'events', 'active', 'minValue', 'maxValue'
|
|
215
|
+
], _autoOptionItem, _hasCall, _call,
|
|
216
|
+
_hasDefinition, _definition, _instance, i, _subView = null;
|
|
217
|
+
|
|
218
|
+
// The name of the class:
|
|
219
|
+
if( !_dataNode['class'] ){
|
|
220
|
+
|
|
221
|
+
for( i in _dataNode ){
|
|
222
|
+
if( _reserved.indexOf( i ) === -1 ){
|
|
223
|
+
_className = i;
|
|
224
|
+
_origNode = _dataNode;
|
|
225
|
+
_dataNode = _dataNode[i];
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
_straightParams = ( !(_dataNode instanceof Object) || (_dataNode instanceof Array) );
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
_className = _dataNode['class'];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
_class = this.findInScope( _className );
|
|
236
|
+
|
|
237
|
+
if (_class['hasAncestor'] !== undefined){
|
|
238
|
+
_isAppClass = _class.hasAncestor( HApplication );
|
|
239
|
+
_isViewClass = _class.hasAncestor( HView );
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
_hasId = ( _dataNode['id'] !== undefined ) && ( typeof _dataNode['id'] === 'string' );
|
|
243
|
+
_hasName = ( _dataNode['name'] !== undefined ) && ( typeof _dataNode['name'] === 'string' );
|
|
244
|
+
|
|
245
|
+
if( _straightParams ){
|
|
246
|
+
_instance = this.initStraight( _class, _dataNode );
|
|
247
|
+
}
|
|
248
|
+
else if( _dataNode['args'] !== undefined ){
|
|
249
|
+
_instance = this.initStraight( _class, _dataNode['args'] );
|
|
250
|
+
}
|
|
251
|
+
else if( _origNode && _origNode['args'] !== undefined ){
|
|
252
|
+
_instance = this.initStraight( _class, _origNode['args'] );
|
|
253
|
+
}
|
|
254
|
+
if( _instance ){
|
|
255
|
+
if( _hasId ){
|
|
256
|
+
this.addViewId( _dataNode.id, _instance );
|
|
257
|
+
}
|
|
258
|
+
if( _hasName ){
|
|
259
|
+
this.addViewName( _dataNode.id, _instance );
|
|
260
|
+
}
|
|
261
|
+
return _instance;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Currently only HView -derived classes are supported, so
|
|
265
|
+
// the rect is mandatory.
|
|
266
|
+
_rect = _dataNode['rect'];
|
|
267
|
+
_hasRect = (_rect !== undefined) && (_rect instanceof Array || typeof _rect === 'string');
|
|
268
|
+
if( !_hasRect && _origNode){
|
|
269
|
+
_hasRect = _origNode['rect'] !== undefined;
|
|
270
|
+
_rect = _hasRect?_origNode['rect']:null;
|
|
271
|
+
}
|
|
272
|
+
if( !_isViewClass ){
|
|
273
|
+
if( _hasRect ){
|
|
274
|
+
console.log( "renderNode warning; Supposedly rect-incompatible class supplied: "+_className );
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Checks, if any sub-views are defined.
|
|
279
|
+
_hasSubviews = _dataNode['subviews'] !== undefined;
|
|
280
|
+
_subViews = _hasSubviews?_dataNode['subviews']:null;
|
|
281
|
+
if( !_hasSubviews && _origNode){
|
|
282
|
+
_hasSubviews = _origNode['subviews'] !== undefined;
|
|
283
|
+
_subViews = _hasSubviews?_origNode['subviews']:null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Checks, if any options are defined.
|
|
287
|
+
_hasOptions = _dataNode['options'] !== undefined;
|
|
288
|
+
_options = _hasOptions?_dataNode['options']:null;
|
|
289
|
+
if( !_hasOptions && _origNode){
|
|
290
|
+
_hasOptions = _origNode['options'] !== undefined;
|
|
291
|
+
_options = _hasOptions?_origNode['options']:null;
|
|
292
|
+
}
|
|
293
|
+
for( i=0; i < _autoOptionItems.length; i++ ){
|
|
294
|
+
_autoOptionItem = _autoOptionItems[i];
|
|
295
|
+
if( _dataNode[ _autoOptionItem ] !== undefined ){
|
|
296
|
+
if( !_hasOptions ){
|
|
297
|
+
_hasOptions = true;
|
|
298
|
+
_options = {};
|
|
299
|
+
}
|
|
300
|
+
_options[_autoOptionItem] = _dataNode[ _autoOptionItem ];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// JS Extension block
|
|
305
|
+
_hasExtension = _dataNode['extend'] !== undefined;
|
|
306
|
+
_extension = _hasExtension?_dataNode['extend']:null;
|
|
307
|
+
if( !_hasExtension && _origNode){
|
|
308
|
+
_hasExtension = _origNode['extend'] !== undefined;
|
|
309
|
+
_extension = _hasExtension?_origNode['extend']:null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// JS Extension block
|
|
313
|
+
_hasBind = _dataNode['bind'] !== undefined;
|
|
314
|
+
_bind = _hasBind?_dataNode['bind']:null;
|
|
315
|
+
if( !_hasBind && _origNode){
|
|
316
|
+
_hasBind = _origNode['bind'] !== undefined;
|
|
317
|
+
_bind = _hasBind?_origNode['bind']:null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
_hasCall = _dataNode['call'] !== undefined;
|
|
321
|
+
if( _hasCall ){
|
|
322
|
+
_call = _dataNode['call'];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// JS Definition block
|
|
326
|
+
_hasDefinition = _dataNode['define'] !== undefined;
|
|
327
|
+
_definitions = _hasDefinition?_dataNode['define']:null;
|
|
328
|
+
if( !_hasDefinition && _origNode){
|
|
329
|
+
_hasDefinition = _origNode['define'] !== undefined;
|
|
330
|
+
_definitions = _hasDefinition?_origNode['define']:null;
|
|
331
|
+
}
|
|
332
|
+
if( _rect === null && _class['hasAncestor'] && _class.hasAncestor( HView ) ) {
|
|
333
|
+
console.log( 'Ancestors include HView, but no rect defined!' );
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// The HView-derived class instance, instance is by default the parent
|
|
337
|
+
_instance = _parent;
|
|
338
|
+
|
|
169
339
|
this.scopeDepth ++;
|
|
170
340
|
this.scopes.push({});
|
|
171
341
|
try{
|
|
@@ -200,35 +370,81 @@ COMM.JSONRenderer = HClass.extend({
|
|
|
200
370
|
}
|
|
201
371
|
if(_hasOptions){
|
|
202
372
|
if(_hasBind){
|
|
203
|
-
|
|
373
|
+
if( _bind instanceof HValue ){
|
|
374
|
+
_options.valueObj = _bind;
|
|
375
|
+
}
|
|
376
|
+
else if( COMM.Values.values[_bind] !== undefined ){
|
|
377
|
+
_options.valueObj = COMM.Values.values[_bind];
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
console.log('renderNode warning; No such valueId:'+_bind);
|
|
381
|
+
}
|
|
204
382
|
}
|
|
205
383
|
else{
|
|
206
384
|
if(_options['valueObjId'] !== undefined){
|
|
207
|
-
|
|
208
|
-
_options['valueObj'] = COMM.Values.values[_options['valueObjId']];
|
|
385
|
+
_options.valueObj = COMM.Values.values[_options['valueObjId']];
|
|
209
386
|
}
|
|
210
387
|
}
|
|
211
388
|
}
|
|
212
389
|
// For HApplication -derived classes
|
|
213
|
-
if(
|
|
214
|
-
|
|
390
|
+
if( _isAppClass ){
|
|
391
|
+
if( _hasOptions ){
|
|
392
|
+
_instance = _class.nu( _options );
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
_instance = _class.nu();
|
|
396
|
+
}
|
|
215
397
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
398
|
+
else if ( _isViewClass ){
|
|
399
|
+
_instance = _class.nu( _rect, _parent, _options );
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
if( _hasRect ){
|
|
403
|
+
if( _hasOptions ){
|
|
404
|
+
_instance = _class.nu(_rect,_parent,_options);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
_instance = _class.nu(_rect,_parent);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else if ( _hasOptions ){
|
|
411
|
+
// console.log(_className,_parent,_options);
|
|
412
|
+
_instance = _class.nu( _parent, _options );
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
// console.log('renderNode warning; unsure how to construct: '+_className+', rect:',_rect,', options:',_options);
|
|
416
|
+
_instance = _class.nu( _parent );
|
|
417
|
+
}
|
|
219
418
|
}
|
|
220
419
|
if(!_hasOptions){
|
|
221
420
|
if(_hasBind){
|
|
222
|
-
|
|
421
|
+
if( _bind instanceof HValue ){
|
|
422
|
+
_bind.bind( _instance );
|
|
423
|
+
}
|
|
424
|
+
else if( COMM.Values.values[_bind] !== undefined ){
|
|
425
|
+
COMM.Values.values[_bind].bind(_instance);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
console.log('renderNode warning; No such valueId:'+_bind);
|
|
429
|
+
}
|
|
223
430
|
}
|
|
224
431
|
}
|
|
225
432
|
}
|
|
226
433
|
else if(!(!_class && _hasSubviews)) {
|
|
227
434
|
console.log('renderNode warning; No such class: '+_className+', node: ',_dataNode);
|
|
228
435
|
}
|
|
436
|
+
if( _hasId ){
|
|
437
|
+
this.addViewId( _dataNode.id, _instance );
|
|
438
|
+
}
|
|
439
|
+
if( _hasName ){
|
|
440
|
+
this.addViewName( _dataNode.id, _instance );
|
|
441
|
+
}
|
|
442
|
+
if(_hasCall){
|
|
443
|
+
this._handleCall(_instance,_call);
|
|
444
|
+
}
|
|
229
445
|
}
|
|
230
|
-
catch(e){
|
|
231
|
-
console.log('renderNode error:',e
|
|
446
|
+
catch (e){
|
|
447
|
+
console.log('renderNode error:',e.toString()+', rect:',_rect,', class:',_dataNode['class'],', options:', JSON.stringify(_options),', e:',e);
|
|
232
448
|
}
|
|
233
449
|
// Iterates recursively through all subviews, if specified.
|
|
234
450
|
if(_hasSubviews){
|