From 3badc664be246e6b4356e606289ba98e00ee5fb3 Mon Sep 17 00:00:00 2001 From: FelisCatus Date: Sat, 18 Oct 2014 22:48:58 +0800 Subject: [PATCH] Use custom directive instead of bootstrap-select for performance. Fix #46. --- omega-web/bower.json | 1 - omega-web/src/coffee/omega_decoration.coffee | 42 ++++++++++++------- omega-web/src/coffee/options.coffee | 2 - omega-web/src/less/options.less | 37 +++++++++------- .../src/partials/omega_profile_select.jade | 23 +++++++--- omega-web/src/partials/profile_switch.jade | 6 +-- 6 files changed, 72 insertions(+), 39 deletions(-) diff --git a/omega-web/bower.json b/omega-web/bower.json index f3f2141..f7a4c46 100644 --- a/omega-web/bower.json +++ b/omega-web/bower.json @@ -37,7 +37,6 @@ "FileSaver": "*", "angular-ui-utils": "bower-validate", "angular-ladda": "~0.1.6", - "bootstrap-select": "~1.6.2", "angular-sanitize": "~1.2.26" }, "exportsOverride": { diff --git a/omega-web/src/coffee/omega_decoration.coffee b/omega-web/src/coffee/omega_decoration.coffee index 6403ca8..cda395a 100644 --- a/omega-web/src/coffee/omega_decoration.coffee +++ b/omega-web/src/coffee/omega_decoration.coffee @@ -36,24 +36,38 @@ angular.module('omegaDecoration', []).value('profileIcons', { 'defaultText': '@?defaultText' 'dispName': '&?dispName' link: (scope, element, attrs, ngModel) -> - scope.classes = [].slice.call(element[0].classList) - element.attr('class', '') - selectpicker = element.find('.selectpicker') - if ngModel - ngModel.$render = -> - selectpicker.selectpicker('val', ngModel.$viewValue) - return - selectpicker.selectpicker().change (e) -> - ngModel.$setViewValue($(e.target).val()) scope.profileIcons = profileIcons scope.currentProfiles = [] - + scope.dispProfiles = undefined + updateView = -> + scope.profileIcon = '' + for profile in scope.currentProfiles + if profile.name == scope.profileName + scope.selectedProfile = profile + scope.profileIcon = profileIcons[profile.profileType] + break scope.$watch(scope.profiles, ((profiles) -> scope.currentProfiles = profiles + if scope.dispProfiles? + scope.dispProfiles = currentProfiles + updateView() ), true) - scope.onItemsUpdated = -> - selectpicker.selectpicker('refresh') - ngModel?.$render() + + scope.toggled = (open) -> + if open and not scope.dispProfiles? + scope.dispProfiles = scope.currentProfiles + scope.toggled = undefined + + if ngModel + ngModel.$render = -> + scope.profileName = ngModel.$viewValue + updateView() + + scope.setProfileName = (name) -> + if ngModel + ngModel.$setViewValue(name) + ngModel.$render() + scope.getName = (profile) -> - scope.dispName?({$profile: profile}) || profile.name + scope.dispName?({$profile: profile}) || profile?.name ) diff --git a/omega-web/src/coffee/options.coffee b/omega-web/src/coffee/options.coffee index faf0fec..01b6e16 100644 --- a/omega-web/src/coffee/options.coffee +++ b/omega-web/src/coffee/options.coffee @@ -28,8 +28,6 @@ $script.ready ['angular-loader'], -> 'lib/angular-ui-utils/validate.min.js' 'lib/jsondiffpatch/bundle.min.js' 'lib/angular-spectrum-colorpicker/angular-spectrum-colorpicker.min.js' - 'lib/bootstrap/js/dropdown.js' - 'lib/bootstrap-select/bootstrap-select.js' ], 'omega-deps') $script.ready ['jquery'], -> $script 'lib/jquery-ui-1.10.4.custom.min.js', 'jquery-ui' diff --git a/omega-web/src/less/options.less b/omega-web/src/less/options.less index 1316979..9736e08 100644 --- a/omega-web/src/less/options.less +++ b/omega-web/src/less/options.less @@ -115,23 +115,32 @@ ul.list-style-none, li.list-style-none { } } -/* bootstrap-select */ +/* omega-profile-select */ -.dropdown-menu>.selected>a { - &, &:hover, &:focus { - color: #FFF; - text-decoration: none; - outline: 0; - background-color: #428BCA; +.omega-profile-select { + width: 100%; + + .btn { + width: 100%; + display: block; + text-align: left; + text-align: initial; + position: relative; + padding-right: 25px; + + .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; + } } -} -.bootstrap-select.btn-group { - margin-bottom: 0 !important; -} - -.form-control[omega-profile-select] { - display: none; // Prevent not loaded directive from showing. + .dropdown-menu { + width: 100%; + cursor: pointer; + } } .disabled .btn { diff --git a/omega-web/src/partials/omega_profile_select.jade b/omega-web/src/partials/omega_profile_select.jade index 3e2d7bd..7f38099 100644 --- a/omega-web/src/partials/omega_profile_select.jade +++ b/omega-web/src/partials/omega_profile_select.jade @@ -1,5 +1,18 @@ -select.selectpicker(ng-class='classes') - option(ng-if='!!defaultText' value='' data-icon='glyphicon-time') {{defaultText}} - option(ng-repeat='profile in currentProfiles' value='{{profile.name}}' omega-repeat-done='onItemsUpdated()' - data-content=' {{getName(profile)}}') - | {{getName(profile)}} +.btn-group.omega-profile-select(dropdown on-toggle="toggled(open)") + button.btn.btn-default.dropdown-toggle(type='button' aria-expanded='false' + role='listbox' aria-haspopup='true') + span.glyphicon(class='{{profileIcon || "glyphicon-time"}}' ng-style='{color: selectedProfile.color}') + = ' ' + span(ng-show='!!profileName') {{getName(selectedProfile)}} + span(ng-show='!profileName') {{defaultText}} + = ' ' + span.caret + ul.dropdown-menu(role='listbox') + li(role='option' ng-if='!!defaultText' ng-class='{active: profileName == ""}') + a(ng-click='setProfileName("")') + span.glyphicon.glyphicon-time + = ' {{defaultText}}' + li(role='option' ng-repeat='profile in dispProfiles' ng-class='{active: profileName == profile.name}') + a(ng-click='setProfileName(profile.name)') + span.glyphicon(class='{{profileIcons[profile.profileType]}}' ng-style='{color: profile.color}') + = ' {{getName(profile)}}' diff --git a/omega-web/src/partials/profile_switch.jade b/omega-web/src/partials/profile_switch.jade index d493a94..4f75ee0 100644 --- a/omega-web/src/partials/profile_switch.jade +++ b/omega-web/src/partials/profile_switch.jade @@ -51,7 +51,7 @@ div(ng-controller='SwitchProfileCtrl') input.form-control(ng-model='rule.condition.pattern' ng-switch-default required ui-validate='{pattern: "validateCondition(rule.condition, $value)"}') td - div.form-control(omega-profile-select='options | profiles:profile' ng-model='rule.profileName' + div(omega-profile-select='options | profiles:profile' ng-model='rule.profileName' disp-name='$profile.name | dispName' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteRule' | tr}}" ng-click='removeRule($index)') @@ -79,7 +79,7 @@ div(ng-controller='SwitchProfileCtrl') span(ng-show='!attachedOptions.enabled') | {{'options_switchAttachedProfileInConditionDisabled' | tr}} td - div.form-control(omega-profile-select='options | profiles:profile' ng-model='attached.matchProfileName' + div(omega-profile-select='options | profiles:profile' ng-model='attached.matchProfileName' disp-name='$profile.name | dispName' ng-class='{disabled: !attachedOptions.enabled}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteAttached' | tr}}" ng-click='removeAttached()') @@ -89,7 +89,7 @@ div(ng-controller='SwitchProfileCtrl') td td(colspan='2') {{'options_switchDefaultProfile' | tr}} td - div.form-control(omega-profile-select='options | profiles:profile' ng-model='defaultProfileName' + div(omega-profile-select='options | profiles:profile' ng-model='defaultProfileName' disp-name='$profile.name | dispName') td button.btn.btn-info.btn-sm(title="{{'options_resetRules_help' | tr}}" ng-click='resetRules()')