├── .gitignore ├── .yo-rc.json ├── Gulpfile.js ├── README.md ├── assets ├── css │ ├── admin.css │ ├── admin.min.css │ └── user.css ├── js │ ├── dropdowns-enhancement.js │ ├── dropdowns-enhancement.min.js │ ├── wds-mega-menus.js │ └── wds-mega-menus.min.js ├── screenshot-1.png ├── scss │ ├── _bootstrap_styles.scss │ ├── _custom.scss │ ├── _dropdown.scss │ ├── _mixins.scss │ ├── _variables.scss │ └── admin.scss ├── svg-defs.svg └── svg │ ├── README.md │ ├── angle-left.svg │ ├── angle-right.svg │ ├── bars.svg │ ├── caret-down-brown.svg │ ├── caret-down-tan.svg │ ├── caret-down-white.svg │ ├── caret-down.svg │ ├── caret-left.svg │ ├── caret-right.svg │ ├── caret-up-brown.svg │ ├── caret-up-tan.svg │ ├── caret-up-white.svg │ ├── caret-up.svg │ ├── cc-amex.svg │ ├── cc-mastercard.svg │ ├── cc-paypal.svg │ ├── cc-visa.svg │ ├── check-circle.svg │ ├── checkbox-checked.svg │ ├── checkbox-unchecked.svg │ ├── checked-white.svg │ ├── checked.svg │ ├── chevron-left.svg │ ├── chevron-right.svg │ ├── download.svg │ ├── envelope.svg │ ├── facebook.svg │ ├── google-plus.svg │ ├── instagram.svg │ ├── layout1.svg │ ├── layout2.svg │ ├── layout3.svg │ ├── layout4.svg │ ├── linkedin.svg │ ├── location.svg │ ├── lock.svg │ ├── minus-white.svg │ ├── minus.svg │ ├── pinterest-p.svg │ ├── plus-white.svg │ ├── plus.svg │ ├── print.svg │ ├── ruler.svg │ ├── search-black.svg │ ├── search-white.svg │ ├── search.svg │ ├── selection.json │ ├── share.svg │ ├── times-circle-o.svg │ ├── truck.svg │ ├── twitter.svg │ └── youtube.svg ├── bin └── install-wp-tests.sh ├── includes ├── class-menu-admin.php ├── class-menu-walker.php ├── class-options.php └── class-walker-nav-menu-edit.php ├── languages └── wds-mega-menus.pot ├── package.json ├── readme.txt ├── tests └── bootstrap.php └── wds-mega-menus.php /.gitignore: -------------------------------------------------------------------------------- 1 | ### OSX ### 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear on external disk 13 | .Spotlight-V100 14 | .Trashes 15 | 16 | # Directories potentially created on remote AFP share 17 | .AppleDB 18 | .AppleDesktop 19 | Network Trash Folder 20 | Temporary Items 21 | .apdisk 22 | 23 | ### Bower ### 24 | bower_components 25 | .bower-cache 26 | .bower-registry 27 | .bower-tmp 28 | 29 | ### Node ### 30 | # Logs 31 | logs 32 | *.log 33 | 34 | # Runtime data 35 | pids 36 | *.pid 37 | *.seed 38 | 39 | # Directory for instrumented libs generated by jscoverage/JSCover 40 | lib-cov 41 | 42 | # Coverage directory used by tools like istanbul 43 | coverage 44 | 45 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 46 | .grunt 47 | 48 | # node-waf configuration 49 | .lock-wscript 50 | 51 | # Compiled binary addons (http://nodejs.org/api/addons.html) 52 | build/Release 53 | 54 | # Dependency directory 55 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 56 | node_modules 57 | 58 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file 59 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 60 | # composer.lock 61 | 62 | ### Sass ### 63 | .sass-cache 64 | 65 | # VIM swap 66 | *.swp 67 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-plugin-wp": { 3 | "name": "WDS Mega Menu", 4 | "homepage": "http://webdevstudios.com", 5 | "description": "Make magnificently magical Mega Menus and more.", 6 | "version": "1.0.0", 7 | "author": "WebDevStudios", 8 | "authoremail": "contact@webdevstudios.com", 9 | "authorurl": "http://webdevstudios.com", 10 | "license": "GPLv2", 11 | "slug": "wds-mega-menus", 12 | "classname": "WDS_Mega_Menus", 13 | "classprefix": "WDS_Mega_Menus_", 14 | "prefix": "wds_menus", 15 | "year": 2016 16 | } 17 | } -------------------------------------------------------------------------------- /Gulpfile.js: -------------------------------------------------------------------------------- 1 | // Require our dependencies 2 | const plumber = require( 'gulp-plumber' ); 3 | const cheerio = require( 'gulp-cheerio' ); 4 | var autoprefixer = require('autoprefixer'); 5 | var cssnano = require('gulp-cssnano'); 6 | var del = require('del'); 7 | var gulp = require('gulp'); 8 | var gutil = require('gulp-util'); 9 | var notify = require('gulp-notify'); 10 | var postcss = require('gulp-postcss'); 11 | var rename = require('gulp-rename'); 12 | var sass = require('gulp-sass'); 13 | var sassLint = require('gulp-sass-lint'); 14 | var sort = require('gulp-sort'); 15 | var sourcemaps = require('gulp-sourcemaps'); 16 | var svgmin = require('gulp-svgmin'); 17 | var svgstore = require('gulp-svgstore'); 18 | var uglify = require('gulp-uglify'); 19 | var wpPot = require('gulp-wp-pot'); 20 | 21 | // Set assets paths. 22 | var paths = { 23 | css: ['assets/css/*.css', '!*.min.css'], 24 | icons: 'assets/svg/*.svg', 25 | php: ['./*.php', './**/*.php'], 26 | sass: 'assets/scss/*.scss', 27 | scripts: ['assets/js/*.js', '!assets/js/*.min.js'], 28 | }; 29 | 30 | /** 31 | * Handle errors and alert the user. 32 | */ 33 | function handleErrors () { 34 | var args = Array.prototype.slice.call(arguments); 35 | 36 | notify.onError({ 37 | title: 'Task Failed [<%= error.message %>', 38 | message: 'See console.', 39 | sound: 'Sosumi' // See: https://github.com/mikaelbr/node-notifier#all-notification-options-with-their-defaults 40 | }).apply(this, args); 41 | 42 | gutil.beep(); // Beep 'sosumi' again 43 | 44 | // Prevent the 'watch' task from stopping 45 | this.emit('end'); 46 | } 47 | 48 | /** 49 | * Delete style.css and style.min.css before we minify and optimize 50 | */ 51 | gulp.task('clean:styles', function() { 52 | return del(['admin.css', 'admin.min.css']) 53 | }); 54 | 55 | /** 56 | * Compile Sass and run stylesheet through PostCSS. 57 | * 58 | * https://www.npmjs.com/package/gulp-sass 59 | * https://www.npmjs.com/package/gulp-postcss 60 | * https://www.npmjs.com/package/gulp-autoprefixer 61 | */ 62 | gulp.task('postcss', ['clean:styles'], function() { 63 | return gulp.src('assets/scss/*.scss', paths.css) 64 | 65 | // Deal with errors. 66 | .pipe(plumber({ errorHandler: handleErrors })) 67 | 68 | // Wrap tasks in a sourcemap. 69 | .pipe(sourcemaps.init()) 70 | 71 | // Compile Sass using LibSass. 72 | .pipe(sass({ 73 | errLogToConsole: true, 74 | outputStyle: 'expanded' // Options: nested, expanded, compact, compressed 75 | })) 76 | 77 | // Parse with PostCSS plugins. 78 | .pipe(postcss([ 79 | autoprefixer({ 80 | browsers: ['last 2 version'] 81 | }), 82 | ])) 83 | 84 | // Create sourcemap. 85 | .pipe(sourcemaps.write()) 86 | 87 | // Create style.css. 88 | .pipe(gulp.dest('assets/css')) 89 | }); 90 | 91 | /** 92 | * Minify and optimize style.css. 93 | * 94 | * https://www.npmjs.com/package/gulp-cssnano 95 | */ 96 | gulp.task('cssnano', ['postcss'], function() { 97 | return gulp.src('assets/css/admin.css') 98 | .pipe(plumber({ errorHandler: handleErrors })) 99 | .pipe(cssnano({ 100 | safe: true // Use safe optimizations 101 | })) 102 | .pipe(rename('admin.min.css')) 103 | .pipe(gulp.dest('assets/css')) 104 | }); 105 | 106 | /** 107 | * Sass linting. 108 | * 109 | * https://www.npmjs.com/package/sass-lint 110 | */ 111 | gulp.task('sass:lint', ['cssnano'], function() { 112 | gulp.src([ 113 | 'assets/scss/*.scss', 114 | ]) 115 | .pipe(sassLint()) 116 | .pipe(sassLint.format()) 117 | .pipe(sassLint.failOnError()); 118 | }); 119 | 120 | /** 121 | * Delete the svg-defs.svg before we minify, concat. 122 | */ 123 | gulp.task('clean:icons', function() { 124 | return del(['assets/svg-defs.svg']); 125 | }); 126 | 127 | /** 128 | * Minify, concatenate, and clean SVG icons. 129 | * 130 | * https://www.npmjs.com/package/gulp-svgmin 131 | * https://www.npmjs.com/package/gulp-svgstore 132 | * https://www.npmjs.com/package/gulp-cheerio 133 | */ 134 | gulp.task('svg', ['clean:icons'], function() { 135 | return gulp.src(paths.icons) 136 | .pipe(plumber({ errorHandler: handleErrors })) 137 | .pipe(svgmin()) 138 | .pipe(rename({ prefix: 'icon-' })) 139 | .pipe(svgstore({ inlineSvg: true })) 140 | .pipe(cheerio({ 141 | run: function($, file) { 142 | $('svg').attr('style', 'display:none'); 143 | $('[fill]').removeAttr('fill'); 144 | $('path').removeAttr('class'); 145 | }, 146 | parserOptions: { xmlMode: true } 147 | })) 148 | .pipe(rename( 'svg-defs.svg' )) 149 | .pipe(gulp.dest('assets/')) 150 | }); 151 | 152 | /** 153 | * Minify compiled javascript after concatenated. 154 | * https://www.npmjs.com/package/gulp-uglify 155 | */ 156 | gulp.task('uglify', function() { 157 | return gulp.src(paths.scripts) 158 | .pipe(rename({suffix: '.min'})) 159 | .pipe(uglify({ 160 | mangle: false 161 | })) 162 | .pipe(gulp.dest('assets/js')); 163 | }); 164 | 165 | /** 166 | * Delete the theme's .pot before we create a new one. 167 | */ 168 | gulp.task('clean:pot', function() { 169 | return del(['languages/precept.pot']); 170 | }); 171 | 172 | /** 173 | * Scan the theme and create a POT file. 174 | * 175 | * https://www.npmjs.com/package/gulp-wp-pot 176 | */ 177 | gulp.task('wp-pot', ['clean:pot'], function() { 178 | return gulp.src(paths.php) 179 | .pipe(plumber({ errorHandler: handleErrors })) 180 | .pipe(sort()) 181 | .pipe(wpPot({ 182 | destFile:'wds-mega-menus.pot', 183 | package: 'wds-mega-menus' 184 | })) 185 | .pipe(gulp.dest('languages/')); 186 | }); 187 | 188 | /** 189 | * Process tasks and reload browsers on file changes. 190 | * 191 | * https://www.npmjs.com/package/browser-sync 192 | */ 193 | gulp.task('watch', function() { 194 | 195 | // Run tasks when files change. 196 | gulp.watch(paths.icons, ['icons']); 197 | gulp.watch(paths.sass, ['styles']); 198 | gulp.watch(paths.scripts, ['scripts']); 199 | }); 200 | 201 | /** 202 | * Create individual tasks. 203 | */ 204 | gulp.task('i18n', ['wp-pot']); 205 | gulp.task('icons', ['svg']); 206 | gulp.task('scripts', ['uglify']); 207 | gulp.task('styles', ['cssnano']); 208 | gulp.task('default', [ 'i18n', 'icons', 'styles', 'scripts']); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WDS Mega Menus 2 | **Contributors:** [dustyf](https://github.com/dustyf), [jazzsequence](https://github.com/jazzsequence), [CamdenSegal](https://github.com/CamdenSegal), [aubreypwd](https://github.com/aubreypwd), [coreymcollins](https://github.com/coreymcollins), [phatsk](https://github.io/phatsk), [PavelK27](https://github.com/PavelK27), [jomurgel](https://github.com/jomurgel) 3 | **Donate link:** http://webdevstudios.com 4 | **Tags:** 5 | **Requires at least:** 3.6.0 6 | **Tested up to:** 4.6.1 7 | **Stable tag:** 0.3.1 8 | **License:** GPLv2 9 | **License URI:** http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | ## Description ## 12 | 13 | Make magnificently magical Mega Menus. 14 | 15 | **License:** GPLv2 16 | 17 | **License URI:** http://www.gnu.org/licenses/gpl-2.0.html 18 | 19 | This project is currently under development. If you want to help out, 20 | check out the [Issues](https://github.com/WebDevStudios/WDS-Mega-Menu/issues) tab. 21 | 22 | ### To Use 23 | 24 | #### The Easy Way 25 | 26 | As of version 0.2.1, if you have nothing hooked on the `wdsmm_walker_nav_allowed_depths` filter, a 27 | new admin page called "WDS Mega Menus" will appear under the WordPress Appearance menu. 28 | 29 | #### The Manual Way 30 | 31 | To use, you must tell WDS Mega Menu which menu levels to apply to. E.g.: 32 | 33 | ``` 34 | function my_allowed_depths( $array ) { 35 | // Allow at depths 0, 1, 2, and 3. 36 | return array( 0, 1, 2, 3 ); 37 | } 38 | 39 | add_filter( 'wdsmm_walker_nav_allowed_depths', 'my_allowed_depths' ); 40 | ``` 41 | 42 | #### ❕0.3.0 Compatibility Notice 43 | 44 | Previously, the filter was named `wds_mega_menus_walker_nav_menu_edit_allowed_depths`. This filter has been renamed to `wdsmm_walker_nav_allowed_depths`. Please update your functions if you are upgrading from a version earlier than 0.3.0. 45 | 46 | ## Installation ## 47 | 48 | ### Manual Installation ### 49 | 50 | 1. Upload the entire `/wds-mega-menus` directory to the `/wp-content/plugins/` directory. 51 | 2. Activate WDS Mega Menus through the 'Plugins' menu in WordPress. 52 | 53 | ## Frequently Asked Questions ## 54 | _none yet_ 55 | 56 | ## Screenshots ## 57 | ![Menu Editor Item View](assets/screenshot-1.png?raw=true) 58 | 59 | ## Changelog ## 60 | 61 | ### 0.3.1 ### 62 | * Various bug fixes. 63 | * Better SVG support. 64 | * Javascript updates for better practices. 65 | 66 | ### 0.3.0 ### 67 | * Default SVG icons now appear in admin dropdown if no SVG icons exist in theme. 68 | * Depths updated to checkboxes for allowed levels. 69 | * Code cleanup. 70 | 71 | ### 0.2.1 ### 72 | * Add options page (hidden if filter is set). 73 | * Allow depths to be configured from the admin area. 74 | 75 | ### 0.1.0 ### 76 | * First release 77 | 78 | -------------------------------------------------------------------------------- /assets/css/admin.min.css: -------------------------------------------------------------------------------- 1 | .sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.btn,[role=button]{cursor:pointer}.btn{background-image:none;border-radius:4px;border:1px solid transparent;display:inline-block;font-size:14px;font-weight:400;line-height:1.42857143;margin-bottom:0;padding:6px 12px;text-align:center;-ms-touch-action:manipulation;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline-offset:-2px;outline:5px auto -webkit-focus-ring-color;outline:thin dotted}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-image:none;box-shadow:inset 0 3px 5px rgba(0,0,0,.125);outline:0}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{box-shadow:none;cursor:not-allowed;filter:alpha(opacity=65);opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#e6e6e6}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#e6e6e6}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#337ab7}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary.active,.btn-primary:active,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#337ab7}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-success.active,.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success.focus,.btn-success:active,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#449d44;border-color:#449d44}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#5cb85c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-info.active,.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info.focus,.btn-info:active,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#31b0d5}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#5bc0de}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning.active,.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning.focus,.btn-warning:active,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#ec971f}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-danger.active,.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger.focus,.btn-danger:active,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#c9302c}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d9534f}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:400;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#286090;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.caret{display:inline-block;width:0;height:0;margin-left:15px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{-webkit-background-clip:padding-box;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box;background-color:#fff;border-radius:4px;border:1px solid #e6e6e6;border:1px solid rgba(0,0,0,.15);box-shadow:0 6px 12px rgba(0,0,0,.175);display:none;float:left;font-size:14px;left:0;list-style:none;margin:2px 0 0;min-width:160px;padding:5px 0;position:absolute;text-align:left;top:57px;z-index:1000}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e6e6e6}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#262626;background-color:#e6e6e6}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active{outline:0}.btn-group.open .dropdown-toggle{outline:0;box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{box-shadow:none}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before{content:" ";display:table}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}.dropdown-menu>li>label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>label:focus,.dropdown-menu>li>label:hover{text-decoration:none;color:#262626;background-color:#e6e6e6}.dropdown-menu>.active>label,.dropdown-menu>.active>label:focus,.dropdown-menu>.active>label:hover,.dropdown-menu>li>input:checked~label,.dropdown-menu>li>input:checked~label:focus,.dropdown-menu>li>input:checked~label:hover{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>label,.dropdown-menu>.disabled>label:focus,.dropdown-menu>.disabled>label:hover,.dropdown-menu>li>input[disabled]~label,.dropdown-menu>li>input[disabled]~label:focus,.dropdown-menu>li>input[disabled]~label:hover{color:#999}.dropdown-menu>.disabled>label:focus,.dropdown-menu>.disabled>label:hover,.dropdown-menu>li>input[disabled]~label:focus,.dropdown-menu>li>input[disabled]~label:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.dropdown-menu>li>label{margin-bottom:0;cursor:pointer}.dropdown-menu>li>input[type=checkbox],.dropdown-menu>li>input[type=radio]{display:none;position:absolute;top:-9999em;left:-9999em}.dropdown-menu>li>input:focus~label,.dropdown-menu>li>label:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu.pull-top{bottom:100%;top:auto;margin:0 0 2px;box-shadow:0 -6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-center{right:50%;left:auto}.dropdown-menu.pull-middle{right:100%;margin:0 2px 0 0;box-shadow:-5px 0 10px rgba(0,0,0,.2);left:auto}.dropdown-menu.pull-middle.pull-right{right:auto;left:100%;margin:0 0 0 2px;box-shadow:5px 0 10px rgba(0,0,0,.2)}.dropdown-menu.pull-middle.pull-center{right:50%;margin:0;box-shadow:0 0 10px rgba(0,0,0,.2)}.dropdown-menu.bullet{margin-top:8px}.dropdown-menu.bullet:before{border-color:transparent;border-style:solid;border-width:0 7px 7px;border-bottom-color:#e6e6e6;border-bottom-color:rgba(0,0,0,.15);top:-7px;left:9px}.dropdown-menu.bullet:after,.dropdown-menu.bullet:before{width:0;height:0;content:'';display:inline-block;position:absolute;-webkit-transform:rotate(1turn)}.dropdown-menu.bullet:after{border-color:transparent;border-style:solid;border-width:0 6px 6px;border-bottom-color:#fff;top:-6px;left:10px}.dropdown-menu.bullet.pull-right:before{left:auto;right:9px}.dropdown-menu.bullet.pull-right:after{left:auto;right:10px}.dropdown-menu.bullet.pull-top{margin-top:0;margin-bottom:8px}.dropdown-menu.bullet.pull-top:before{top:auto;bottom:-7px;border-bottom-width:0;border-top-width:7px;border-top-color:#e6e6e6;border-top-color:rgba(0,0,0,.15)}.dropdown-menu.bullet.pull-top:after{top:auto;bottom:-6px;border-bottom:none;border-top-width:6px;border-top-color:#fff}.dropdown-menu.bullet.pull-center:before{left:auto;right:50%;margin-right:-7px}.dropdown-menu.bullet.pull-center:after{left:auto;right:50%;margin-right:-6px}.dropdown-menu.bullet.pull-middle{margin-right:8px}.dropdown-menu.bullet.pull-middle:before{margin-top:-7px;border-top-width:7px;border-left-color:#e6e6e6;border-left-color:rgba(0,0,0,.15)}.dropdown-menu.bullet.pull-middle:after,.dropdown-menu.bullet.pull-middle:before{top:50%;left:100%;right:auto;border-right-width:0;border-bottom-color:transparent}.dropdown-menu.bullet.pull-middle:after{margin-top:-6px;border-top-width:6px;border-left-color:#fff}.dropdown-menu.bullet.pull-middle.pull-right{margin-right:0;margin-left:8px}.dropdown-menu.bullet.pull-middle.pull-right:before{left:-7px;border-left-width:0;border-right-width:7px;border-right-color:#e6e6e6;border-right-color:rgba(0,0,0,.15)}.dropdown-menu.bullet.pull-middle.pull-right:after{left:-6px;border-left-width:0;border-right-width:6px;border-right-color:#fff}.dropdown-menu.bullet.pull-middle.pull-center{margin-left:0;margin-right:0}.dropdown-menu.bullet.pull-middle.pull-center:after,.dropdown-menu.bullet.pull-middle.pull-center:before{border:none;display:none}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;border-top-left-radius:0}.dropdown-submenu>a:before{display:block;float:right;width:0;height:0;content:"";margin-top:6px;margin-right:-8px;border-width:4px 0 4px 4px;border-style:solid;border-left-style:dashed;border-top-color:transparent;border-bottom-color:transparent}@media (max-width:767px){.navbar-nav .dropdown-submenu>a{padding-left:40px}.navbar-nav .dropdown-submenu>a:before{margin-top:8px;border-color:inherit;border-style:solid;border-width:4px 4px 0;border-left-color:transparent;border-right-color:transparent}.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>a,.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>label{padding-left:35px}.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>a,.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>label{padding-left:45px}.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>a,.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>label{padding-left:55px}.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>a,.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>label{padding-left:65px}.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>a,.navbar-nav>.open>.dropdown-menu>.dropdown-submenu>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>.dropdown-menu>li>label{padding-left:75px}}.navbar-default .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a,.navbar-default .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:focus,.navbar-default .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:hover{background-color:#e6e6e6;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:before{border-top-color:#555}}.navbar-inverse .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a,.navbar-inverse .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:focus,.navbar-inverse .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:hover{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open>.dropdown-menu>.dropdown-submenu.open>a:before{border-top-color:#fff}}.btn-group ul.dropdown-menu{max-height:250px;overflow:scroll}.btn-group svg.icon{height:14px;position:absolute;top:6px;left:3px;max-width:15px}.btn-group li:hover{background-color:#e6e6e6}.btn-default svg.icon{height:14px;margin-right:5px;position:relative;top:2px;width:14px} -------------------------------------------------------------------------------- /assets/css/user.css: -------------------------------------------------------------------------------- 1 | .menu-item svg.icon { 2 | height: 14px; 3 | margin-right: 5px; 4 | position: relative; 5 | top: 2px; 6 | width: 14px; 7 | } 8 | -------------------------------------------------------------------------------- /assets/js/dropdowns-enhancement.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap Dropdowns Enhancement: dropdowns-enhancement.js v3.1.1 (Beta 1) 3 | * http://behigh.github.io/bootstrap_dropdowns_enhancement/ 4 | * ======================================================================== 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * ======================================================================== */ 7 | 8 | (function($) { 9 | "use strict"; 10 | 11 | var toggle = '[data-toggle="dropdown"]', 12 | disabled = '.disabled, :disabled', 13 | backdrop = '.dropdown-backdrop', 14 | menuClass = 'dropdown-menu', 15 | subMenuClass = 'dropdown-submenu', 16 | namespace = '.bs.dropdown.data-api', 17 | eventNamespace = '.bs.dropdown', 18 | openClass = 'open', 19 | touchSupport = 'ontouchstart' in document.documentElement, 20 | opened; 21 | 22 | 23 | function Dropdown(element) { 24 | $(element).on('click' + eventNamespace, this.toggle) 25 | } 26 | 27 | var proto = Dropdown.prototype; 28 | 29 | proto.toggle = function(event) { 30 | var $element = $(this); 31 | 32 | if ($element.is(disabled)) return; 33 | 34 | var $parent = getParent($element); 35 | var isActive = $parent.hasClass(openClass); 36 | var isSubMenu = $parent.hasClass(subMenuClass); 37 | var menuTree = isSubMenu ? getSubMenuParents($parent) : null; 38 | 39 | closeOpened(event, menuTree); 40 | 41 | if (!isActive) { 42 | if (!menuTree) 43 | menuTree = [$parent]; 44 | 45 | if (touchSupport && !$parent.closest('.navbar-nav').length && !menuTree[0].find(backdrop).length) { 46 | // if mobile we use a backdrop because click events don't delegate 47 | $('
').appendTo(menuTree[0]).on('click', closeOpened) 48 | } 49 | 50 | for (var i = 0, s = menuTree.length; i < s; i++) { 51 | if (!menuTree[i].hasClass(openClass)) { 52 | menuTree[i].addClass(openClass); 53 | positioning(menuTree[i].children('.' + menuClass), menuTree[i]); 54 | } 55 | } 56 | opened = menuTree[0]; 57 | } 58 | 59 | return false; 60 | }; 61 | 62 | proto.keydown = function (e) { 63 | if (!/(38|40|27)/.test(e.keyCode)) return; 64 | 65 | var $this = $(this); 66 | 67 | e.preventDefault(); 68 | e.stopPropagation(); 69 | 70 | if ($this.is('.disabled, :disabled')) return; 71 | 72 | var $parent = getParent($this); 73 | var isActive = $parent.hasClass('open'); 74 | 75 | if (!isActive || (isActive && e.keyCode == 27)) { 76 | if (e.which == 27) $parent.find(toggle).trigger('focus'); 77 | return $this.trigger('click') 78 | } 79 | 80 | var desc = ' li:not(.divider):visible a'; 81 | var desc1 = 'li:not(.divider):visible > input:not(disabled) ~ label'; 82 | var $items = $parent.find(desc1 + ', ' + '[role="menu"]' + desc + ', [role="listbox"]' + desc); 83 | 84 | if (!$items.length) return; 85 | 86 | var index = $items.index($items.filter(':focus')); 87 | 88 | if (e.keyCode == 38 && index > 0) index--; // up 89 | if (e.keyCode == 40 && index < $items.length - 1) index++; // down 90 | if (!~index) index = 0; 91 | 92 | $items.eq(index).trigger('focus') 93 | }; 94 | 95 | proto.change = function (e) { 96 | 97 | var 98 | $parent, 99 | $menu, 100 | $toggle, 101 | selector, 102 | text = '', 103 | $items; 104 | 105 | $menu = $(this).closest('.' + menuClass); 106 | 107 | $toggle = $menu.parent().find('[data-label-placement]'); 108 | 109 | if (!$toggle || !$toggle.length) { 110 | $toggle = $menu.parent().find(toggle); 111 | } 112 | 113 | if (!$toggle || !$toggle.length || $toggle.data('placeholder') === false) 114 | return; // do nothing, no control 115 | 116 | ($toggle.data('placeholder') == undefined && $toggle.data('placeholder', $.trim($toggle.text()))); 117 | text = $.data($toggle[0], 'placeholder'); 118 | 119 | $items = $menu.find('li > input:checked'); 120 | 121 | if ($items.length) { 122 | text = []; 123 | $items.each(function () { 124 | var str = $(this).parent().find('label').eq(0), 125 | label = str.find('.data-label'); 126 | 127 | if (label.length) { 128 | var p = $('

'); 129 | p.append(label.clone()); 130 | str = p.html(); 131 | } 132 | else { 133 | str = str.html(); 134 | } 135 | 136 | 137 | str && text.push($.trim(str)); 138 | }); 139 | 140 | text = text.length < 4 ? text.join(', ') : text.length + ' selected'; 141 | } 142 | 143 | var caret = $toggle.find('.caret'); 144 | 145 | $toggle.html(text || ' '); 146 | if (caret.length) 147 | $toggle.append(' ') && caret.appendTo($toggle); 148 | 149 | }; 150 | 151 | function positioning($menu, $control) { 152 | if ($menu.hasClass('pull-center')) { 153 | $menu.css('margin-right', $menu.outerWidth() / -2); 154 | } 155 | 156 | if ($menu.hasClass('pull-middle')) { 157 | $menu.css('margin-top', ($menu.outerHeight() / -2) - ($control.outerHeight() / 2)); 158 | } 159 | } 160 | 161 | function closeOpened(event, menuTree) { 162 | if (opened) { 163 | 164 | if (!menuTree) { 165 | menuTree = [opened]; 166 | } 167 | 168 | var parent; 169 | 170 | if (opened[0] !== menuTree[0][0]) { 171 | parent = opened; 172 | } else { 173 | parent = menuTree[menuTree.length - 1]; 174 | if (parent.parent().hasClass(menuClass)) { 175 | parent = parent.parent(); 176 | } 177 | } 178 | 179 | parent.find('.' + openClass).removeClass(openClass); 180 | 181 | if (parent.hasClass(openClass)) 182 | parent.removeClass(openClass); 183 | 184 | if (parent === opened) { 185 | opened = null; 186 | $(backdrop).remove(); 187 | } 188 | } 189 | } 190 | 191 | function getSubMenuParents($submenu) { 192 | var result = [$submenu]; 193 | var $parent; 194 | while (!$parent || $parent.hasClass(subMenuClass)) { 195 | $parent = ($parent || $submenu).parent(); 196 | if ($parent.hasClass(menuClass)) { 197 | $parent = $parent.parent(); 198 | } 199 | if ($parent.children(toggle)) { 200 | result.unshift($parent); 201 | } 202 | } 203 | return result; 204 | } 205 | 206 | function getParent($this) { 207 | var selector = $this.attr('data-target'); 208 | 209 | if (!selector) { 210 | selector = $this.attr('href'); 211 | selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7 212 | } 213 | 214 | var $parent = selector && $(selector); 215 | 216 | return $parent && $parent.length ? $parent : $this.parent() 217 | } 218 | 219 | // DROPDOWN PLUGIN DEFINITION 220 | // ========================== 221 | 222 | var old = $.fn.dropdown; 223 | 224 | $.fn.dropdown = function (option) { 225 | return this.each(function () { 226 | var $this = $(this); 227 | var data = $this.data('bs.dropdown'); 228 | 229 | if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))); 230 | if (typeof option == 'string') data[option].call($this); 231 | }) 232 | }; 233 | 234 | $.fn.dropdown.Constructor = Dropdown; 235 | 236 | $.fn.dropdown.clearMenus = function(e) { 237 | $(backdrop).remove(); 238 | $('.' + openClass + ' ' + toggle).each(function () { 239 | var $parent = getParent($(this)); 240 | var relatedTarget = { relatedTarget: this }; 241 | if (!$parent.hasClass('open')) return; 242 | $parent.trigger(e = $.Event('hide' + eventNamespace, relatedTarget)); 243 | if (e.isDefaultPrevented()) return; 244 | $parent.removeClass('open').trigger('hidden' + eventNamespace, relatedTarget); 245 | }); 246 | return this; 247 | }; 248 | 249 | 250 | // DROPDOWN NO CONFLICT 251 | // ==================== 252 | 253 | $.fn.dropdown.noConflict = function () { 254 | $.fn.dropdown = old; 255 | return this 256 | }; 257 | 258 | 259 | $(document).off(namespace) 260 | .on('click' + namespace, closeOpened) 261 | .on('click' + namespace, toggle, proto.toggle) 262 | .on('click' + namespace, '.dropdown-menu > li > input[type="checkbox"] ~ label, .dropdown-menu > li > input[type="checkbox"], .dropdown-menu.noclose > li', function (e) { 263 | e.stopPropagation() 264 | }) 265 | .on('change' + namespace, '.dropdown-menu > li > input[type="checkbox"], .dropdown-menu > li > input[type="radio"]', proto.change) 266 | .on('keydown' + namespace, toggle + ', [role="menu"], [role="listbox"]', proto.keydown) 267 | }(jQuery)); -------------------------------------------------------------------------------- /assets/js/dropdowns-enhancement.min.js: -------------------------------------------------------------------------------- 1 | !function($){"use strict";function Dropdown(element){$(element).on("click"+eventNamespace,this.toggle)}function positioning($menu,$control){$menu.hasClass("pull-center")&&$menu.css("margin-right",$menu.outerWidth()/-2),$menu.hasClass("pull-middle")&&$menu.css("margin-top",$menu.outerHeight()/-2-$control.outerHeight()/2)}function closeOpened(event,menuTree){if(opened){menuTree||(menuTree=[opened]);var parent;opened[0]!==menuTree[0][0]?parent=opened:(parent=menuTree[menuTree.length-1],parent.parent().hasClass(menuClass)&&(parent=parent.parent())),parent.find("."+openClass).removeClass(openClass),parent.hasClass(openClass)&&parent.removeClass(openClass),parent===opened&&(opened=null,$(backdrop).remove())}}function getSubMenuParents($submenu){for(var $parent,result=[$submenu];!$parent||$parent.hasClass(subMenuClass);)$parent=($parent||$submenu).parent(),$parent.hasClass(menuClass)&&($parent=$parent.parent()),$parent.children(toggle)&&result.unshift($parent);return result}function getParent($this){var selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&/#[A-Za-z]/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,""));var $parent=selector&&$(selector);return $parent&&$parent.length?$parent:$this.parent()}var opened,toggle='[data-toggle="dropdown"]',disabled=".disabled, :disabled",backdrop=".dropdown-backdrop",menuClass="dropdown-menu",subMenuClass="dropdown-submenu",namespace=".bs.dropdown.data-api",eventNamespace=".bs.dropdown",openClass="open",touchSupport="ontouchstart"in document.documentElement,proto=Dropdown.prototype;proto.toggle=function(event){var $element=$(this);if(!$element.is(disabled)){var $parent=getParent($element),isActive=$parent.hasClass(openClass),isSubMenu=$parent.hasClass(subMenuClass),menuTree=isSubMenu?getSubMenuParents($parent):null;if(closeOpened(event,menuTree),!isActive){menuTree||(menuTree=[$parent]),!touchSupport||$parent.closest(".navbar-nav").length||menuTree[0].find(backdrop).length||$('
').appendTo(menuTree[0]).on("click",closeOpened);for(var i=0,s=menuTree.length;i0&&index--,40==e.keyCode&&index<$items.length-1&&index++,~index||(index=0),$items.eq(index).trigger("focus")}}}},proto.change=function(e){var $menu,$toggle,$items,text="";if($menu=$(this).closest("."+menuClass),$toggle=$menu.parent().find("[data-label-placement]"),$toggle&&$toggle.length||($toggle=$menu.parent().find(toggle)),$toggle&&$toggle.length&&$toggle.data("placeholder")!==!1){void 0==$toggle.data("placeholder")&&$toggle.data("placeholder",$.trim($toggle.text())),text=$.data($toggle[0],"placeholder"),$items=$menu.find("li > input:checked"),$items.length&&(text=[],$items.each(function(){var str=$(this).parent().find("label").eq(0),label=str.find(".data-label");if(label.length){var p=$("

");p.append(label.clone()),str=p.html()}else str=str.html();str&&text.push($.trim(str))}),text=text.length<4?text.join(", "):text.length+" selected");var caret=$toggle.find(".caret");$toggle.html(text||" "),caret.length&&$toggle.append(" ")&&caret.appendTo($toggle)}};var old=$.fn.dropdown;$.fn.dropdown=function(option){return this.each(function(){var $this=$(this),data=$this.data("bs.dropdown");data||$this.data("bs.dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})},$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.clearMenus=function(e){return $(backdrop).remove(),$("."+openClass+" "+toggle).each(function(){var $parent=getParent($(this)),relatedTarget={relatedTarget:this};$parent.hasClass("open")&&($parent.trigger(e=$.Event("hide"+eventNamespace,relatedTarget)),e.isDefaultPrevented()||$parent.removeClass("open").trigger("hidden"+eventNamespace,relatedTarget))}),this},$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).off(namespace).on("click"+namespace,closeOpened).on("click"+namespace,toggle,proto.toggle).on("click"+namespace,'.dropdown-menu > li > input[type="checkbox"] ~ label, .dropdown-menu > li > input[type="checkbox"], .dropdown-menu.noclose > li',function(e){e.stopPropagation()}).on("change"+namespace,'.dropdown-menu > li > input[type="checkbox"], .dropdown-menu > li > input[type="radio"]',proto.change).on("keydown"+namespace,toggle+', [role="menu"], [role="listbox"]',proto.keydown)}(jQuery); -------------------------------------------------------------------------------- /assets/js/wds-mega-menus.js: -------------------------------------------------------------------------------- 1 | (function(global){ 2 | 'use strict'; 3 | var $ = $ || jQuery; 4 | 5 | /** 6 | * WDS Mega Menu JS Class 7 | */ 8 | function WDS_Mega_Menu() { 9 | if ( WDS_Mega_Menu.prototype._singleton ) { 10 | return WDS_Mega_Menu.prototype._singleton; 11 | } 12 | 13 | WDS_Mega_Menu.prototype._singleton = this; 14 | 15 | /** 16 | * Callback function for the 'click' event of the 'Set Footer Image' 17 | * anchor in its meta box. 18 | * 19 | * Displays the media uploader for selecting an image. 20 | * 21 | * @since 0.1.0 22 | * @author Dustin Filippini, Zach Owen 23 | * 24 | * @param string element_id The ID of the mega menu target. 25 | */ 26 | this.renderMediaUploader = function( element_id ) { 27 | var file_frame; 28 | var image_data; 29 | 30 | /** 31 | * If an instance of file_frame already exists, then we can open it 32 | * rather than creating a new instance. 33 | */ 34 | if ( undefined !== file_frame ) { 35 | file_frame.open(); 36 | return; 37 | } 38 | 39 | /** 40 | * If we're this far, then an instance does not exist, so we need to 41 | * create our own. 42 | * 43 | * Here, use the wp.media library to define the settings of the Media 44 | * Uploader. We're opting to use the 'post' frame which is a template 45 | * defined in WordPress core and are initializing the file frame 46 | * with the 'insert' state. 47 | * 48 | * We're also not allowing the user to select more than one image. 49 | */ 50 | file_frame = wp.media.frames.file_frame = wp.media({ 51 | frame: 'post', 52 | state: 'insert', 53 | multiple: false 54 | }); 55 | 56 | /** 57 | * Setup an event handler for what to do when an image has been 58 | * selected. 59 | * 60 | * Since we're using the 'view' state when initializing 61 | * the file_frame, we need to make sure that the handler is attached 62 | * to the insert event. 63 | * 64 | * @TODO this function should be lifted out of the anonymous call if there could ever be 65 | * @TODO a case where someone might want to unbind it from the 'insert' event. -ZO 66 | */ 67 | file_frame.on( 'insert', function() { 68 | // Read the JSON data returned from the Media Uploader 69 | var json = file_frame.state().get( 'selection' ).first().toJSON(); 70 | 71 | // First, make sure that we have the URL of an image to display 72 | if ( 0 > jQuery.trim( json.url.length ) ) { 73 | return; 74 | } 75 | 76 | // After that, set the properties of the image and display it 77 | jQuery( '#menu-item-image-container-' + element_id ) 78 | .children( 'img' ) 79 | .attr({ 80 | 'src': json.url, 81 | 'alt': json.caption, 82 | 'title': json.title 83 | }) 84 | .show() 85 | .parent() 86 | .removeClass( 'hidden' ); 87 | 88 | jQuery( '#menu-item-image-' + element_id ).val( json.id ); 89 | 90 | // Next, hide the anchor responsible for allowing the user to select an image 91 | jQuery( '#menu-item-image-container-' + element_id ) 92 | .prev() 93 | .hide(); 94 | 95 | jQuery( '#menu-item-image-container-' + element_id ) 96 | .next() 97 | .show(); 98 | }); 99 | 100 | // Now display the actual file_frame 101 | file_frame.open(); 102 | }; 103 | 104 | /** 105 | * Callback function for the 'click' event of the 'Remove Footer Image' 106 | * anchor in its meta box. 107 | * 108 | * Resets the meta box by hiding the image and by hiding the 'Remove 109 | * Footer Image' container. 110 | * 111 | * @since 0.2.0 112 | * @param string element_id The ID of the mega menu target. 113 | */ 114 | this.resetUploadForm = function( element_id ) { 115 | // First, we'll hide the image 116 | $( '#menu-item-image-container-' + element_id ) 117 | .children( 'img' ) 118 | .hide(); 119 | 120 | // Then display the previous container 121 | $( '#menu-item-image-container-' + element_id ) 122 | .prev() 123 | .show(); 124 | 125 | // Finally, we add the 'hidden' class back to this anchor's parent 126 | $( '#menu-item-image-container-' + element_id ) 127 | .next() 128 | .hide() 129 | .addClass( 'hidden' ); 130 | 131 | jQuery( '#menu-item-image-' + element_id ).val( '' ); 132 | }; 133 | 134 | /** 135 | * Checks to see if the input field for the thumbnail source has a value. 136 | * If so, then the image and the 'Remove featured image' anchor are displayed. 137 | * 138 | * Otherwise, the standard anchor is rendered. 139 | * 140 | * @since 0.1.0 141 | * @author Dustin Filippini, Zach Owen 142 | * 143 | * @param string element_id The ID of the mega menu target. 144 | */ 145 | this.renderFeaturedImage = function( element_id ) { 146 | /* If a thumbnail URL has been associated with this image 147 | * Then we need to display the image and the reset link. 148 | */ 149 | if ( 0 < $.trim( $( '#menu-item-image-' + element_id ).val() ).length ) { 150 | $( '#menu-item-image-container-' + element_id ).removeClass( 'hidden' ); 151 | 152 | $( '#set-menu-item-image-' + element_id ) 153 | .parent() 154 | .hide(); 155 | 156 | $( '#remove-menu-item-image-' + element_id ) 157 | .parent() 158 | .removeClass( 'hidden' ); 159 | } 160 | }; 161 | 162 | /** 163 | * Inits the edit menu buttons based on IDs from the localization. 164 | * 165 | * @since 0.3.1 166 | * 167 | * @author Zach Owen 168 | */ 169 | this.initEditMenu = function() { 170 | if ( ! global.hasOwnProperty( 'WDS_MegaMenu_Loc' ) ) { 171 | return; 172 | } 173 | 174 | for ( var key in global.WDS_MegaMenu_Loc.featured_ids ) { 175 | if ( ! global.WDS_MegaMenu_Loc.featured_ids.hasOwnProperty( key ) ) { 176 | continue; 177 | } 178 | 179 | registerMenuButton( parseInt( global.WDS_MegaMenu_Loc.featured_ids[ key ], 10 ) ); 180 | } 181 | }; 182 | 183 | /** 184 | * Initialize the options page controls. 185 | */ 186 | this.initOptionsPage = function() { 187 | registerOptionsControls(); 188 | }; 189 | } 190 | 191 | global.WDS = global.WDS || {}; 192 | global.WDS.MegaMenu = new WDS_Mega_Menu(); 193 | $( document ).ready( global.WDS.MegaMenu.initEditMenu ); 194 | $( document ).ready( global.WDS.MegaMenu.initOptionsPage ); 195 | 196 | /** 197 | * Register the menu button listeners for the menu editor. 198 | * 199 | * @since 0.3.1 200 | * 201 | * @param int id The ID of the post object we're setting buttons for. 202 | * 203 | * @author Zach Owen 204 | */ 205 | function registerMenuButton( id ) { 206 | WDS.MegaMenu.renderFeaturedImage( id ); 207 | $( '#set-menu-item-image-' + id ).on( 'click', function( e ) { 208 | e.preventDefault(); 209 | WDS.MegaMenu.renderMediaUploader( id ); 210 | }); 211 | 212 | $( '#remove-menu-item-image-' + id ).on( 'click', function( evt ) { 213 | 214 | // Stop the anchor's default behavior 215 | evt.preventDefault(); 216 | 217 | // Remove the image, toggle the anchors 218 | WDS.MegaMenu.resetUploadForm( id ); 219 | }); 220 | } 221 | 222 | /** 223 | * Registers our handlers for the Options Page checkboxes. 224 | * 225 | * @since 0.3.1 226 | * @author Zach Owen 227 | */ 228 | function registerOptionsControls() { 229 | var $all_depths = $( '#all_depths' ); 230 | var $depth_input_last = $( ".depth_options li:not(:last-child) input" ); 231 | // Check all items if All depths checked and lock them 232 | if ( $all_depths.length ) { 233 | $all_depths.change( function() { 234 | if(this.checked) { 235 | /** 236 | * I don't think we need to disable these if the last is checked. 237 | * The mechanism of unchecking it once another option is changed works well. 238 | * -ZO 239 | */ 240 | $( ".depth_options" ).find( "li:not(:last-child) input" ).attr({ 241 | checked: "checked" 242 | }); 243 | } 244 | }); 245 | } 246 | 247 | // Uncheck All depth checkbox if any other item was unchecked 248 | if ( $depth_input_last.length ) { 249 | $( $depth_input_last ).change( function() { 250 | $all_depths.removeAttr( 'checked' ); 251 | }); 252 | } 253 | } 254 | })(window); 255 | -------------------------------------------------------------------------------- /assets/js/wds-mega-menus.min.js: -------------------------------------------------------------------------------- 1 | !function(global){"use strict";function WDS_Mega_Menu(){return WDS_Mega_Menu.prototype._singleton?WDS_Mega_Menu.prototype._singleton:(WDS_Mega_Menu.prototype._singleton=this,this.renderMediaUploader=function(element_id){var file_frame;return void 0!==file_frame?void file_frame.open():(file_frame=wp.media.frames.file_frame=wp.media({frame:"post",state:"insert",multiple:!1}),file_frame.on("insert",function(){var json=file_frame.state().get("selection").first().toJSON();0>jQuery.trim(json.url.length)||(jQuery("#menu-item-image-container-"+element_id).children("img").attr({src:json.url,alt:json.caption,title:json.title}).show().parent().removeClass("hidden"),jQuery("#menu-item-image-"+element_id).val(json.id),jQuery("#menu-item-image-container-"+element_id).prev().hide(),jQuery("#menu-item-image-container-"+element_id).next().show())}),void file_frame.open())},this.resetUploadForm=function(element_id){$("#menu-item-image-container-"+element_id).children("img").hide(),$("#menu-item-image-container-"+element_id).prev().show(),$("#menu-item-image-container-"+element_id).next().hide().addClass("hidden"),jQuery("#menu-item-image-"+element_id).val("")},this.renderFeaturedImage=function(element_id){0<$.trim($("#menu-item-image-"+element_id).val()).length&&($("#menu-item-image-container-"+element_id).removeClass("hidden"),$("#set-menu-item-image-"+element_id).parent().hide(),$("#remove-menu-item-image-"+element_id).parent().removeClass("hidden"))},this.initEditMenu=function(){if(global.hasOwnProperty("WDS_MegaMenu_Loc"))for(var key in global.WDS_MegaMenu_Loc.featured_ids)global.WDS_MegaMenu_Loc.featured_ids.hasOwnProperty(key)&®isterMenuButton(parseInt(global.WDS_MegaMenu_Loc.featured_ids[key],10))},void(this.initOptionsPage=function(){registerOptionsControls()}))}function registerMenuButton(id){WDS.MegaMenu.renderFeaturedImage(id),$("#set-menu-item-image-"+id).on("click",function(e){e.preventDefault(),WDS.MegaMenu.renderMediaUploader(id)}),$("#remove-menu-item-image-"+id).on("click",function(evt){evt.preventDefault(),WDS.MegaMenu.resetUploadForm(id)})}function registerOptionsControls(){var $all_depths=$("#all_depths"),$depth_input_last=$(".depth_options li:not(:last-child) input");$all_depths.length&&$all_depths.change(function(){this.checked&&$(".depth_options").find("li:not(:last-child) input").attr({checked:"checked"})}),$depth_input_last.length&&$($depth_input_last).change(function(){$all_depths.removeAttr("checked")})}var $=$||jQuery;global.WDS=global.WDS||{},global.WDS.MegaMenu=new WDS_Mega_Menu,$(document).ready(global.WDS.MegaMenu.initEditMenu),$(document).ready(global.WDS.MegaMenu.initOptionsPage)}(window); -------------------------------------------------------------------------------- /assets/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevStudios/WDS-Mega-Menu/1d0aa71d87130879f9a9b6f9a1d9ef922b1ac73b/assets/screenshot-1.png -------------------------------------------------------------------------------- /assets/scss/_bootstrap_styles.scss: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Bootstrap Styles: http://getbootstrap.com 3 | //-------------------------------------------------------------- 4 | 5 | .sr-only { 6 | border: 0; 7 | clip: rect(0, 0, 0, 0); 8 | height: 1px; 9 | margin: -1px; 10 | overflow: hidden; 11 | padding: 0; 12 | position: absolute; 13 | width: 1px; 14 | } 15 | 16 | .sr-only-focusable { 17 | 18 | &:active, 19 | &:focus { 20 | clip: auto; 21 | height: auto; 22 | margin: 0; 23 | overflow: visible; 24 | position: static; 25 | width: auto; 26 | } 27 | } 28 | 29 | //----------------------------------------- 30 | // Buttons 31 | //----------------------------------------- 32 | [role="button"] { 33 | cursor: pointer; 34 | } 35 | 36 | .btn { 37 | background-image: none; 38 | border-radius: 4px; 39 | border: 1px solid transparent; 40 | cursor: pointer; 41 | display: inline-block; 42 | font-size: 14px; 43 | font-weight: normal; 44 | line-height: 1.42857143; 45 | margin-bottom: 0; 46 | padding: 6px 12px; 47 | text-align: center; 48 | touch-action: manipulation; 49 | user-select: none; 50 | vertical-align: middle; 51 | white-space: nowrap; 52 | 53 | &:focus, 54 | &:active:focus, 55 | &.active:focus, 56 | &.focus, 57 | &:active.focus, 58 | &.active.focus { 59 | outline-offset: -2px; 60 | outline: 5px auto -webkit-focus-ring-color; 61 | outline: thin dotted; 62 | } 63 | 64 | &:hover, 65 | &:focus, 66 | &.focus { 67 | color: $color-mine-shaft; 68 | text-decoration: none; 69 | } 70 | 71 | &:active, 72 | &.active { 73 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 74 | background-image: none; 75 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 76 | outline: 0; 77 | } 78 | 79 | &.disabled, 80 | &[disabled] { 81 | box-shadow: none; 82 | cursor: not-allowed; 83 | filter: alpha(opacity = 65); 84 | opacity: 0.65; 85 | } 86 | } 87 | 88 | fieldset[disabled] .btn { 89 | cursor: not-allowed; 90 | opacity: 0.65; 91 | filter: alpha(opacity = 65); 92 | -webkit-box-shadow: none; 93 | box-shadow: none; 94 | } 95 | 96 | a.btn.disabled, 97 | fieldset[disabled] a.btn { 98 | pointer-events: none; 99 | } 100 | 101 | .btn-default { 102 | color: $color-mine-shaft; 103 | background-color: $color-white; 104 | border-color: $color-mercury; 105 | 106 | &:focus, 107 | &.focus { 108 | color: $color-mine-shaft; 109 | background-color: $color-mercury; 110 | border-color: $color-stack; 111 | } 112 | &:hover, 113 | &:active, 114 | &.active { 115 | color: $color-mine-shaft; 116 | background-color: $color-mercury; 117 | border-color: $color-silver-chalice; 118 | } 119 | } // .btn-default 120 | 121 | .open > .dropdown-toggle.btn-default { 122 | color: $color-mine-shaft; 123 | background-color: $color-mercury; 124 | border-color: $color-silver-chalice; 125 | } 126 | 127 | .btn-default { 128 | 129 | &:active:hover, 130 | &.active:hover { 131 | color: $color-mine-shaft; 132 | background-color: $color-mercury; 133 | border-color: $color-stack; 134 | } 135 | } 136 | 137 | .open > .dropdown-toggle.btn-default:hover { 138 | color: $color-mine-shaft; 139 | background-color: $color-mercury; 140 | border-color: $color-stack; 141 | } 142 | 143 | .btn-default { 144 | 145 | &:active:focus, 146 | &.active:focus { 147 | color: $color-mine-shaft; 148 | background-color: $color-mercury; 149 | border-color: $color-stack; 150 | } 151 | } 152 | 153 | .open > .dropdown-toggle.btn-default:focus { 154 | color: $color-mine-shaft; 155 | background-color: $color-mercury; 156 | border-color: $color-stack; 157 | } 158 | 159 | .btn-default { 160 | 161 | &:active.focus, 162 | &.active.focus { 163 | color: $color-mine-shaft; 164 | background-color: $color-mercury; 165 | border-color: $color-stack; 166 | } 167 | } 168 | 169 | .open > .dropdown-toggle.btn-default.focus { 170 | color: $color-mine-shaft; 171 | background-color: $color-mercury; 172 | border-color: $color-stack; 173 | } 174 | 175 | .btn-default { 176 | 177 | &:active, 178 | &.active { 179 | background-image: none; 180 | } 181 | } 182 | 183 | .open > .dropdown-toggle.btn-default { 184 | background-image: none; 185 | } 186 | 187 | .btn-default { 188 | 189 | &.disabled, 190 | &[disabled] { 191 | background-color: $color-white; 192 | border-color: $color-mercury; 193 | } 194 | } 195 | 196 | fieldset[disabled] .btn-default { 197 | background-color: $color-white; 198 | border-color: $color-mercury; 199 | } 200 | 201 | .btn-default { 202 | 203 | &.disabled:hover, 204 | &[disabled]:hover { 205 | background-color: $color-white; 206 | border-color: $color-mercury; 207 | } 208 | } 209 | 210 | fieldset[disabled] .btn-default:hover { 211 | background-color: $color-white; 212 | border-color: $color-mercury; 213 | } 214 | 215 | .btn-default { 216 | &.disabled:focus, 217 | &[disabled]:focus { 218 | background-color: $color-white; 219 | border-color: $color-mercury; 220 | } 221 | } 222 | 223 | fieldset[disabled] .btn-default:focus { 224 | background-color: $color-white; 225 | border-color: $color-mercury; 226 | } 227 | 228 | .btn-default { 229 | &.disabled.focus, 230 | &[disabled].focus { 231 | background-color: $color-white; 232 | border-color: $color-mercury; 233 | } 234 | } 235 | 236 | fieldset[disabled] .btn-default.focus { 237 | background-color: $color-white; 238 | border-color: $color-mercury; 239 | } 240 | 241 | .btn-default { 242 | &.disabled:active, 243 | &[disabled]:active { 244 | background-color: $color-white; 245 | border-color: $color-mercury; 246 | } 247 | } 248 | 249 | fieldset[disabled] .btn-default:active { 250 | background-color: $color-white; 251 | border-color: $color-mercury; 252 | } 253 | 254 | .btn-default { 255 | &.disabled.active, 256 | &[disabled].active { 257 | background-color: $color-white; 258 | border-color: $color-mercury; 259 | } 260 | } 261 | 262 | fieldset[disabled] .btn-default.active { 263 | background-color: $color-white; 264 | border-color: $color-mercury; 265 | } 266 | 267 | .btn-default .badge { 268 | color: $color-white; 269 | background-color: $color-mine-shaft; 270 | } 271 | 272 | .btn-primary { 273 | color: $color-white; 274 | background-color: $color-curious-blue; 275 | border-color: $color-curious-blue; 276 | 277 | &:focus, 278 | &.focus { 279 | color: $color-white; 280 | background-color: $color-endeavor; 281 | border-color: $color-big-stone; 282 | } 283 | 284 | &:hover, 285 | &:active, 286 | &.active { 287 | color: $color-white; 288 | background-color: $color-endeavor; 289 | border-color: $color-midnight; 290 | } 291 | } 292 | 293 | .open > .dropdown-toggle.btn-primary { 294 | color: $color-white; 295 | background-color: $color-endeavor; 296 | border-color: $color-midnight; 297 | } 298 | 299 | .btn-primary { 300 | 301 | &:active:hover, 302 | &.active:hover { 303 | color: $color-white; 304 | background-color: $color-midnight; 305 | border-color: $color-big-stone; 306 | } 307 | } 308 | 309 | .open > .dropdown-toggle.btn-primary:hover { 310 | color: $color-white; 311 | background-color: $color-midnight; 312 | border-color: $color-big-stone; 313 | } 314 | 315 | .btn-primary { 316 | 317 | &:active:focus, 318 | &.active:focus { 319 | color: $color-white; 320 | background-color: $color-midnight; 321 | border-color: $color-big-stone; 322 | } 323 | } 324 | 325 | .open > .dropdown-toggle.btn-primary:focus { 326 | color: $color-white; 327 | background-color: $color-midnight; 328 | border-color: $color-big-stone; 329 | } 330 | 331 | .btn-primary { 332 | 333 | &:active.focus, 334 | &.active.focus { 335 | color: $color-white; 336 | background-color: $color-midnight; 337 | border-color: $color-big-stone; 338 | } 339 | } 340 | 341 | .open > .dropdown-toggle.btn-primary.focus { 342 | color: $color-white; 343 | background-color: $color-midnight; 344 | border-color: $color-big-stone; 345 | } 346 | 347 | .btn-primary { 348 | &:active, 349 | &.active { 350 | background-image: none; 351 | } 352 | } 353 | 354 | .open > .dropdown-toggle.btn-primary { 355 | background-image: none; 356 | } 357 | 358 | .btn-primary { 359 | 360 | &.disabled, 361 | &[disabled] { 362 | background-color: $color-curious-blue; 363 | border-color: $color-curious-blue; 364 | } 365 | } 366 | 367 | fieldset[disabled] .btn-primary { 368 | background-color: $color-curious-blue; 369 | border-color: $color-curious-blue; 370 | } 371 | 372 | .btn-primary { 373 | 374 | &.disabled:hover, 375 | &[disabled]:hover { 376 | background-color: $color-curious-blue; 377 | border-color: $color-curious-blue; 378 | } 379 | } 380 | 381 | fieldset[disabled] .btn-primary:hover { 382 | background-color: $color-curious-blue; 383 | border-color: $color-curious-blue; 384 | } 385 | 386 | .btn-primary { 387 | &.disabled:focus, 388 | &[disabled]:focus { 389 | background-color: $color-curious-blue; 390 | border-color: $color-curious-blue; 391 | } 392 | } 393 | 394 | fieldset[disabled] .btn-primary:focus { 395 | background-color: $color-curious-blue; 396 | border-color: $color-curious-blue; 397 | } 398 | 399 | .btn-primary { 400 | &.disabled.focus, 401 | &[disabled].focus { 402 | background-color: $color-curious-blue; 403 | border-color: $color-curious-blue; 404 | } 405 | } 406 | 407 | fieldset[disabled] .btn-primary.focus { 408 | background-color: $color-curious-blue; 409 | border-color: $color-curious-blue; 410 | } 411 | 412 | .btn-primary { 413 | &.disabled:active, 414 | &[disabled]:active { 415 | background-color: $color-curious-blue; 416 | border-color: $color-curious-blue; 417 | } 418 | } 419 | 420 | fieldset[disabled] .btn-primary:active { 421 | background-color: $color-curious-blue; 422 | border-color: $color-curious-blue; 423 | } 424 | 425 | .btn-primary { 426 | &.disabled.active, 427 | &[disabled].active { 428 | background-color: $color-curious-blue; 429 | border-color: $color-curious-blue; 430 | } 431 | } 432 | 433 | fieldset[disabled] .btn-primary.active { 434 | background-color: $color-curious-blue; 435 | border-color: $color-curious-blue; 436 | } 437 | 438 | .btn-primary .badge { 439 | color: $color-curious-blue; 440 | background-color: $color-white; 441 | } 442 | 443 | .btn-success { 444 | color: $color-white; 445 | background-color: $color-fern; 446 | border-color: $color-fern; 447 | 448 | &:focus, 449 | &.focus { 450 | color: $color-white; 451 | background-color: $color-fruit-salad; 452 | border-color: $color-fruit-salad; 453 | } 454 | 455 | &:hover, 456 | &:active, 457 | &.active { 458 | color: $color-white; 459 | background-color: $color-fruit-salad; 460 | border-color: $color-fruit-salad; 461 | } 462 | } 463 | 464 | .open > .dropdown-toggle.btn-success { 465 | color: $color-white; 466 | background-color: $color-fruit-salad; 467 | border-color: $color-fruit-salad; 468 | } 469 | 470 | .btn-success { 471 | 472 | &:active:hover, 473 | &.active:hover { 474 | color: $color-white; 475 | background-color: $color-fruit-salad; 476 | border-color: $color-fruit-salad; 477 | } 478 | } 479 | 480 | .open > .dropdown-toggle.btn-success:hover { 481 | color: $color-white; 482 | background-color: $color-fruit-salad; 483 | border-color: $color-fruit-salad; 484 | } 485 | 486 | .btn-success { 487 | 488 | &:active:focus, 489 | &.active:focus { 490 | color: $color-white; 491 | background-color: $color-fruit-salad; 492 | border-color: $color-fruit-salad; 493 | } 494 | } 495 | 496 | .open > .dropdown-toggle.btn-success:focus { 497 | color: $color-white; 498 | background-color: $color-fruit-salad; 499 | border-color: $color-fruit-salad; 500 | } 501 | 502 | .btn-success { 503 | &:active.focus, 504 | &.active.focus { 505 | color: $color-white; 506 | background-color: $color-fruit-salad; 507 | border-color: $color-fruit-salad; 508 | } 509 | } 510 | 511 | .open > .dropdown-toggle.btn-success.focus { 512 | color: $color-white; 513 | background-color: $color-fruit-salad; 514 | border-color: $color-fruit-salad; 515 | } 516 | 517 | .btn-success { 518 | &:active, 519 | &.active { 520 | background-image: none; 521 | } 522 | } 523 | 524 | .open > .dropdown-toggle.btn-success { 525 | background-image: none; 526 | } 527 | 528 | .btn-success { 529 | 530 | &.disabled, 531 | &[disabled] { 532 | background-color: $color-fern; 533 | border-color: $color-fern; 534 | } 535 | } 536 | 537 | fieldset[disabled] .btn-success { 538 | background-color: $color-fern; 539 | border-color: $color-fern; 540 | } 541 | 542 | .btn-success { 543 | 544 | &.disabled:hover, 545 | &[disabled]:hover { 546 | background-color: $color-fern; 547 | border-color: $color-fern; 548 | } 549 | } 550 | 551 | fieldset[disabled] .btn-success:hover { 552 | background-color: $color-fern; 553 | border-color: $color-fern; 554 | } 555 | 556 | .btn-success { 557 | &.disabled:focus, 558 | &[disabled]:focus { 559 | background-color: $color-fern; 560 | border-color: $color-fern; 561 | } 562 | } 563 | 564 | fieldset[disabled] .btn-success:focus { 565 | background-color: $color-fern; 566 | border-color: $color-fern; 567 | } 568 | 569 | .btn-success { 570 | 571 | &.disabled.focus, 572 | &[disabled].focus { 573 | background-color: $color-fern; 574 | border-color: $color-fern; 575 | } 576 | } 577 | 578 | fieldset[disabled] .btn-success.focus { 579 | background-color: $color-fern; 580 | border-color: $color-fern; 581 | } 582 | 583 | .btn-success { 584 | 585 | &.disabled:active, 586 | &[disabled]:active { 587 | background-color: $color-fern; 588 | border-color: $color-fern; 589 | } 590 | } 591 | 592 | fieldset[disabled] .btn-success:active { 593 | background-color: $color-fern; 594 | border-color: $color-fern; 595 | } 596 | 597 | .btn-success { 598 | 599 | &.disabled.active, 600 | &[disabled].active { 601 | background-color: $color-fern; 602 | border-color: $color-fern; 603 | } 604 | } 605 | 606 | fieldset[disabled] .btn-success.active { 607 | background-color: $color-fern; 608 | border-color: $color-fern; 609 | } 610 | 611 | .btn-success .badge { 612 | color: $color-fern; 613 | background-color: $color-white; 614 | } 615 | 616 | .btn-info { 617 | color: $color-white; 618 | background-color: $color-malibu; 619 | border-color: $color-malibu; 620 | 621 | &:focus, 622 | &.focus { 623 | color: $color-white; 624 | background-color: $color-summer-sky; 625 | border-color: $color-summer-sky; 626 | } 627 | 628 | &:hover, 629 | &:active, 630 | &.active { 631 | color: $color-white; 632 | background-color: $color-summer-sky; 633 | border-color: $color-summer-sky; 634 | } 635 | } 636 | 637 | .open > .dropdown-toggle.btn-info { 638 | color: $color-white; 639 | background-color: $color-summer-sky; 640 | border-color: $color-summer-sky; 641 | } 642 | 643 | .btn-info { 644 | 645 | &:active:hover, 646 | &.active:hover { 647 | color: $color-white; 648 | background-color: $color-summer-sky; 649 | border-color: $color-summer-sky; 650 | } 651 | } 652 | 653 | .open > .dropdown-toggle.btn-info:hover { 654 | color: $color-white; 655 | background-color: $color-summer-sky; 656 | border-color: $color-summer-sky; 657 | } 658 | 659 | .btn-info { 660 | 661 | &:active:focus, 662 | &.active:focus { 663 | color: $color-white; 664 | background-color: $color-summer-sky; 665 | border-color: $color-summer-sky; 666 | } 667 | } 668 | 669 | .open > .dropdown-toggle.btn-info:focus { 670 | color: $color-white; 671 | background-color: $color-summer-sky; 672 | border-color: $color-summer-sky; 673 | } 674 | 675 | .btn-info { 676 | 677 | &:active.focus, 678 | &.active.focus { 679 | color: $color-white; 680 | background-color: $color-summer-sky; 681 | border-color: $color-summer-sky; 682 | } 683 | } 684 | 685 | .open > .dropdown-toggle.btn-info.focus { 686 | color: $color-white; 687 | background-color: $color-summer-sky; 688 | border-color: $color-summer-sky; 689 | } 690 | 691 | .btn-info { 692 | 693 | &:active, 694 | &.active { 695 | background-image: none; 696 | } 697 | } 698 | 699 | .open > .dropdown-toggle.btn-info { 700 | background-image: none; 701 | } 702 | 703 | .btn-info { 704 | 705 | &.disabled, 706 | &[disabled] { 707 | background-color: $color-malibu; 708 | border-color: $color-malibu; 709 | } 710 | } 711 | 712 | fieldset[disabled] .btn-info { 713 | background-color: $color-malibu; 714 | border-color: $color-malibu; 715 | } 716 | 717 | .btn-info { 718 | 719 | &.disabled:hover, 720 | &[disabled]:hover { 721 | background-color: $color-malibu; 722 | border-color: $color-malibu; 723 | } 724 | } 725 | 726 | fieldset[disabled] .btn-info:hover { 727 | background-color: $color-malibu; 728 | border-color: $color-malibu; 729 | } 730 | 731 | .btn-info { 732 | 733 | &.disabled:focus, 734 | &[disabled]:focus { 735 | background-color: $color-malibu; 736 | border-color: $color-malibu; 737 | } 738 | } 739 | 740 | fieldset[disabled] .btn-info:focus { 741 | background-color: $color-malibu; 742 | border-color: $color-malibu; 743 | } 744 | 745 | .btn-info { 746 | 747 | &.disabled.focus, 748 | &[disabled].focus { 749 | background-color: $color-malibu; 750 | border-color: $color-malibu; 751 | } 752 | } 753 | 754 | fieldset[disabled] .btn-info.focus { 755 | background-color: $color-malibu; 756 | border-color: $color-malibu; 757 | } 758 | 759 | .btn-info { 760 | 761 | &.disabled:active, 762 | &[disabled]:active { 763 | background-color: $color-malibu; 764 | border-color: $color-malibu; 765 | } 766 | } 767 | 768 | fieldset[disabled] .btn-info:active { 769 | background-color: $color-malibu; 770 | border-color: $color-malibu; 771 | } 772 | 773 | .btn-info { 774 | 775 | &.disabled.active, 776 | &[disabled].active { 777 | background-color: $color-malibu; 778 | border-color: $color-malibu; 779 | } 780 | } 781 | 782 | fieldset[disabled] .btn-info.active { 783 | background-color: $color-malibu; 784 | border-color: $color-malibu; 785 | } 786 | 787 | .btn-info .badge { 788 | color: $color-malibu; 789 | background-color: $color-white; 790 | } 791 | 792 | .btn-warning { 793 | color: $color-white; 794 | background-color: $color-casablanca; 795 | border-color: $color-casablanca; 796 | 797 | &:focus, 798 | &.focus { 799 | color: $color-white; 800 | background-color: $color-carrot; 801 | border-color: $color-carrot; 802 | } 803 | 804 | &:hover, 805 | &:active, 806 | &.active { 807 | color: $color-white; 808 | background-color: $color-carrot; 809 | border-color: $color-carrot; 810 | } 811 | } 812 | 813 | .open > .dropdown-toggle.btn-warning { 814 | color: $color-white; 815 | background-color: $color-carrot; 816 | border-color: $color-carrot; 817 | } 818 | 819 | .btn-warning { 820 | 821 | &:active:hover, 822 | &.active:hover { 823 | color: $color-white; 824 | background-color: $color-carrot; 825 | border-color: $color-carrot; 826 | } 827 | } 828 | 829 | .open > .dropdown-toggle.btn-warning:hover { 830 | color: $color-white; 831 | background-color: $color-carrot; 832 | border-color: $color-carrot; 833 | } 834 | 835 | .btn-warning { 836 | 837 | &:active:focus, 838 | &.active:focus { 839 | color: $color-white; 840 | background-color: $color-carrot; 841 | border-color: $color-carrot; 842 | } 843 | } 844 | 845 | .open > .dropdown-toggle.btn-warning:focus { 846 | color: $color-white; 847 | background-color: $color-carrot; 848 | border-color: $color-carrot; 849 | } 850 | 851 | .btn-warning { 852 | 853 | &:active.focus, 854 | &.active.focus { 855 | color: $color-white; 856 | background-color: $color-carrot; 857 | border-color: $color-carrot; 858 | } 859 | } 860 | 861 | .open > .dropdown-toggle.btn-warning.focus { 862 | color: $color-white; 863 | background-color: $color-carrot; 864 | border-color: $color-carrot; 865 | } 866 | 867 | .btn-warning { 868 | 869 | &:active, 870 | &.active { 871 | background-image: none; 872 | } 873 | } 874 | 875 | .open > .dropdown-toggle.btn-warning { 876 | background-image: none; 877 | } 878 | 879 | .btn-warning { 880 | 881 | &.disabled, 882 | &[disabled] { 883 | background-color: $color-casablanca; 884 | border-color: $color-casablanca; 885 | } 886 | } 887 | 888 | fieldset[disabled] .btn-warning { 889 | background-color: $color-casablanca; 890 | border-color: $color-casablanca; 891 | } 892 | 893 | .btn-warning { 894 | &.disabled:hover, 895 | &[disabled]:hover { 896 | background-color: $color-casablanca; 897 | border-color: $color-casablanca; 898 | } 899 | } 900 | 901 | fieldset[disabled] .btn-warning:hover { 902 | background-color: $color-casablanca; 903 | border-color: $color-casablanca; 904 | } 905 | 906 | .btn-warning { 907 | 908 | &.disabled:focus, 909 | &[disabled]:focus { 910 | background-color: $color-casablanca; 911 | border-color: $color-casablanca; 912 | } 913 | } 914 | 915 | fieldset[disabled] .btn-warning:focus { 916 | background-color: $color-casablanca; 917 | border-color: $color-casablanca; 918 | } 919 | 920 | .btn-warning { 921 | 922 | &.disabled.focus, 923 | &[disabled].focus { 924 | background-color: $color-casablanca; 925 | border-color: $color-casablanca; 926 | } 927 | } 928 | 929 | fieldset[disabled] .btn-warning.focus { 930 | background-color: $color-casablanca; 931 | border-color: $color-casablanca; 932 | } 933 | 934 | .btn-warning { 935 | &.disabled:active, 936 | &[disabled]:active { 937 | background-color: $color-casablanca; 938 | border-color: $color-casablanca; 939 | } 940 | } 941 | 942 | fieldset[disabled] .btn-warning:active { 943 | background-color: $color-casablanca; 944 | border-color: $color-casablanca; 945 | } 946 | 947 | .btn-warning { 948 | 949 | &.disabled.active, 950 | &[disabled].active { 951 | background-color: $color-casablanca; 952 | border-color: $color-casablanca; 953 | } 954 | } 955 | 956 | fieldset[disabled] .btn-warning.active { 957 | background-color: $color-casablanca; 958 | border-color: $color-casablanca; 959 | } 960 | 961 | .btn-warning .badge { 962 | color: $color-casablanca; 963 | background-color: $color-white; 964 | } 965 | 966 | .btn-danger { 967 | color: $color-white; 968 | background-color: $color-valencia; 969 | border-color: $color-valencia; 970 | 971 | &:focus, 972 | &.focus { 973 | color: $color-white; 974 | background-color: $color-persian-red; 975 | border-color: $color-persian-red; 976 | } 977 | 978 | &:hover, 979 | &:active, 980 | &.active { 981 | color: $color-white; 982 | background-color: $color-persian-red; 983 | border-color: $color-persian-red; 984 | } 985 | } 986 | 987 | .open > .dropdown-toggle.btn-danger { 988 | color: $color-white; 989 | background-color: $color-persian-red; 990 | border-color: $color-persian-red; 991 | } 992 | 993 | .btn-danger { 994 | 995 | &:active:hover, 996 | &.active:hover { 997 | color: $color-white; 998 | background-color: $color-persian-red; 999 | border-color: $color-persian-red; 1000 | } 1001 | } 1002 | 1003 | .open > .dropdown-toggle.btn-danger:hover { 1004 | color: $color-white; 1005 | background-color: $color-persian-red; 1006 | border-color: $color-persian-red; 1007 | } 1008 | 1009 | .btn-danger { 1010 | 1011 | &:active:focus, 1012 | &.active:focus { 1013 | color: $color-white; 1014 | background-color: $color-persian-red; 1015 | border-color: $color-persian-red; 1016 | } 1017 | } 1018 | 1019 | .open > .dropdown-toggle.btn-danger:focus { 1020 | color: $color-white; 1021 | background-color: $color-persian-red; 1022 | border-color: $color-persian-red; 1023 | } 1024 | 1025 | .btn-danger { 1026 | 1027 | &:active.focus, 1028 | &.active.focus { 1029 | color: $color-white; 1030 | background-color: $color-persian-red; 1031 | border-color: $color-persian-red; 1032 | } 1033 | } 1034 | 1035 | .open > .dropdown-toggle.btn-danger.focus { 1036 | color: $color-white; 1037 | background-color: $color-persian-red; 1038 | border-color: $color-persian-red; 1039 | } 1040 | 1041 | .btn-danger { 1042 | 1043 | &:active, 1044 | &.active { 1045 | background-image: none; 1046 | } 1047 | } 1048 | 1049 | .open > .dropdown-toggle.btn-danger { 1050 | background-image: none; 1051 | } 1052 | 1053 | .btn-danger { 1054 | 1055 | &.disabled, 1056 | &[disabled] { 1057 | background-color: $color-valencia; 1058 | border-color: $color-valencia; 1059 | } 1060 | } 1061 | 1062 | fieldset[disabled] .btn-danger { 1063 | background-color: $color-valencia; 1064 | border-color: $color-valencia; 1065 | } 1066 | 1067 | .btn-danger { 1068 | 1069 | &.disabled:hover, 1070 | &[disabled]:hover { 1071 | background-color: $color-valencia; 1072 | border-color: $color-valencia; 1073 | } 1074 | } 1075 | 1076 | fieldset[disabled] .btn-danger:hover { 1077 | background-color: $color-valencia; 1078 | border-color: $color-valencia; 1079 | } 1080 | 1081 | .btn-danger { 1082 | 1083 | &.disabled:focus, 1084 | &[disabled]:focus { 1085 | background-color: $color-valencia; 1086 | border-color: $color-valencia; 1087 | } 1088 | } 1089 | 1090 | fieldset[disabled] .btn-danger:focus { 1091 | background-color: $color-valencia; 1092 | border-color: $color-valencia; 1093 | } 1094 | 1095 | .btn-danger { 1096 | 1097 | &.disabled.focus, 1098 | &[disabled].focus { 1099 | background-color: $color-valencia; 1100 | border-color: $color-valencia; 1101 | } 1102 | } 1103 | 1104 | fieldset[disabled] .btn-danger.focus { 1105 | background-color: $color-valencia; 1106 | border-color: $color-valencia; 1107 | } 1108 | 1109 | .btn-danger { 1110 | 1111 | &.disabled:active, 1112 | &[disabled]:active { 1113 | background-color: $color-valencia; 1114 | border-color: $color-valencia; 1115 | } 1116 | } 1117 | 1118 | fieldset[disabled] .btn-danger:active { 1119 | background-color: $color-valencia; 1120 | border-color: $color-valencia; 1121 | } 1122 | 1123 | .btn-danger { 1124 | 1125 | &.disabled.active, 1126 | &[disabled].active { 1127 | background-color: $color-valencia; 1128 | border-color: $color-valencia; 1129 | } 1130 | } 1131 | 1132 | fieldset[disabled] .btn-danger.active { 1133 | background-color: $color-valencia; 1134 | border-color: $color-valencia; 1135 | } 1136 | 1137 | .btn-danger .badge { 1138 | color: $color-valencia; 1139 | background-color: $color-white; 1140 | } 1141 | 1142 | .btn-link { 1143 | color: $color-curious-blue; 1144 | font-weight: normal; 1145 | border-radius: 0; 1146 | background-color: transparent; 1147 | -webkit-box-shadow: none; 1148 | box-shadow: none; 1149 | 1150 | &:active, 1151 | &.active, 1152 | &[disabled] { 1153 | background-color: transparent; 1154 | -webkit-box-shadow: none; 1155 | box-shadow: none; 1156 | } 1157 | } 1158 | 1159 | fieldset[disabled] .btn-link { 1160 | background-color: transparent; 1161 | -webkit-box-shadow: none; 1162 | box-shadow: none; 1163 | } 1164 | 1165 | .btn-link { 1166 | border-color: transparent; 1167 | 1168 | &:hover, 1169 | &:focus, 1170 | &:active { 1171 | border-color: transparent; 1172 | } 1173 | 1174 | &:hover, 1175 | &:focus { 1176 | color: $color-endeavor; 1177 | text-decoration: underline; 1178 | background-color: transparent; 1179 | } 1180 | 1181 | &[disabled]:hover { 1182 | color: $color-monsoon; 1183 | text-decoration: none; 1184 | } 1185 | } 1186 | 1187 | fieldset[disabled] .btn-link:hover, 1188 | .btn-link[disabled]:focus, 1189 | fieldset[disabled] .btn-link:focus { 1190 | color: $color-monsoon; 1191 | text-decoration: none; 1192 | } 1193 | 1194 | .btn-lg, 1195 | .btn-group-lg > .btn { 1196 | padding: 10px 16px; 1197 | font-size: 18px; 1198 | line-height: 1.3333333; 1199 | border-radius: 6px; 1200 | } 1201 | 1202 | .btn-sm, 1203 | .btn-group-sm > .btn { 1204 | padding: 5px 10px; 1205 | font-size: 12px; 1206 | line-height: 1.5; 1207 | border-radius: 3px; 1208 | } 1209 | 1210 | .btn-xs, 1211 | .btn-group-xs > .btn { 1212 | padding: 1px 5px; 1213 | font-size: 12px; 1214 | line-height: 1.5; 1215 | border-radius: 3px; 1216 | } 1217 | 1218 | .btn-block { 1219 | display: block; 1220 | width: 100%; 1221 | + .btn-block { 1222 | margin-top: 5px; 1223 | } 1224 | } 1225 | 1226 | input { 1227 | 1228 | &[type="submit"].btn-block, 1229 | &[type="reset"].btn-block, 1230 | &[type="button"].btn-block { 1231 | width: 100%; 1232 | } 1233 | } -------------------------------------------------------------------------------- /assets/scss/_custom.scss: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Custom Styles 3 | //-------------------------------------------------------------- 4 | .btn-group { 5 | 6 | ul.dropdown-menu { 7 | max-height: 250px; 8 | overflow: scroll; 9 | } // ul.drpdown-menu 10 | 11 | svg.icon { 12 | height: 14px; 13 | position: absolute; 14 | top: 6px; 15 | left: 3px; 16 | max-width: 15px; 17 | } // svg.icon 18 | 19 | li:hover { 20 | background-color: $color-mercury; 21 | } // li:hover 22 | } // .btn-group 23 | 24 | .btn-default { 25 | 26 | svg.icon { 27 | height: 14px; 28 | margin-right: 5px; 29 | position: relative; 30 | top: 2px; 31 | width: 14px; 32 | } // svg.icon 33 | } // .btn-default -------------------------------------------------------------------------------- /assets/scss/_dropdown.scss: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Dropdown 3 | //-------------------------------------------------------------- 4 | .caret { 5 | display: inline-block; 6 | width: 0; 7 | height: 0; 8 | margin-left: 15px; 9 | vertical-align: middle; 10 | border-top: 4px dashed; 11 | border-top: 4px solid \9; 12 | border-right: 4px solid transparent; 13 | border-left: 4px solid transparent; 14 | } 15 | 16 | //----------------------------------------- 17 | // Container 18 | //----------------------------------------- 19 | .dropup, .dropdown { 20 | position: relative; 21 | } 22 | 23 | .dropdown-toggle:focus { 24 | outline: 0; 25 | } 26 | 27 | .dropdown-menu { 28 | -webkit-background-clip: padding-box; 29 | -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); 30 | background-clip: padding-box; 31 | background-color: $color-white; 32 | border-radius: 4px; 33 | border: 1px solid $color-mercury; 34 | border: 1px solid rgba(0, 0, 0, 0.15); 35 | box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); 36 | display: none; 37 | float: left; 38 | font-size: 14px; 39 | left: 0; 40 | list-style: none; 41 | margin: 2px 0 0; 42 | min-width: 160px; 43 | padding: 5px 0; 44 | position: absolute; 45 | text-align: left; 46 | top: 57px; 47 | z-index: 1000; 48 | 49 | &.pull-right { 50 | right: 0; 51 | left: auto; 52 | } 53 | 54 | .divider { 55 | height: 1px; 56 | margin: 9px 0; 57 | overflow: hidden; 58 | background-color: $color-mercury; 59 | } 60 | 61 | > { 62 | 63 | li > a { 64 | display: block; 65 | padding: 3px 20px; 66 | clear: both; 67 | font-weight: normal; 68 | line-height: 1.42857143; 69 | color: $color-mine-shaft; 70 | white-space: nowrap; 71 | 72 | &:hover, 73 | &:focus { 74 | text-decoration: none; 75 | color: $color-nero; 76 | background-color: $color-mercury; 77 | } 78 | } 79 | 80 | .active > a { 81 | color: $color-white; 82 | text-decoration: none; 83 | outline: 0; 84 | background-color: $color-curious-blue; 85 | 86 | &:hover, &:focus { 87 | color: $color-white; 88 | text-decoration: none; 89 | outline: 0; 90 | background-color: $color-curious-blue; 91 | } 92 | } 93 | 94 | .disabled > a { 95 | color: $color-monsoon; 96 | 97 | &:hover, 98 | &:focus { 99 | color: $color-monsoon; 100 | } 101 | 102 | &:hover, 103 | &:focus { 104 | text-decoration: none; 105 | background-color: transparent; 106 | background-image: none; 107 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 108 | cursor: not-allowed; 109 | } 110 | } 111 | } 112 | } 113 | 114 | .open > { 115 | 116 | .dropdown-menu { 117 | display: block; 118 | } 119 | 120 | a { 121 | outline: 0; 122 | } 123 | } 124 | 125 | .dropdown-menu-right { 126 | left: auto; 127 | right: 0; 128 | } 129 | 130 | .dropdown-menu-left { 131 | left: 0; 132 | right: auto; 133 | } 134 | 135 | .dropdown-header { 136 | display: block; 137 | padding: 3px 20px; 138 | font-size: 12px; 139 | line-height: 1.42857143; 140 | color: $color-monsoon; 141 | white-space: nowrap; 142 | } 143 | 144 | .dropdown-backdrop { 145 | position: fixed; 146 | left: 0; 147 | right: 0; 148 | bottom: 0; 149 | top: 0; 150 | z-index: 990; 151 | } 152 | 153 | .pull-right > .dropdown-menu { 154 | right: 0; 155 | left: auto; 156 | } 157 | 158 | .dropup .caret, 159 | .navbar-fixed-bottom .dropdown .caret { 160 | border-top: 0; 161 | border-bottom: 4px dashed; 162 | border-bottom: 4px solid \9; 163 | content: ""; 164 | } 165 | 166 | .dropup .dropdown-menu, 167 | .navbar-fixed-bottom .dropdown .dropdown-menu { 168 | top: auto; 169 | bottom: 100%; 170 | margin-bottom: 2px; 171 | } 172 | 173 | @media (min-width: 768px) { 174 | .navbar-right { 175 | 176 | .dropdown-menu { 177 | left: auto; 178 | right: 0; 179 | } 180 | 181 | .dropdown-menu-left { 182 | left: 0; 183 | right: auto; 184 | } 185 | } 186 | } 187 | 188 | .btn-group, 189 | .btn-group-vertical { 190 | position: relative; 191 | display: inline-block; 192 | vertical-align: middle; 193 | } 194 | 195 | .btn-group > .btn, 196 | .btn-group-vertical > .btn { 197 | position: relative; 198 | float: left; 199 | } 200 | 201 | .btn-group > .btn:hover, 202 | .btn-group-vertical > .btn:hover, 203 | .btn-group > .btn:focus, 204 | .btn-group-vertical > .btn:focus, 205 | .btn-group > .btn:active, 206 | .btn-group-vertical > .btn:active, 207 | .btn-group > .btn.active, 208 | .btn-group-vertical > .btn.active { 209 | z-index: 2; 210 | } 211 | 212 | .btn-group { 213 | .btn + { 214 | 215 | .btn, .btn-group { 216 | margin-left: -1px; 217 | } 218 | } 219 | 220 | .btn-group + { 221 | 222 | .btn, .btn-group { 223 | margin-left: -1px; 224 | } 225 | } 226 | } 227 | 228 | .btn-toolbar { 229 | margin-left: -5px; 230 | 231 | .btn, .btn-group, .input-group { 232 | float: left; 233 | } 234 | 235 | > { 236 | 237 | .btn, .btn-group, .input-group { 238 | margin-left: 5px; 239 | } 240 | } 241 | } 242 | 243 | .btn-group { 244 | > { 245 | 246 | .btn { 247 | 248 | &:not(:first-child):not(:last-child):not(.dropdown-toggle) { 249 | border-radius: 0; 250 | } 251 | 252 | &:first-child { 253 | margin-left: 0; 254 | 255 | &:not(:last-child):not(.dropdown-toggle) { 256 | border-bottom-right-radius: 0; 257 | border-top-right-radius: 0; 258 | } 259 | } 260 | 261 | &:last-child:not(:first-child) { 262 | border-bottom-left-radius: 0; 263 | border-top-left-radius: 0; 264 | } 265 | } 266 | 267 | .dropdown-toggle:not(:first-child) { 268 | border-bottom-left-radius: 0; 269 | border-top-left-radius: 0; 270 | } 271 | 272 | .btn-group { 273 | float: left; 274 | 275 | &:not(:first-child):not(:last-child) > .btn { 276 | border-radius: 0; 277 | } 278 | 279 | &:first-child:not(:last-child) > { 280 | 281 | .btn:last-child, .dropdown-toggle { 282 | border-bottom-right-radius: 0; 283 | border-top-right-radius: 0; 284 | } 285 | } 286 | 287 | &:last-child:not(:first-child) > .btn:first-child { 288 | border-bottom-left-radius: 0; 289 | border-top-left-radius: 0; 290 | } 291 | } 292 | } 293 | 294 | .dropdown-toggle:active { 295 | outline: 0; 296 | } 297 | 298 | &.open .dropdown-toggle { 299 | outline: 0; 300 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 301 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 302 | 303 | &.btn-link { 304 | -webkit-box-shadow: none; 305 | box-shadow: none; 306 | } 307 | } 308 | 309 | > { 310 | 311 | .btn + .dropdown-toggle { 312 | padding-left: 8px; 313 | padding-right: 8px; 314 | } 315 | 316 | .btn-lg + .dropdown-toggle { 317 | padding-left: 12px; 318 | padding-right: 12px; 319 | } 320 | } 321 | } 322 | 323 | .btn .caret { 324 | margin-left: 0; 325 | } 326 | 327 | .btn-lg .caret { 328 | border-width: 5px 5px 0; 329 | border-bottom-width: 0; 330 | } 331 | 332 | .dropup .btn-lg .caret { 333 | border-width: 0 5px 5px; 334 | } 335 | 336 | .btn-group-vertical > { 337 | 338 | .btn { 339 | display: block; 340 | float: none; 341 | width: 100%; 342 | max-width: 100%; 343 | } 344 | 345 | .btn-group { 346 | display: block; 347 | float: none; 348 | width: 100%; 349 | max-width: 100%; 350 | 351 | > .btn { 352 | display: block; 353 | float: none; 354 | width: 100%; 355 | max-width: 100%; 356 | float: none; 357 | } 358 | } 359 | 360 | .btn + { 361 | 362 | .btn, 363 | .btn-group { 364 | margin-top: -1px; 365 | margin-left: 0; 366 | } 367 | } 368 | 369 | .btn-group + { 370 | 371 | .btn, 372 | .btn-group { 373 | margin-top: -1px; 374 | margin-left: 0; 375 | } 376 | } 377 | 378 | .btn { 379 | 380 | &:not(:first-child):not(:last-child) { 381 | border-radius: 0; 382 | } 383 | 384 | &:first-child:not(:last-child) { 385 | border-top-right-radius: 4px; 386 | border-bottom-right-radius: 0; 387 | border-bottom-left-radius: 0; 388 | } 389 | 390 | &:last-child:not(:first-child) { 391 | border-bottom-left-radius: 4px; 392 | border-top-right-radius: 0; 393 | border-top-left-radius: 0; 394 | } 395 | } 396 | 397 | .btn-group { 398 | 399 | &:not(:first-child):not(:last-child) > .btn { 400 | border-radius: 0; 401 | } 402 | 403 | &:first-child:not(:last-child) > { 404 | 405 | .btn:last-child, 406 | .dropdown-toggle { 407 | border-bottom-right-radius: 0; 408 | border-bottom-left-radius: 0; 409 | } 410 | } 411 | &:last-child:not(:first-child) > .btn:first-child { 412 | border-top-right-radius: 0; 413 | border-top-left-radius: 0; 414 | } 415 | } 416 | } 417 | 418 | .btn-group-justified { 419 | display: table; 420 | width: 100%; 421 | table-layout: fixed; 422 | border-collapse: separate; 423 | 424 | > { 425 | .btn { 426 | float: none; 427 | display: table-cell; 428 | width: 1%; 429 | } 430 | 431 | .btn-group { 432 | float: none; 433 | display: table-cell; 434 | width: 1%; 435 | 436 | .btn { 437 | width: 100%; 438 | } 439 | 440 | .dropdown-menu { 441 | left: auto; 442 | } 443 | } 444 | } 445 | } 446 | 447 | [data-toggle="buttons"] > { 448 | 449 | .btn input[type="radio"], 450 | .btn-group > .btn input[type="radio"], 451 | .btn input[type="checkbox"], 452 | .btn-group > .btn input[type="checkbox"] { 453 | position: absolute; 454 | clip: rect(0, 0, 0, 0); 455 | pointer-events: none; 456 | } 457 | } 458 | 459 | .clearfix { 460 | 461 | &:before, 462 | &:after { 463 | content: " "; 464 | display: table; 465 | } 466 | } 467 | 468 | .btn-toolbar { 469 | 470 | &:before, 471 | &:after { 472 | content: " "; 473 | display: table; 474 | } 475 | } 476 | 477 | .btn-group-vertical > .btn-group { 478 | 479 | &:before, 480 | &:after { 481 | content: " "; 482 | display: table; 483 | } 484 | } 485 | 486 | .clearfix:after, 487 | .btn-toolbar:after, 488 | .btn-group-vertical > .btn-group:after { 489 | clear: both; 490 | } 491 | 492 | .center-block { 493 | display: block; 494 | margin-left: auto; 495 | margin-right: auto; 496 | } 497 | 498 | .pull-right { 499 | float: right !important; 500 | } 501 | 502 | .pull-left { 503 | float: left !important; 504 | } 505 | 506 | .hide { 507 | display: none !important; 508 | } 509 | 510 | .show { 511 | display: block !important; 512 | } 513 | 514 | .invisible { 515 | visibility: hidden; 516 | } 517 | 518 | .text-hide { 519 | font: 0/0 a; 520 | color: transparent; 521 | text-shadow: none; 522 | background-color: transparent; 523 | border: 0; 524 | } 525 | 526 | .affix { 527 | position: fixed; 528 | } 529 | 530 | 531 | //----------------------------------------- 532 | // Enhancements 533 | //----------------------------------------- 534 | .dropdown-menu { 535 | > { 536 | 537 | li > { 538 | 539 | label { 540 | display: block; 541 | padding: 3px 20px; 542 | clear: both; 543 | font-weight: normal; 544 | line-height: 1.42857143; 545 | color: $color-mine-shaft; 546 | white-space: nowrap; 547 | 548 | &:hover, 549 | &:focus { 550 | text-decoration: none; 551 | color: $color-nero; 552 | background-color: $color-mercury; 553 | } 554 | } 555 | 556 | input:checked ~ label { 557 | color: $color-white; 558 | text-decoration: none; 559 | outline: 0; 560 | background-color: $color-celestial-blue; 561 | 562 | &:hover, 563 | &:focus { 564 | color: $color-white; 565 | text-decoration: none; 566 | outline: 0; 567 | background-color: $color-celestial-blue; 568 | } 569 | } 570 | } 571 | 572 | .active > label { 573 | color: $color-white; 574 | text-decoration: none; 575 | outline: 0; 576 | background-color: $color-celestial-blue; 577 | 578 | &:hover, 579 | &:focus { 580 | color: $color-white; 581 | text-decoration: none; 582 | outline: 0; 583 | background-color: $color-celestial-blue; 584 | } 585 | } 586 | 587 | li > input[disabled] ~ label { 588 | color: $color-alumminum; 589 | 590 | &:hover, 591 | &:focus { 592 | color: $color-alumminum; 593 | } 594 | } 595 | 596 | .disabled > label { 597 | color: $color-alumminum; 598 | 599 | &:hover, 600 | &:focus { 601 | color: $color-alumminum; 602 | } 603 | } 604 | 605 | li > input[disabled] ~ label { 606 | 607 | &:hover, 608 | &:focus { 609 | text-decoration: none; 610 | background-color: transparent; 611 | background-image: none; 612 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 613 | cursor: not-allowed; 614 | } 615 | } 616 | 617 | .disabled > label { 618 | 619 | &:hover, 620 | &:focus { 621 | text-decoration: none; 622 | background-color: transparent; 623 | background-image: none; 624 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 625 | cursor: not-allowed; 626 | } 627 | } 628 | li > { 629 | 630 | label { 631 | margin-bottom: 0; 632 | cursor: pointer; 633 | } 634 | 635 | input { 636 | 637 | &[type="radio"], 638 | &[type="checkbox"] { 639 | display: none; 640 | position: absolute; 641 | top: -9999em; 642 | left: -9999em; 643 | } 644 | } 645 | 646 | label:focus, 647 | input:focus ~ label { 648 | outline: thin dotted; 649 | outline: 5px auto -webkit-focus-ring-color; 650 | outline-offset: -2px; 651 | } 652 | } 653 | } 654 | 655 | &.pull-right { 656 | right: 0; 657 | left: auto; 658 | } 659 | 660 | &.pull-top { 661 | bottom: 100%; 662 | top: auto; 663 | margin: 0 0 2px; 664 | -webkit-box-shadow: 0 -6px 12px rgba(0, 0, 0, 0.175); 665 | box-shadow: 0 -6px 12px rgba(0, 0, 0, 0.175); 666 | } 667 | 668 | &.pull-center { 669 | right: 50%; 670 | left: auto; 671 | } 672 | 673 | &.pull-middle { 674 | right: 100%; 675 | margin: 0 2px 0 0; 676 | box-shadow: -5px 0 10px rgba(0, 0, 0, 0.2); 677 | left: auto; 678 | 679 | &.pull-right { 680 | right: auto; 681 | left: 100%; 682 | margin: 0 0 0 2px; 683 | box-shadow: 5px 0 10px rgba(0, 0, 0, 0.2); 684 | } 685 | 686 | &.pull-center { 687 | right: 50%; 688 | margin: 0; 689 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 690 | } 691 | } 692 | 693 | &.bullet { 694 | margin-top: 8px; 695 | 696 | &:before { 697 | width: 0; 698 | height: 0; 699 | content: ''; 700 | display: inline-block; 701 | position: absolute; 702 | border-color: transparent; 703 | border-style: solid; 704 | -webkit-transform: rotate(360deg); 705 | border-width: 0 7px 7px; 706 | border-bottom-color: $color-mercury; 707 | border-bottom-color: rgba(0, 0, 0, 0.15); 708 | top: -7px; 709 | left: 9px; 710 | } 711 | 712 | &:after { 713 | width: 0; 714 | height: 0; 715 | content: ''; 716 | display: inline-block; 717 | position: absolute; 718 | border-color: transparent; 719 | border-style: solid; 720 | -webkit-transform: rotate(360deg); 721 | border-width: 0 6px 6px; 722 | border-bottom-color: $color-white; 723 | top: -6px; 724 | left: 10px; 725 | } 726 | 727 | &.pull-right { 728 | 729 | &:before { 730 | left: auto; 731 | right: 9px; 732 | } 733 | 734 | &:after { 735 | left: auto; 736 | right: 10px; 737 | } 738 | } 739 | 740 | &.pull-top { 741 | margin-top: 0; 742 | margin-bottom: 8px; 743 | 744 | &:before { 745 | top: auto; 746 | bottom: -7px; 747 | border-bottom-width: 0; 748 | border-top-width: 7px; 749 | border-top-color: $color-mercury; 750 | border-top-color: rgba(0, 0, 0, 0.15); 751 | } 752 | 753 | &:after { 754 | top: auto; 755 | bottom: -6px; 756 | border-bottom: none; 757 | border-top-width: 6px; 758 | border-top-color: $color-white; 759 | } 760 | } 761 | 762 | &.pull-center { 763 | 764 | &:before { 765 | left: auto; 766 | right: 50%; 767 | margin-right: -7px; 768 | } 769 | 770 | &:after { 771 | left: auto; 772 | right: 50%; 773 | margin-right: -6px; 774 | } 775 | } 776 | 777 | &.pull-middle { 778 | margin-right: 8px; 779 | 780 | &:before { 781 | top: 50%; 782 | left: 100%; 783 | right: auto; 784 | margin-top: -7px; 785 | border-right-width: 0; 786 | border-bottom-color: transparent; 787 | border-top-width: 7px; 788 | border-left-color: $color-mercury; 789 | border-left-color: rgba(0, 0, 0, 0.15); 790 | } 791 | 792 | &:after { 793 | top: 50%; 794 | left: 100%; 795 | right: auto; 796 | margin-top: -6px; 797 | border-right-width: 0; 798 | border-bottom-color: transparent; 799 | border-top-width: 6px; 800 | border-left-color: $color-white; 801 | } 802 | 803 | &.pull-right { 804 | margin-right: 0; 805 | margin-left: 8px; 806 | 807 | &:before { 808 | left: -7px; 809 | border-left-width: 0; 810 | border-right-width: 7px; 811 | border-right-color: $color-mercury; 812 | border-right-color: rgba(0, 0, 0, 0.15); 813 | } 814 | 815 | &:after { 816 | left: -6px; 817 | border-left-width: 0; 818 | border-right-width: 6px; 819 | border-right-color: $color-white; 820 | } 821 | } 822 | 823 | &.pull-center { 824 | margin-left: 0; 825 | margin-right: 0; 826 | 827 | &:before, &:after { 828 | border: none; 829 | display: none; 830 | } 831 | } 832 | } 833 | } 834 | } 835 | 836 | .dropdown-submenu { 837 | position: relative; 838 | 839 | > { 840 | .dropdown-menu { 841 | top: 0; 842 | left: 100%; 843 | margin-top: -6px; 844 | margin-left: -1px; 845 | border-top-left-radius: 0; 846 | } 847 | 848 | a:before { 849 | display: block; 850 | float: right; 851 | width: 0; 852 | height: 0; 853 | content: ""; 854 | margin-top: 6px; 855 | margin-right: -8px; 856 | border-width: 4px 0 4px 4px; 857 | border-style: solid; 858 | border-left-style: dashed; 859 | border-top-color: transparent; 860 | border-bottom-color: transparent; 861 | } 862 | } 863 | } 864 | 865 | @media (max-width: 767px) { 866 | .navbar-nav { 867 | 868 | .dropdown-submenu > a { 869 | padding-left: 40px; 870 | 871 | &:before { 872 | margin-top: 8px; 873 | border-color: inherit; 874 | border-style: solid; 875 | border-width: 4px 4px 0; 876 | border-left-color: transparent; 877 | border-right-color: transparent; 878 | } 879 | } 880 | 881 | > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > { 882 | 883 | a, 884 | label { 885 | padding-left: 35px; 886 | } 887 | 888 | .dropdown-menu > li > { 889 | 890 | a, label { 891 | padding-left: 45px; 892 | } 893 | 894 | .dropdown-menu > li > { 895 | 896 | a, label { 897 | padding-left: 55px; 898 | } 899 | 900 | .dropdown-menu > li > { 901 | 902 | a, label { 903 | padding-left: 65px; 904 | } 905 | 906 | .dropdown-menu > li > { 907 | 908 | a, label { 909 | padding-left: 75px; 910 | } 911 | } 912 | } 913 | } 914 | } 915 | } 916 | } 917 | } 918 | 919 | .navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a { 920 | background-color: $color-mercury; 921 | color: $color-dark-gray; 922 | 923 | &:hover, 924 | &:focus { 925 | background-color: $color-mercury; 926 | color: $color-dark-gray; 927 | } 928 | } 929 | 930 | @media (max-width: 767px) { 931 | 932 | .navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:before { 933 | border-top-color: $color-dark-gray; 934 | } 935 | } 936 | 937 | .navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a { 938 | background-color: $color-cod-gray; 939 | color: $color-white; 940 | 941 | &:hover, 942 | &:focus { 943 | background-color: $color-cod-gray; 944 | color: $color-white; 945 | } 946 | } 947 | 948 | @media (max-width: 767px) { 949 | 950 | .navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:before { 951 | border-top-color: $color-white; 952 | } 953 | } -------------------------------------------------------------------------------- /assets/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Mixins 3 | //-------------------------------------------------------------- -------------------------------------------------------------------------------- /assets/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | // Variables 3 | //-------------------------------------------------------------- 4 | 5 | //----------------------------------------- 6 | // Blue 7 | //----------------------------------------- 8 | $color-big-stone: #122b40; 9 | $color-midnight: #204d74; 10 | $color-endeavor: #286090; 11 | $color-curious-blue: #337ab7; 12 | $color-celestial-blue: #428bca; 13 | 14 | 15 | //----------------------------------------- 16 | // Grayscale 17 | //----------------------------------------- 18 | $color-cod-gray: #080808; 19 | $color-nero: #262626; 20 | $color-mine-shaft: #333333; 21 | $color-dark-gray: #555555; 22 | $color-monsoon: #777777; 23 | $color-alumminum: #999999; 24 | $color-stack: #8c8c8c; 25 | $color-silver-chalice: #adadad; 26 | $color-mercury: #e6e6e6; 27 | $color-white: #ffffff; 28 | 29 | 30 | //----------------------------------------- 31 | // Bootstrap Buttons 32 | //----------------------------------------- 33 | $color-malibu: #5bc0de; 34 | $color-summer-sky: darken($color-malibu, 10%); 35 | $color-fern: #5cb85c; 36 | $color-fruit-salad: darken($color-fern, 10%); 37 | $color-casablanca: #f0ad4e; 38 | $color-carrot: darken($color-casablanca, 10%); 39 | $color-valencia: #d9534f; 40 | $color-persian-red: darken($color-valencia, 10%); -------------------------------------------------------------------------------- /assets/scss/admin.scss: -------------------------------------------------------------------------------- 1 | //----------------------------------------- 2 | // Start 3 | //----------------------------------------- 4 | @import "variables"; 5 | @import "mixins"; 6 | 7 | 8 | //----------------------------------------- 9 | // Global 10 | //----------------------------------------- 11 | @import "bootstrap_styles"; 12 | @import "dropdown"; // also from bootstrap 13 | @import "custom"; -------------------------------------------------------------------------------- /assets/svg/README.md: -------------------------------------------------------------------------------- 1 | # Using SVG's with wd_s 2 | 3 | ## Editing SVGs library for your project 4 | All the SVGs in this folder are from [https://icomoon.io/app/](icoMoon App). If you would like to update (add/remove) from the overall library for your project. Just open icoMoonApp, and import the wdflexi-icoMoon-FontAwesome.json file, and select to your whimsy. 5 | 6 | ## Using inline SVGs with wd_s 7 | - Drop SVG(s) into images/svg 8 | - Run 'grunt icons' 9 | - Use 10 | 11 | SVG icons will now appear inline, and can be styled via CSS! 12 | 13 | https://github.com/FWeinb/grunt-svgstore -------------------------------------------------------------------------------- /assets/svg/angle-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/angle-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/bars.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-down-brown.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-down-tan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-down-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-up-brown.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-up-tan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-up-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/caret-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/cc-amex.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/cc-mastercard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/cc-paypal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/cc-visa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/check-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/checkbox-checked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/checkbox-unchecked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/checked-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/checked.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/chevron-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/chevron-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/envelope.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/google-plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/instagram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/layout1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/layout2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/layout3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/layout4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/linkedin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/location.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/minus-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/minus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/pinterest-p.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/plus-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/print.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/ruler.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/search-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/search-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/share.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/times-circle-o.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/truck.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svg/youtube.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/install-wp-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -lt 3 ]; then 4 | echo "usage: $0 [db-host] [wp-version]" 5 | exit 1 6 | fi 7 | 8 | DB_NAME=$1 9 | DB_USER=$2 10 | DB_PASS=$3 11 | DB_HOST=${4-localhost} 12 | WP_VERSION=${5-latest} 13 | 14 | WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} 15 | WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} 16 | 17 | download() { 18 | if [ `which curl` ]; then 19 | curl -s "$1" > "$2"; 20 | elif [ `which wget` ]; then 21 | wget -nv -O "$2" "$1" 22 | fi 23 | } 24 | 25 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then 26 | WP_TESTS_TAG="tags/$WP_VERSION" 27 | else 28 | # http serves a single offer, whereas https serves multiple. we only want one 29 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json 30 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json 31 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') 32 | if [[ -z "$LATEST_VERSION" ]]; then 33 | echo "Latest WordPress version could not be found" 34 | exit 1 35 | fi 36 | WP_TESTS_TAG="tags/$LATEST_VERSION" 37 | fi 38 | 39 | set -ex 40 | 41 | install_wp() { 42 | 43 | if [ -d $WP_CORE_DIR ]; then 44 | return; 45 | fi 46 | 47 | mkdir -p $WP_CORE_DIR 48 | 49 | if [ $WP_VERSION == 'latest' ]; then 50 | local ARCHIVE_NAME='latest' 51 | else 52 | local ARCHIVE_NAME="wordpress-$WP_VERSION" 53 | fi 54 | 55 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz 56 | tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR 57 | 58 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php 59 | } 60 | 61 | install_test_suite() { 62 | # portable in-place argument for both GNU sed and Mac OSX sed 63 | if [[ $(uname -s) == 'Darwin' ]]; then 64 | local ioption='-i .bak' 65 | else 66 | local ioption='-i' 67 | fi 68 | 69 | # set up testing suite if it doesn't yet exist 70 | if [ ! -d $WP_TESTS_DIR ]; then 71 | # set up testing suite 72 | mkdir -p $WP_TESTS_DIR 73 | svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes 74 | fi 75 | 76 | cd $WP_TESTS_DIR 77 | 78 | if [ ! -f wp-tests-config.php ]; then 79 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php 80 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php 81 | sed $ioption "s:define( 'WP_DEBUG', true );:define( 'WP_DEBUG', true ); define( 'WP_DEBUG_LOG', true );:" "$WP_TESTS_DIR"/wp-tests-config.php 82 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php 83 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php 84 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php 85 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php 86 | fi 87 | 88 | } 89 | 90 | install_db() { 91 | # parse DB_HOST for port or socket references 92 | local PARTS=(${DB_HOST//\:/ }) 93 | local DB_HOSTNAME=${PARTS[0]}; 94 | local DB_SOCK_OR_PORT=${PARTS[1]}; 95 | local EXTRA="" 96 | 97 | if ! [ -z $DB_HOSTNAME ] ; then 98 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then 99 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" 100 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then 101 | EXTRA=" --socket=$DB_SOCK_OR_PORT" 102 | elif ! [ -z $DB_HOSTNAME ] ; then 103 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" 104 | fi 105 | fi 106 | 107 | # create database 108 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA 109 | } 110 | 111 | install_wp 112 | install_test_suite 113 | install_db 114 | -------------------------------------------------------------------------------- /includes/class-menu-admin.php: -------------------------------------------------------------------------------- 1 | id ) { 44 | return; // Only show on nav-menu's screen. 45 | } 46 | 47 | wp_enqueue_media(); 48 | wp_enqueue_style( 'wdsmm-admin', wds_mega_menus()->url . 'assets/css/admin.css', array(), wds_mega_menus()->version ); 49 | 50 | $min = '.min'; 51 | 52 | if ( defined( 'WP_SCRIPT_DEBUG' ) && WP_SCRIPT_DEBUG ) { 53 | $min = ''; 54 | } 55 | 56 | wp_register_script( 'wds-mega-menus', wds_mega_menus()->url . "assets/js/wds-mega-menus{$min}.js", array( 'jquery' ), wds_mega_menus()->version, true ); 57 | wp_enqueue_script( 'wds-mega-menus' ); 58 | wp_enqueue_script( 'bootstrap-dropdown', wds_mega_menus()->url . 'assets/js/dropdowns-enhancement.js', array( 'jquery' ), wds_mega_menus()->version, true ); 59 | } 60 | 61 | /** 62 | * Filter the walker being used for the menu edit screen 63 | * 64 | * @since 0.1.0 65 | * @author Dustin Filippini, Aubrey Portwood 66 | * 67 | * @return string 68 | */ 69 | public function nav_menu_edit_walker() { 70 | return 'WDS_Mega_Menus_Walker_Nav_Menu_Edit'; 71 | } 72 | 73 | /** 74 | * Register a field for the nav menu 75 | * 76 | * @since 0.1.0 77 | * @author Dustin Filippini, Aubrey Portwood 78 | * 79 | * @param object $menu_item The menu item object. 80 | * @return mixed 81 | */ 82 | public function register_nav_field( $menu_item ) { 83 | $menu_item->image = get_post_thumbnail_id( $menu_item->ID ); 84 | $menu_item->icon = get_post_meta( $menu_item->ID, '_menu_item_icon', true ); 85 | $menu_item->icon = get_post_meta( $menu_item->ID, '_menu_item_widget_area', true ); 86 | return $menu_item; 87 | } 88 | 89 | /** 90 | * Save the new field data for the nav menu. 91 | * 92 | * @since 0.1.0 93 | * @author Dustin Filippini, Aubrey Portwood, Chris Reynolds 94 | * 95 | * @param int $menu_id Not used here. 96 | * @param int $menu_item_db_id The menu item post ID. 97 | * @param array $args Not used here. 98 | * @todo Maybe add nonces when getting data from $_POST? 99 | */ 100 | public function update_nav_fields( $menu_id, $menu_item_db_id, $args ) { 101 | 102 | // Hide on mobile. 103 | if ( isset( $_POST['hide-menu-on-mobile'][ $menu_item_db_id ] ) ) { 104 | update_post_meta( $menu_item_db_id, 'hide_menu_on_mobile', empty( $_POST['hide-menu-on-mobile'][ $menu_item_db_id ] ) ? false : 'on' ); 105 | } else { 106 | delete_post_meta( $menu_item_db_id, 'hide_menu_on_mobile' ); 107 | } 108 | 109 | // Image. 110 | if ( isset( $_POST['menu-item-image'] ) && is_array( $_POST['menu-item-image'] ) ) { 111 | if ( ! isset( $_POST['menu-item-image'][$menu_item_db_id] ) || ! $_POST['menu-item-image'][$menu_item_db_id] ) { 112 | delete_post_thumbnail( $menu_item_db_id ); 113 | } 114 | 115 | if ( isset( $_POST['menu-item-image'][$menu_item_db_id] ) ) { 116 | set_post_thumbnail( $menu_item_db_id, absint( $_POST['menu-item-image'][$menu_item_db_id] ) ); 117 | } 118 | } 119 | 120 | if ( isset( $_POST['menu-item-icon'] ) && is_array( $_POST['menu-item-icon'] ) ) { 121 | if ( isset( $_POST['menu-item-icon'][$menu_item_db_id] ) ) { 122 | update_post_meta( $menu_item_db_id, '_menu_item_icon', sanitize_text_field( $_POST['menu-item-icon'][$menu_item_db_id] ) ); 123 | } 124 | } 125 | 126 | if ( isset( $_POST['menu-item-widget-area'] ) && isset( $_POST['menu-item-widget-area'][$menu_item_db_id] ) && is_array( $_POST['menu-item-widget-area'] ) ) { 127 | update_post_meta( $menu_item_db_id, '_menu_item_widget_area', sanitize_text_field( $_POST['menu-item-widget-area'][$menu_item_db_id] ) ); 128 | } 129 | 130 | } 131 | 132 | /** 133 | * Add SVG definitions to . 134 | * 135 | * @since 0.2.0 136 | * @author Chris Reynolds 137 | */ 138 | public function include_svg_definitions() { 139 | // Only do this on the nav menus page. Theme will load SVGs on its own. 140 | $screen = get_current_screen(); 141 | if ( 'nav-menus' !== $screen->id ) { 142 | return; 143 | } 144 | // Require the svg-defs.svg file. 145 | if ( file_exists( wds_mega_menus()->svg_defs ) ) { 146 | require_once( wds_mega_menus()->svg_defs ); 147 | } 148 | } 149 | } // class WDS_Mega_Menus_Admin 150 | } // if class WDS_Mega_Menus_Admin. 151 | -------------------------------------------------------------------------------- /includes/class-menu-walker.php: -------------------------------------------------------------------------------- 1 | 'menu_item_parent', 'id' => 'db_id' ); 36 | 37 | /** 38 | * Constructor 39 | * 40 | * @since 0.3.0 41 | * @author Pavel Korotenko 42 | */ 43 | public function __construct() { 44 | if ( file_exists( wds_mega_menus()->svg_defs ) ) { 45 | require_once( wds_mega_menus()->svg_defs ); 46 | } 47 | } 48 | 49 | /** 50 | * Starts the list before the elements are added. 51 | * 52 | * @see Walker::start_lvl() 53 | * 54 | * @since 0.1.0 55 | * @author Dustin Filippini, Aubrey Portwood 56 | * 57 | * @param string $output Passed by reference. Used to append additional content. 58 | * @param int $depth Depth of menu item. Used for padding. 59 | * @param array $args An array of arguments. 60 | * @see wp_nav_menu() 61 | */ 62 | public function start_lvl( &$output, $depth = 0, $args = array() ) { 63 | $indent = str_repeat( "\t", $depth ); 64 | if ( 1 == $depth ) { 65 | $output .= "\n$indent
    \n"; 66 | } else { 67 | $output .= "\n$indent
      \n"; 68 | } 69 | } 70 | 71 | /** 72 | * Ends the list of after the elements are added. 73 | * 74 | * @see Walker::end_lvl() 75 | * 76 | * @since 0.1.0 77 | * @author Dustin Filippini, Aubrey Portwood 78 | * 79 | * @param string $output Passed by reference. Used to append additional content. 80 | * @param int $depth Depth of menu item. Used for padding. 81 | * @param array $args An array of arguments. 82 | * @see wp_nav_menu() 83 | */ 84 | public function end_lvl( &$output, $depth = 0, $args = array() ) { 85 | $indent = str_repeat( "\t", $depth ); 86 | $output .= "$indent
    \n"; 87 | } 88 | 89 | /** 90 | * Start the element output. 91 | * 92 | * @see Walker::start_el() 93 | * 94 | * @since 0.1.0 95 | * @author Dustin Filippini, Aubrey Portwood, Corey Collins 96 | * 97 | * @param string $output Passed by reference. Used to append additional content. 98 | * @param object $item Menu item data object. 99 | * @param int $depth Depth of menu item. Used for padding. 100 | * @param array $args An array of arguments. 101 | * @param int $id Current item ID. 102 | * @see wp_nav_menu() 103 | */ 104 | public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { 105 | 106 | 107 | $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; 108 | 109 | $classes = empty( $item->classes ) ? array() : (array) $item->classes; 110 | $classes[] = 'menu-item-' . $item->ID; 111 | 112 | // Hide on mobile. 113 | $hide_on_mobile = get_post_meta( $item->ID, 'hide_menu_on_mobile', true ); 114 | if ( $hide_on_mobile ) { 115 | $classes[] = 'menu-item-hide-on-mobile'; 116 | } 117 | 118 | /** 119 | * Filter the CSS class(es) applied to a menu item's list item element. 120 | * 121 | * @since 0.1.0 122 | * @author Dustin Filippini, Aubrey Portwood 123 | * 124 | * @param array $classes The CSS classes that are applied to the menu item's `
  • ` element. 125 | * @param object $item The current menu item. 126 | * @param array $args An array of {@see wp_nav_menu()} arguments. 127 | * @param int $depth Depth of menu item. Used for padding. 128 | */ 129 | $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) ); 130 | $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; 131 | 132 | /** 133 | * Filter the ID applied to a menu item's list item element. 134 | * 135 | * @since 0.1.0 136 | * @author Dustin Filippini, Aubrey Portwood 137 | * 138 | * @param string $menu_id The ID that is applied to the menu item's `
  • ` element. 139 | * @param object $item The current menu item. 140 | * @param array $args An array of {@see wp_nav_menu()} arguments. 141 | * @param int $depth Depth of menu item. Used for padding. 142 | */ 143 | $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth ); 144 | $id = $id ? ' id="' . esc_attr( $id ) . '"' : ''; 145 | 146 | $output .= $indent . ''; 147 | 148 | $atts = array(); 149 | $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; 150 | $atts['target'] = ! empty( $item->target ) ? $item->target : ''; 151 | $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; 152 | $atts['href'] = ! empty( $item->url ) ? $item->url : ''; 153 | 154 | /** 155 | * Filter the HTML attributes applied to a menu item's anchor element. 156 | * 157 | * @since 0.1.0 158 | * @author Dustin Filippini, Aubrey Portwood 159 | * 160 | * @param array $atts { 161 | * The HTML attributes applied to the menu item's `` element, empty strings are ignored. 162 | * 163 | * @type string $title Title attribute. 164 | * @type string $target Target attribute. 165 | * @type string $rel The rel attribute. 166 | * @type string $href The href attribute. 167 | * } 168 | * @param object $item The current menu item. 169 | * @param array $args An array of {@see wp_nav_menu()} arguments. 170 | * @param int $depth Depth of menu item. Used for padding. 171 | */ 172 | $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth ); 173 | 174 | $attributes = ''; 175 | foreach ( $atts as $attr => $value ) { 176 | if ( ! empty( $value ) ) { 177 | $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); 178 | $attributes .= ' ' . $attr . '="' . $value . '"'; 179 | } 180 | } 181 | 182 | $icon = get_post_meta( $item->ID, '_menu_item_icon', true ); 183 | $item_output = isset( $args->before ) ? $args->before : ''; 184 | 185 | // Add the menu link. 186 | $item_output .= ''; 187 | $item_output .= ( ! $icon ) ? $this->get_svg( apply_filters( 'wds_mega_menu_default_icon', false ) ) : $this->get_svg( $icon ); 188 | // This filter is documented in wp-includes/post-template.php. 189 | $item_output .= isset( $args->link_before ) ? $args->link_before : ''; 190 | $item_output .= apply_filters( 'the_title', $item->title, $item->ID ); 191 | $item_output .= isset( $args->link_after ) ? $args->link_after : ''; 192 | $item_output .= ''; 193 | 194 | // The item title. 195 | $item_title = apply_filters( 'wds-mega-menu-title', '

    ' . ( ! $icon ) ? '' : $this->get_svg( $icon ) . apply_filters( 'the_title', $item->title, $item->ID ) . '

    ' ); 196 | 197 | // The item content. 198 | $item_content = apply_filters( 'wds-mega-menu-content', wpautop( $item->post_content ) ); 199 | 200 | // The item read more link. 201 | $item_read_more = apply_filters( 'wds-mega-menu-read-more', '

    ' . __( 'Keep Reading', 'wds-mega-menus' ) . '

    ' ); 202 | 203 | // Use an inline image, or CSS on a Div? 204 | $item_use_real_image = apply_filters( 'wds-mega-menu-inline-image', true ); 205 | 206 | // Start the menu item wrap so it can contain a potential sidebar widget 207 | $item_output .= ''; // .menu-item-container 247 | 248 | /** 249 | * Filter a menu item's starting output. 250 | * 251 | * The menu item's starting output only includes `$args->before`, the opening ``, 252 | * the menu item's title, the closing ``, and `$args->after`. Currently, there is 253 | * no filter for modifying the opening and closing `
  • ` for a menu item. 254 | * 255 | * @since 0.1.0 256 | * @author Dustin Filippini, Aubrey Portwood 257 | * 258 | * @param string $item_output The menu item's starting HTML output. 259 | * @param object $item Menu item data object. 260 | * @param int $depth Depth of menu item. Used for padding. 261 | * @param array $args An array of {@see wp_nav_menu()} arguments. 262 | */ 263 | $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); 264 | } 265 | 266 | /** 267 | * Ends the element output, if needed. 268 | * 269 | * @see Walker::end_el() 270 | * 271 | * @since 0.1.0 272 | * @author Dustin Filippini, Aubrey Portwood 273 | * 274 | * @param string $output Passed by reference. Used to append additional content. 275 | * @param object $item Page data object. Not used. 276 | * @param int $depth Depth of page. Not Used. 277 | * @param array $args An array of arguments. 278 | * @see wp_nav_menu() 279 | */ 280 | public function end_el( &$output, $item, $depth = 0, $args = array() ) { 281 | $output .= "
  • \n"; 282 | } 283 | 284 | /** 285 | * Returns the SVG markup. 286 | * 287 | * @since 0.1.0 288 | * @author Dustin Filippini, Aubrey Portwood 289 | * 290 | * @param string $icon_name The SVG icon slug/name. 291 | * @return string The full SVG markup. 292 | */ 293 | private function get_svg( $icon_name ) { 294 | if ( $icon_name && ! empty( $icon_name ) ) { 295 | $svg = ''; 296 | $svg .= ' '; 297 | $svg .= ''; 298 | 299 | return $svg; 300 | } 301 | 302 | return false; 303 | } 304 | } // class WDS_Mega_Menu_Walker. 305 | 306 | // We don't have the requirements for this. 307 | } // if ( ! class_exists( 'WDS_Mega_Menus_Walker_Nav_Menu_Edit' ) 308 | -------------------------------------------------------------------------------- /includes/class-options.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 97 | $this->page_title = __( 'WDS Mega Menus Options', 'wds-mega-menus' ); 98 | $this->hooks(); 99 | } 100 | 101 | /** 102 | * Deepest menu depth. 103 | * 104 | * @since 0.2.1 105 | * @author Zach Owen 106 | * @var int 107 | */ 108 | private $deepest_menu = 1; 109 | 110 | /** 111 | * Show the options page. This also handles saving. 112 | * 113 | * @since 0.2.1 114 | * @author Zach Owen, Chris Reynolds 115 | */ 116 | public function handle_options_page() { 117 | // @TODO Filter which menu to use? 118 | $this->deepest_menu = $this->get_deepest_menu( 'nav_menu' ) ?: 1; 119 | 120 | /** 121 | * Some quick todos for later. 122 | * 123 | * @TODO this looks ugly with that long description :/ 124 | * @TODO Also, I think I've just created a poor man's CMB. Butts. 125 | */ 126 | $this->add_field( array( 127 | 'key' => 'wds_mega_menus_depth', 128 | 'title' => __( 'Applied Menu Depth(s)', 'wds-mega-menus' ), 129 | 'desc' => __( 'Select menu levels to apply the Mega Menu to.', 'wds-mega-menus' ), // Replaces wdsmm_walker_nav_allowed_depths filter). 130 | ) ); 131 | 132 | // Check to see if anything is saved. 133 | $this->check_for_save(); 134 | 135 | // Output the form and fields. 136 | echo $this->open_options_page(); 137 | echo $this->get_options_fields(); 138 | 139 | wp_nonce_field( $this->nonce_action, $this->nonce_field ); 140 | 141 | echo $this->close_options_page(); 142 | } 143 | 144 | /** 145 | * Hooks to activate the options page. 146 | * 147 | * @since 0.2.1 148 | * @author Zach Owen 149 | */ 150 | public function hooks() { 151 | add_action( 'admin_menu', array( $this, 'register_menu' ) ); 152 | add_filter( 'wds_mega_menus_options_save', array( $this, 'process_depth_value' ), 10, 2 ); 153 | add_filter( 'wds_mega_menus_input', array( $this, 'render_depth_input' ), 10, 3 ); 154 | } 155 | 156 | /** 157 | * Register the submenu. 158 | * 159 | * @since 0.2.1 160 | * @author Zach Owen, Chris Reynolds 161 | */ 162 | public function register_menu() { 163 | if ( has_filter( 'wdsmm_walker_nav_allowed_depths' ) ) { 164 | return; 165 | } 166 | 167 | // Check for the old filter and display a notice if it's being used. Add the submenu page for those folks. 168 | if ( has_filter( 'wds_mega_menus_walker_nav_menu_edit_allowed_depths' ) ) { 169 | _deprecated_hook( 'wds_mega_menus_walker_nav_menu_edit_allowed_depths', '0.3.0', 'wdsmm_walker_nav_allowed_depths' ); 170 | } 171 | 172 | add_submenu_page( 173 | $this->page, 174 | $this->page_title, 175 | __( 'WDS Mega Menus', 'wds-mega-menus' ), 176 | 'edit_theme_options', 177 | $this->menu_slug, 178 | array( $this, 'handle_options_page' ) 179 | ); 180 | } 181 | 182 | /** 183 | * Returns the opening of the form page. 184 | * 185 | * @since 0.2.1 186 | * @author Zach Owen 187 | */ 188 | private function open_options_page() { 189 | return << 191 |

    {$this->page_title}

    192 |

    193 |

    194 | 195 | 196 | HTML; 197 | } 198 | 199 | /** 200 | * Close the options form table. 201 | * 202 | * @since 0.2.1 203 | * @author Zach Owen, Pavel Korotenko 204 | * 205 | * @return string 206 | * @todo Properly enqueue the javascript here. 207 | */ 208 | private function close_options_page() { 209 | wds_mega_menus()->admin->admin_enqueue_scripts( true ); 210 | return << 212 |
    213 |

    214 | 215 | HTML; 216 | } 217 | 218 | /** 219 | * Get an option from the serialized options array. 220 | * 221 | * @since 0.2.1 222 | * @author Zach Owen 223 | * 224 | * @param string $key The option key to get. 225 | * @param mixed $default Optional default value to reutrn. 226 | * @return mixed 227 | */ 228 | public function get_option( $key, $default = null ) { 229 | if ( null === self::$options ) { 230 | self::$options = get_option( $this->option_key ); 231 | 232 | if ( ! self::$options ) { 233 | self::$options = array(); 234 | update_option( $this->option_key, self::$options ); 235 | return $default; 236 | } 237 | } 238 | 239 | if ( ! isset( self::$options[ $key ] ) ) { 240 | return $default; 241 | } 242 | 243 | // Return the test value if truthy, otherwise $default. 244 | return self::$options[ $key ] ?: $default; 245 | } 246 | 247 | /** 248 | * Set an option to the serialized array and sync to the options table. 249 | * 250 | * @since 0.2.1 251 | * @author Zach Owen 252 | * 253 | * @param string $key The option key to use. 254 | * @param mixed $value The option value to set. 255 | */ 256 | private function set_option( $key, $value ) { 257 | self::$options[ $key ] = $value; 258 | update_option( $this->option_key, self::$options ); 259 | } 260 | 261 | /** 262 | * Add a field to the set to be rendered and saved. 263 | * Fields should contain a key, title, and description. 264 | * 265 | * @since 0.2.1 266 | * @author Zach Owen 267 | * 268 | * @param array $field The field definition. 269 | */ 270 | private function add_field( $field ) { 271 | if ( ! isset( $this->fields[ $field['key'] ] ) ) { 272 | $this->fields[ $field['key'] ] = $field; 273 | } 274 | } 275 | 276 | /** 277 | * Render option fields to go in the table. Bear in mind that this only accounts for text fields currently. 278 | * 279 | * @since 0.2.1 280 | * @author Zach Owen 281 | * 282 | * @return string 283 | */ 284 | private function get_options_fields() { 285 | $html = ''; 286 | 287 | foreach ( $this->fields as $field ) { 288 | $value = $this->get_option( $field['key'] ); 289 | 290 | $input = vsprintf( '', array( 291 | esc_attr( $value ), 292 | esc_attr( $field['key'] ), 293 | ) ); 294 | 295 | /** 296 | * Filter an input's HTML before rendering the field. 297 | * 298 | * @since 0.2.1 299 | * @author Zach Owen 300 | * 301 | * @param string $field The field name. 302 | * @param mixed $value The field value. 303 | * @return string 304 | */ 305 | $input = apply_filters( 'wds_mega_menus_input', $input, $field, $value ); 306 | 307 | $html .= << 309 | 310 | 311 | 312 | 313 | {$input} 314 |
    315 | 316 | {$field['desc']} 317 | 318 | 319 | 320 | HTML; 321 | } 322 | 323 | return $html; 324 | } 325 | 326 | /** 327 | * Check for and save form data. 328 | * 329 | * @since 0.2.1 330 | * @author Zach Owen 331 | */ 332 | private function check_for_save() { 333 | if ( ! empty( $_POST ) && check_admin_referer( $this->nonce_action, $this->nonce_field ) ) { 334 | foreach ( $this->fields as $field ) { 335 | $key = $field['key']; 336 | if ( ! isset( $_POST[ $key ] ) ) { 337 | continue; 338 | } 339 | 340 | if ( empty( $key ) ) { 341 | $this->set_option( $key ); 342 | continue; 343 | } 344 | 345 | /** 346 | * Filter the value before saving. 347 | * 348 | * @since 0.2.1 349 | * @author Zach Owen 350 | * 351 | * @param string $key The key of the field being processed. 352 | * @return mixed 353 | */ 354 | $value = apply_filters( 'wds_mega_menus_options_save', wp_unslash( $_POST[ $key ] ), $key ); 355 | $this->set_option( $key, $value ); 356 | } 357 | } 358 | } 359 | 360 | /** 361 | * Process a saved depth value. 362 | * 363 | * @since 0.2.1 364 | * @author Zach Owen, Pavel Korotenko 365 | * 366 | * @param mixed $value The menu depths value. Comma-separated list of depths. 367 | * @param string $key The key of the field being processed. 368 | * @return mixed 369 | */ 370 | public function process_depth_value( $value, $key ) { 371 | if ( 'wds_mega_menus_depth' !== $key ) { 372 | return array(); 373 | } 374 | 375 | if ( empty( $value ) ) { 376 | return array(); 377 | } 378 | 379 | return implode( ',', $value ); 380 | } 381 | 382 | /** 383 | * Render the depth input field. 384 | * 385 | * @since 0.2.1 386 | * @author Zach Owen, Pavel Korotenko 387 | * 388 | * @param string $input The input field HMTL. 389 | * @param string $field The field name. 390 | * @param mixed $value The field value. 391 | * @return string 392 | */ 393 | public function render_depth_input( $input, $field, $value ) { 394 | if ( 'wds_mega_menus_depth' !== $field['key'] ) { 395 | return; 396 | } 397 | 398 | // Set to 1 when the deepest menu is 0. 399 | $checked_items = explode( ',', $value ); 400 | $html = ''; 401 | $html .= '
      '; 402 | 403 | for ( $i = 0; $i <= $this->deepest_menu; $i++ ) { 404 | $attributes = array(); 405 | 406 | if ( in_array( $i, $checked_items ) ) { 407 | $attributes[] = 'checked="checked"'; 408 | } 409 | 410 | /** 411 | * Filter an array that can contain integers (refernced by constants on the main class). 412 | * 413 | * @since 0.3.0 414 | * @param array $overrides The array of overrides to use. 415 | * @param int $i The current depth. 416 | * @param array $checked_items The items in the menu that are checked currently. 417 | * @param int $deepest_menu The deepest menu depth. 418 | */ 419 | $attribute_override = apply_filters( 'wdsmm_walker_nav_options_depth_override', array(), $i, $checked_items, $this->deepest_menu ); 420 | 421 | /** 422 | * Note: I considered allowing direct modification of the attributes, but this seems 423 | * safer since the user can't flub anything up in the admin with malformed/malicious HTML. 424 | */ 425 | switch ( $attribute_override ) { 426 | case WDS_Mega_Menus::OVERRIDE_DEPTH_REQUIRED: 427 | $attributes[] = 'checked="checked"'; 428 | $attributes[] = 'disabled="disabled"'; 429 | break; 430 | 431 | case WDS_Mega_Menus::OVERRIDE_DEPTH_DISABLED: 432 | $attributes[] = 'disabled="disabled"'; 433 | break; 434 | } 435 | 436 | $attributes = implode( ' ', $attributes ); 437 | 438 | $key = esc_attr( $field['key'] ); 439 | $html .= sprintf( '
    • ', $key, $attributes, $i ); 440 | $html .= sprintf( __( '
    • ', 'wds-mega-menus' ), $key, $i ); 441 | } 442 | 443 | $html .= sprintf( '
    • ', $key, in_array( "all", $checked_items ) ? 'checked' : ''); 444 | $html .= sprintf( __( '
    • ', 'wds-mega-menus' ), $key ); 445 | 446 | 447 | $i--; 448 | 449 | do { 450 | $html .= '
    '; 451 | } while ( $i-- ); 452 | 453 | return $html; 454 | } 455 | 456 | /** 457 | * Find the deepest menu depth. 458 | * 459 | * @since 0.2.1 460 | * @author Zach Owen 461 | * 462 | * @return int 463 | */ 464 | private function get_deepest_menu( $menu ) { 465 | $deepest = 0; 466 | $menu_items = get_terms( $menu, array( 'hide_empty' => true ) ); 467 | 468 | foreach ( $menu_items as $item ) { 469 | $nav_menu_items = isset( $menus[ $item->slug ] ) ? $menus[ $item->slug ] : wp_get_nav_menu_items( $item->slug ); 470 | 471 | foreach ( $nav_menu_items as $nav_item ) { 472 | if ( ! $nav_item->menu_item_parent ) { 473 | continue; 474 | } 475 | 476 | $parent_meta = get_post_meta( $nav_item->menu_item_parent, '_menu_item_menu_item_parent', true ); 477 | $depth = 0; 478 | 479 | do { 480 | $depth++; 481 | $nav_item = get_post( $parent_meta ); 482 | 483 | if ( ! $parent_meta || ! $nav_item ) { 484 | break; 485 | } 486 | 487 | $parent_meta = get_post_meta( $nav_item->ID, '_menu_item_menu_item_parent', true ); 488 | } while ( ! empty( $parent_meta ) ); 489 | 490 | if ( $depth > $deepest ) { 491 | $deepest = $depth; 492 | } 493 | } 494 | } 495 | 496 | // Account for WP menu levels. 497 | return $deepest + 1; 498 | } 499 | } 500 | } 501 | -------------------------------------------------------------------------------- /includes/class-walker-nav-menu-edit.php: -------------------------------------------------------------------------------- 1 | field_display( $item->ID, array( 45 | 'args' => $args, 46 | 'depth' => $depth, 47 | 'item' => $item, 48 | 'item_output' => $item_output, 49 | ) ); 50 | 51 | $item_output = preg_replace( '/(?=]+class="[^"]*field-move)/', $new_fields, $item_output ); 52 | $output .= $item_output; 53 | 54 | } 55 | 56 | /** 57 | * Create the markup for our custom field 58 | * 59 | * @since 0.1.0 60 | * @author Dustin Filippini, Aubrey Portwood, Chris Reynolds, Zach Owen, Jo Murgel 61 | * 62 | * @param int $id Menu item ID. 63 | * @param array $args Array of arguments passed from start_el. 64 | * @return string The markup for the custom field. 65 | */ 66 | public function field_display( $id, $args = array() ) { 67 | ob_start(); 68 | 69 | $args = wp_parse_args( $args, array( 70 | 'args' => array(), 71 | 'depth' => false, 72 | 'item' => false, 73 | 'item_output' => false, 74 | ) ); 75 | 76 | // Disable on mobile. 77 | if ( isset( $args['depth'] ) && false == $args['depth'] ) : 78 | $hide_on_mobile = get_post_meta( $id, 'hide_menu_on_mobile', true ); 79 | ?> 80 |

    81 |

    82 | 85 |
    86 |

    87 | options->get_option( 'wds_mega_menus_depth', '' ); 110 | 111 | if ( strlen( $option_value ) ) { 112 | $allowed_depths = explode( ',', $option_value ); 113 | } 114 | } 115 | 116 | if ( ! empty( $allowed_depths ) && in_array( $args['depth'], $allowed_depths ) ) : 117 | $img_id = get_post_thumbnail_id( $id ); 118 | $img_url = wp_get_attachment_image_src( $img_id, 'large' ); 119 | $this->featured_ids[] = esc_attr( absint( $id ) ); 120 | ?> 121 | 122 |
    123 |
    124 |

    125 |
    126 | 133 | 142 |
    143 |
    144 |
    145 |
    146 |

    147 |
    148 | 149 |

    150 |

    151 | 152 |

    153 | 157 | 160 |
    161 |
    162 |

    163 |

    164 | 173 |

    174 |
    175 | svg . '*.svg' ) as $svg ) { 195 | $slug = str_replace( array( wds_mega_menus()->svg, '.svg' ), '', $svg ); 196 | $svgs[ $slug ] = $this->get_svg( $slug ) . ' ' . ucfirst( str_replace( '-', ' ', $slug ) ); 197 | } 198 | 199 | return $svgs; 200 | } 201 | 202 | /** 203 | * Return the SVG icon markup. 204 | * 205 | * @since 0.1.0 206 | * @author Dustin Filippini, Aubrey Portwood, Chris Reynolds 207 | * 208 | * @param string $icon_name The SVG icon name/slug (based on the original filename). 209 | * @return string The SVG markup. 210 | */ 211 | function get_svg( $icon_name ) { 212 | 213 | $svg = ''; 214 | $svg .= ' '; 215 | $svg .= ''; 216 | 217 | return $svg; 218 | } 219 | 220 | /** 221 | * Override to allow us to localize the featured IDs before we finish. 222 | * 223 | * @since 0.3.1 224 | * @param string $output Passed by reference. 225 | * @param int $depth Depth of menu item. Used for padding. 226 | * @param array $args Not used. 227 | */ 228 | public function end_lvl( &$output, $depth = 0, $args = array() ) { 229 | // Only do this on depth = 0. 230 | if ( ! $depth ) { 231 | wds_mega_menus()->admin->admin_enqueue_scripts(); 232 | wp_localize_script( 'wds-mega-menus', 'WDS_MegaMenu_Loc', array( 233 | 'featured_ids' => $this->featured_ids, 234 | ) ); 235 | } 236 | 237 | parent::end_lvl( $output, $depth, $args ); 238 | } 239 | } // class WDS_Mega_Menus_Walker_Nav_Menu_Edit. 240 | 241 | // We don't have the requirements to do this. 242 | } // class WDS_Mega_Menus_Walker_Nav_Menu_Edit exists. 243 | -------------------------------------------------------------------------------- /languages/wds-mega-menus.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2016 wds-mega-menus 2 | # This file is distributed under the same license as the wds-mega-menus package. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: wds-mega-menus\n" 6 | "MIME-Version: 1.0\n" 7 | "Content-Type: text/plain; charset=UTF-8\n" 8 | "Content-Transfer-Encoding: 8bit\n" 9 | "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n" 10 | "X-Poedit-Basepath: ..\n" 11 | "X-Poedit-SourceCharset: UTF-8\n" 12 | "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n" 13 | "X-Poedit-SearchPath-0: .\n" 14 | "X-Poedit-SearchPathExcluded-0: *.js\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 16 | 17 | #: includes/class-menu-walker.php:189 18 | msgid "Keep Reading" 19 | msgstr "" 20 | 21 | #: includes/class-options.php:97 22 | msgid "WDS Mega Menus Options" 23 | msgstr "" 24 | 25 | #: includes/class-options.php:127 26 | msgid "Applied Menu Depth(s)" 27 | msgstr "" 28 | 29 | #: includes/class-options.php:128 30 | msgid "Select menu levels to apply the Mega Menu to." 31 | msgstr "" 32 | 33 | #: includes/class-options.php:174 34 | msgid "WDS Mega Menus" 35 | msgstr "" 36 | 37 | #: includes/class-options.php:411 38 | msgid "" 39 | msgstr "" 40 | 41 | #: includes/class-options.php:416 42 | msgid "" 43 | msgstr "" 44 | 45 | #: includes/class-walker-nav-menu-edit.php:83 46 | msgid "Hide this on mobile" 47 | msgstr "" 48 | 49 | #: includes/class-walker-nav-menu-edit.php:123 50 | msgid "Menu Item Icon" 51 | msgstr "" 52 | 53 | #: includes/class-walker-nav-menu-edit.php:128 54 | msgid "- Choose an icon -" 55 | msgstr "" 56 | 57 | #: includes/class-walker-nav-menu-edit.php:133 58 | msgid "No Icon" 59 | msgstr "" 60 | 61 | #: includes/class-walker-nav-menu-edit.php:146 62 | msgid "Menu Item Image" 63 | msgstr "" 64 | 65 | #: includes/class-walker-nav-menu-edit.php:147 66 | msgid "Images should be 130px wide by 250px high to prevent cropping." 67 | msgstr "" 68 | 69 | #: includes/class-walker-nav-menu-edit.php:150 70 | msgid "Set Menu Item Image" 71 | msgstr "" 72 | 73 | #: includes/class-walker-nav-menu-edit.php:150 74 | msgid "Set menu item image" 75 | msgstr "" 76 | 77 | #: includes/class-walker-nav-menu-edit.php:157 78 | msgid "Remove Menu Item Image" 79 | msgstr "" 80 | 81 | #: includes/class-walker-nav-menu-edit.php:157 82 | msgid "Remove menu item image" 83 | msgstr "" 84 | 85 | #: includes/class-walker-nav-menu-edit.php:161 86 | msgid "Select Widget Area to Display" 87 | msgstr "" 88 | 89 | #: includes/class-walker-nav-menu-edit.php:165 90 | msgid "- Select Widget Area -" 91 | msgstr "" 92 | 93 | #: node_modules/grunt-wp-i18n/test/fixtures/basic-theme/exclude/file.php:3, node_modules/grunt-wp-i18n/test/fixtures/plugin-include/plugin-include.php:6 94 | msgid "Exclude" 95 | msgstr "" 96 | 97 | #: node_modules/grunt-wp-i18n/test/fixtures/plugin-include/include/file.php:2 98 | msgid "Include" 99 | msgstr "" 100 | 101 | #: node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:3, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:4, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-domains.php:2, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-domains.php:3 102 | msgid "String" 103 | msgstr "" 104 | 105 | #: node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:6, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:7, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:8 106 | msgctxt "a string" 107 | msgid "String" 108 | msgstr "" 109 | 110 | #: node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:9, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:10, node_modules/grunt-wp-i18n/test/fixtures/text-domains/update-all-domains.php:11 111 | msgid "1 Star" 112 | msgid_plural "%s Stars" 113 | msgstr[0] "" 114 | msgstr[1] "" 115 | 116 | #: wds-mega-menus.php:302 117 | msgid "WDS Mega Menus is missing requirements and has been deactivated. Please make sure all requirements are available." 118 | msgstr "" 119 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wds-mega-menus", 3 | "title": "WDS Mega Menus", 4 | "version": "1.0.0", 5 | "description": "Make magnificently magical Mega Menus and more.", 6 | "main": "Gulpfile.js", 7 | "dependencies": { 8 | "autoprefixer": "^6.3.1", 9 | "del": "^2.2.0", 10 | "gulp": "^3.9.1", 11 | "gulp-cheerio": "^0.6.2", 12 | "gulp-cssnano": "^2.1.0", 13 | "gulp-notify": "^2.2.0", 14 | "gulp-plumber": "^1.1.0", 15 | "gulp-postcss": "^6.1.0", 16 | "gulp-rename": "^1.2.2", 17 | "gulp-sass": "^2.2.0", 18 | "gulp-sass-lint": "^1.1.1", 19 | "gulp-sort": "^1.1.1", 20 | "gulp-sourcemaps": "^1.6.0", 21 | "gulp-svgmin": "^1.2.1", 22 | "gulp-svgstore": "^5.0.5", 23 | "gulp-uglify": "^1.5.2", 24 | "gulp-util": "^3.0.7", 25 | "gulp-wp-pot": "^1.1.1" 26 | }, 27 | "devDependencies": {}, 28 | "scripts": { 29 | "test": "echo \"No test specified\"" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "git+https://github.com/WebDevStudios/WDS-Mega-Menu" 34 | }, 35 | "keywords": [ 36 | "theme" 37 | ], 38 | "author": "WebDevStudios", 39 | "license": "GPL-3.0", 40 | "bugs": { 41 | "url": "https://github.com/WebDevStudios/WDS-Mega-Menu/issues" 42 | }, 43 | "homepage": "https://github.com/WebDevStudios/WDS-Mega-Menu#readme" 44 | } 45 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === WDS Mega Menus === 2 | Contributors: WebDevStudios 3 | Donate link: http://webdevstudios.com 4 | Tags: 5 | Requires at least: 3.6.0 6 | Tested up to: 4.6.1 7 | Stable tag: 0.3.0 8 | License: GPLv2 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | 12 | == Description == 13 | 14 | Make Magnificently Magical Mega Menus and More 15 | 16 | == Installation == 17 | 18 | = Manual Installation = 19 | 20 | 1. Upload the entire `/wds-mega-menus` directory to the `/wp-content/plugins/` directory. 21 | 2. Activate WDS Mega Menus through the 'Plugins' menu in WordPress. 22 | 23 | == Frequently Asked Questions == 24 | 25 | 26 | == Screenshots == 27 | 28 | 29 | == Changelog == 30 | 31 | = 0.1.0 = 32 | * Initial release 33 | 34 | == Upgrade Notice == 35 | 36 | = 0.1.0 = 37 | Initial Release 38 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | | \ \ ___ ___ ___ | \ \ ___ ._ _ _ _ ___ 23 | * | | | || | |\__ \ | |/ ._>/ . |<_> | | |/ ._>| ' || | |<_-< 24 | * |__/_/ |___/<___/ |_|_|_|\___.\_. |<___| |_|_|_|\___.|_|_|`___|/__/ 25 | * <___' 26 | * 27 | * WDS Mega Menus is a plugin that helps you customize things in the WP Nav. 28 | * 29 | * Copyright (c) 2015 WebDevStudios (email : contact@webdevstudios.com) 30 | * 31 | * This program is free software; you can redistribute it and/or modify 32 | * it under the terms of the GNU General Public License, version 2 or, at 33 | * your discretion, any later version, as published by the Free 34 | * Software Foundation. 35 | * 36 | * This program is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39 | * GNU General Public License for more details. 40 | * 41 | * You should have received a copy of the GNU General Public License 42 | * along with this program; if not, write to the Free Software 43 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 44 | */ 45 | 46 | if ( defined( 'DISABLE_WDS_MEGA_MENU' ) && DISABLE_WDS_MEGA_MENU ) { 47 | return; // Bail if they configure this not to load. 48 | } 49 | 50 | /** 51 | * Autoloads files with classes when needed 52 | * 53 | * @since 0.3.0 54 | * @author Chris Reynolds 55 | * 56 | * @param string $class_name Name of the class being requested. 57 | */ 58 | function wds_menus_autoload_classes( $class_name ) { 59 | if ( 0 !== strpos( $class_name, 'WDS_Mega_Menu_' ) ) { 60 | return; 61 | } 62 | 63 | $filename = strtolower( str_replace( 64 | '_', '-', 65 | substr( $class_name, strlen( 'WDS_Mega_Menu_' ) ) 66 | ) ); 67 | 68 | WDS_Mega_Menus::include_file( $filename ); 69 | } 70 | spl_autoload_register( 'wds_menus_autoload_classes' ); 71 | 72 | /** 73 | * WDS Mega Menus. 74 | * 75 | * This base class handles mostly the instance itself and the plugin 76 | * as a whole. 77 | * 78 | * @since 0.1.0 79 | * @package WDS_Mega_Menus 80 | */ 81 | class WDS_Mega_Menus { 82 | 83 | /** 84 | * Current version 85 | * 86 | * @var string 87 | * @since 0.1.0 88 | */ 89 | const VERSION = '0.3.1'; 90 | 91 | /** 92 | * Constant for overriding the option page depths. 93 | * 94 | * @var int 95 | * @since 0.3.0 96 | */ 97 | const OVERRIDE_DEPTH_REQUIRED = 1; 98 | 99 | /** 100 | * Constant for overriding the option page depths. 101 | * 102 | * @var int 103 | * @since 0.3.0 104 | */ 105 | const OVERRIDE_DEPTH_DISABLED = 2; 106 | 107 | /** 108 | * URL of plugin directory 109 | * 110 | * @var string 111 | * @since 0.1.0 112 | */ 113 | protected $url = ''; 114 | 115 | /** 116 | * Path of plugin directory 117 | * 118 | * @var string 119 | * @since 0.1.0 120 | */ 121 | protected $path = ''; 122 | 123 | /** 124 | * Plugin basename 125 | * 126 | * @var string 127 | * @since 0.1.0 128 | */ 129 | protected $basename = ''; 130 | 131 | /** 132 | * Admin Nav Menus class instance 133 | * 134 | * @var string 135 | * @since 0.3.0 136 | */ 137 | protected $admin = ''; 138 | 139 | /** 140 | * Options class instance 141 | * 142 | * @var string 143 | * @since 0.3.0 144 | */ 145 | protected $options = ''; 146 | 147 | /** 148 | * Default svg-defs.svg path 149 | * 150 | * @var string 151 | * @since 0.3.0 152 | */ 153 | protected $svg_defs = ''; 154 | 155 | /** 156 | * Default /svg assets path 157 | * 158 | * @var string 159 | * @since 0.3.0 160 | */ 161 | protected $svg = ''; 162 | 163 | /** 164 | * Singleton instance of plugin. 165 | * 166 | * @var WDS_Mega_Menus 167 | * @since 0.1.0 168 | */ 169 | protected static $single_instance = null; 170 | 171 | /** 172 | * Creates or returns an instance of this class. 173 | * 174 | * @since 0.1.0 175 | * @return WDS_Mega_Menus A single instance of this class. 176 | */ 177 | public static function get_instance() { 178 | if ( null === self::$single_instance ) { 179 | self::$single_instance = new self(); 180 | } 181 | 182 | return self::$single_instance; 183 | } 184 | 185 | /** 186 | * Sets up our plugin 187 | * 188 | * @since 0.1.0 189 | */ 190 | protected function __construct() { 191 | $this->basename = plugin_basename( __FILE__ ); 192 | $this->url = plugin_dir_url( __FILE__ ); 193 | $this->path = plugin_dir_path( __FILE__ ); 194 | $this->svg_defs = $this->path . '/assets/svg-defs.svg'; 195 | $this->svg = $this->path . '/assets/svg/'; 196 | 197 | require $this->path . 'includes/class-menu-walker.php'; 198 | require $this->path . 'includes/class-walker-nav-menu-edit.php'; 199 | require $this->path . 'includes/class-menu-admin.php'; 200 | require $this->path . 'includes/class-options.php'; 201 | } 202 | 203 | /** 204 | * Attach other plugin classes to the base plugin class. 205 | * 206 | * @since 0.2.0 207 | * @author Chris Reynolds 208 | */ 209 | public function plugin_classes() { 210 | // Attach other plugin classes to the base plugin class. 211 | $this->admin = new WDS_Mega_Menus_Admin(); 212 | $this->options = new WDS_Mega_Menus_Options( $this ); 213 | } // END OF PLUGIN CLASSES FUNCTION 214 | 215 | /** 216 | * Add hooks and filters 217 | * 218 | * @since 0.3.0 219 | * @author Chris Reynolds 220 | */ 221 | public function hooks() { 222 | add_action( 'init', array( $this, 'init' ) ); 223 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_user_styles' ) ); 224 | } 225 | 226 | /** 227 | * Activate the plugin 228 | * 229 | * @since 0.3.0 230 | * @author Chris Reynolds 231 | */ 232 | public function _activate() { 233 | // Make sure any rewrite functionality has been loaded. 234 | flush_rewrite_rules(); 235 | } 236 | 237 | /** 238 | * Deactivate the plugin 239 | * Uninstall routines should be in uninstall.php 240 | * 241 | * @since 0.3.0 242 | * @author Chris Reynolds 243 | */ 244 | public function _deactivate() {} 245 | 246 | 247 | /** 248 | * Init hooks 249 | * 250 | * @since 0.3.0 251 | * @author Chris Reynolds 252 | */ 253 | public function init() { 254 | if ( $this->check_requirements() ) { 255 | load_plugin_textdomain( 'wds-mega-menus', false, dirname( $this->basename ) . '/languages/' ); 256 | $this->plugin_classes(); 257 | $this->update_svg_paths(); 258 | } 259 | } 260 | 261 | /** 262 | * Check if the plugin meets requirements and 263 | * disable it if they are not present. 264 | * 265 | * @since 0.3.0 266 | * @author Chris Reynolds 267 | * 268 | * @return boolean result of meets_requirements 269 | */ 270 | public function check_requirements() { 271 | if ( ! $this->meets_requirements() ) { 272 | 273 | // Add a dashboard notice. 274 | add_action( 'all_admin_notices', array( $this, 'requirements_not_met_notice' ) ); 275 | 276 | // Deactivate our plugin. 277 | add_action( 'admin_init', array( $this, 'deactivate_me' ) ); 278 | 279 | return false; 280 | } 281 | 282 | return true; 283 | } 284 | 285 | /** 286 | * Deactivates this plugin, hook this function on admin_init. 287 | * 288 | * @since 0.3.0 289 | * @author Chris Reynolds 290 | */ 291 | public function deactivate_me() { 292 | deactivate_plugins( $this->basename ); 293 | } 294 | 295 | /** 296 | * Check that all plugin requirements are met 297 | * 298 | * @since 0.3.0 299 | * @author Chris Reynolds 300 | * 301 | * @return boolean True if requirements are met. 302 | */ 303 | public static function meets_requirements() { 304 | // Do checks for required classes / functions 305 | // function_exists('') & class_exists(''). 306 | // We have met all requirements. 307 | return true; 308 | } 309 | 310 | /** 311 | * Adds a notice to the dashboard if the plugin requirements are not met 312 | * 313 | * @since 0.3.0 314 | * @author Chris Reynolds 315 | */ 316 | public function requirements_not_met_notice() { 317 | // Output our error. 318 | echo '
    '; 319 | echo '

    ' . sprintf( __( 'WDS Mega Menus is missing requirements and has been deactivated. Please make sure all requirements are available.', 'wds-mega-menus' ), admin_url( 'plugins.php' ) ) . '

    '; 320 | echo '
    '; 321 | } 322 | 323 | /** 324 | * Update SVG paths. 325 | * 326 | * Updates the default $this->svg_defs and $this->svg paths if the theme has svgs. 327 | * 328 | * @since 0.2.0 329 | * @author Chris Reynolds 330 | */ 331 | public function update_svg_paths() { 332 | if ( $this->have_svgs() ) { 333 | /** 334 | * SVG Defs Path 335 | * 336 | * @since 0.2.0 337 | * @author Chris Reynolds 338 | * @var string wdsmm_svg_defs_path 339 | */ 340 | $this->svg_defs = apply_filters( 'wdsmm_svg_defs_path', get_stylesheet_directory() . '/assets/svg-defs.svg' ); 341 | 342 | /** 343 | * SVGs Directory 344 | * 345 | * Filter the directory path to the SVGs folder. Defaults to the current child theme in the /assets/svg folder. 346 | * 347 | * @var string wdsmm_svgs_directory 348 | * @since 0.2.0 349 | */ 350 | $this->svg = apply_filters( 'wdsmm_svgs_directory', get_stylesheet_directory() . '/assets/svg/' ); 351 | } 352 | } 353 | 354 | /** 355 | * Check if we already have an svgs folder. 356 | * 357 | * @since 0.2.0 358 | * @author Chris Reynolds 359 | * 360 | * @return bool Whether we already have our own svgs directory. Checks the theme by default. 361 | */ 362 | public function have_svgs() { 363 | /** 364 | * SVGs Directory 365 | * 366 | * Filter the directory path to the SVGs folder. Defaults to /assets/svg in the current child theme folder. 367 | * 368 | * @var string wdsmm_svgs_directory 369 | * @since 0.2.0 370 | */ 371 | $svgs_directory = apply_filters( 'wdsmm_svgs_directory', get_stylesheet_directory() . '/assets/svg' ); 372 | return file_exists( $svgs_directory ); 373 | } 374 | 375 | /** 376 | * Include a file from the includes directory 377 | * 378 | * @since 0.3.0 379 | * @author Chris Reynolds 380 | * 381 | * @param string $filename Name of the file to be included. 382 | * @return bool Result of include call. 383 | */ 384 | public static function include_file( $filename ) { 385 | $file = self::dir( 'includes/class-'. $filename .'.php' ); 386 | if ( file_exists( $file ) ) { 387 | return include_once( $file ); 388 | } 389 | return false; 390 | } 391 | 392 | /** 393 | * Magic getter for our object. 394 | * 395 | * @since 0.1.0 396 | * 397 | * @param string $field The field we're trying to fetch. 398 | * @throws Exception Throws an exception if the field is invalid. 399 | * @return mixed 400 | */ 401 | public function __get( $field ) { 402 | switch ( $field ) { 403 | case 'version': 404 | return self::VERSION; 405 | case 'basename': 406 | case 'url': 407 | case 'path': 408 | case 'svg_defs': 409 | case 'svg': 410 | case 'options': 411 | case 'admin': 412 | return $this->$field; 413 | default: 414 | throw new Exception( 'Invalid '. __CLASS__ .' property: ' . $field ); 415 | } 416 | } 417 | 418 | /** 419 | * This plugin's directory 420 | * 421 | * @since 0.3.0 422 | * @author Chris Reynolds 423 | * 424 | * @param string $path (optional) appended path. 425 | * @return string Directory and path 426 | */ 427 | public static function dir( $path = '' ) { 428 | static $dir; 429 | $dir = $dir ? $dir : trailingslashit( dirname( __FILE__ ) ); 430 | return $dir . $path; 431 | } 432 | 433 | /** 434 | * This plugin's url 435 | * 436 | * @since 0.3.0 437 | * @author Chris Reynolds 438 | * 439 | * @param string $path (optional) appended path. 440 | * @return string URL and path 441 | */ 442 | public static function url( $path = '' ) { 443 | static $url; 444 | $url = $url ? $url : trailingslashit( plugin_dir_url( __FILE__ ) ); 445 | return $url . $path; 446 | } 447 | 448 | /** 449 | * Enqueue front-end styles 450 | * 451 | * @since 0.3.0 452 | * @author Pavel Korotenko 453 | */ 454 | public function enqueue_user_styles() { 455 | wp_enqueue_style( 'wdsmm-user', wds_mega_menus()->url . 'assets/css/user.css', array(), wds_mega_menus()->version ); 456 | } 457 | } // class WDS_Mega_Menus 458 | 459 | /** 460 | * Grab the WDS_Mega_Menus object and return it. 461 | * 462 | * Wrapper for WDS_Mega_Menus::get_instance() 463 | * 464 | * @since 0.1.0 465 | * @return WDS_Mega_Menus Singleton instance of plugin class. 466 | */ 467 | function wds_mega_menus() { 468 | return WDS_Mega_Menus::get_instance(); 469 | } 470 | 471 | // Kick it off. 472 | add_action( 'plugins_loaded', array( wds_mega_menus(), 'hooks' ) ); 473 | 474 | register_activation_hook( __FILE__, array( wds_mega_menus(), '_activate' ) ); 475 | register_deactivation_hook( __FILE__, array( wds_mega_menus(), '_deactivate' ) ); 476 | 477 | --------------------------------------------------------------------------------