Kirki - Version 1.0.0

Version Description

July 11, 2014, dev time: 177 hours

  • NEW: Added PHPUnit tests
  • NEW: Use wp_add_inline_style to add customizer styles
  • NEW: Rebuilt the background fields calculation
  • NEW: Now using Formstone for switches & toggles
  • NEW: Added a new API. See https://github.com/aristath/kirki/wiki for documentation.
  • NEW: Minimum PHP requirement is now PHP 5.2
  • NEW: Added a Select2 field type.
  • NEW: Introducing the Kirki::get_option() method to get values.
  • NEW: added 'media_query' argument to output.
  • NEW: Added ability to get variables for CSS preprocessors from the customizer values. See https://github.com/aristath/kirki/wiki/variables for documentation
  • NEW: now supporting 'units' to all outputs to support '!important'
  • NEW: Ability to create panels & sections using the new API.
  • NEW: added a get_posts method to the Kirki class.
  • NEW: Implement width argument in the styling options. See https://github.com/aristath/kirki/wiki/Styling-the-Customizer
  • NEW: add 'kirki/control_types' filter
  • FIX: Properly saving values in the db when using serialized options
  • FIX: Check if classes & functions exist before adding them (allows for better compatibility when embedded in a theme)
  • FIX: PHP Warnings & Notices
  • FIX: Other minor bugfixes
  • FIX: Now using consistently option_type instead of options_type everywhere
  • FIX: Kirki::get_option() method now works for all fields, including background fields.
  • FIX: avoid errors when Color is undefined in background fields
  • FIX: Use WP_Filesystem to get the google fonts array from a json file
  • FIX: Radio-Button styling
  • FIX: PHP Notices
  • FIX: Typos
  • FIX: Properly sanitizing rgba colors
  • FIX: Properly sanitize numbers
  • FIX: Make sure all variables are escaped on output
  • TWEAK: Simplify the Colourlovers integration.
  • TWEAK: Improve sanitization
  • TWEAK: Improve the Kirki_Styles_Customizer class
  • TWEAK: Code cleanups
  • TWEAK: Added more inline docs (lots of them)
  • TWEAK: Use active_callback for required arguments instead of custom JS
  • TWEAK: Updated translation files
  • TWEAK: Better color manipulation in the Kirki_Color class
  • TWEAK: Move secondary classes instantiation to the Kirki() function.
  • TWEAK: set a $kirki global
  • TWEAK: deprecate getOrThrow method in the Kirki_Config class.
  • TWEAK: Move sanitisation functions to a Kirki_Sanitize class.
  • TWEAK: Rename Kirki_Framework to Kirki_Toolkit.
  • TWEAK: Move variables to the new API
  • TWEAK: simplify Kirki_Controls class
  • TWEAK: move the kirki/fields & kirki/controls filters to the new API
  • REMOVED: remove the 'stylesheet_id' from the configuration.
Download this release

Release Info

Developer aristath
Plugin Icon 128x128 Kirki
Version 1.0.0
Comparing to
See all releases

Code changes from version 0.8.4 to 1.0.0

Files changed (156) hide show
  1. .codeclimate.yml +10 -0
  2. .coveralls.yml +3 -0
  3. .editorconfig +25 -0
  4. .gitignore +18 -0
  5. .simplecov +7 -0
  6. .travis.yml +40 -0
  7. Gruntfile.js +22 -0
  8. README.md +61 -0
  9. assets/css/customizer-dynamic-css-colors.css +107 -0
  10. assets/css/customizer-dynamic-css-width.css +7 -0
  11. assets/css/customizer-dynamic-css.css +57 -0
  12. assets/css/customizer.css +8 -342
  13. assets/css/customizer.scss +11 -392
  14. assets/css/jquery-ui-1.10.0.custom.css +0 -0
  15. assets/css/select2.min.css +1 -0
  16. assets/js/customizer.js +0 -215
  17. assets/js/jquery.fs.stepper.min.js +0 -9
  18. assets/js/kirki-tooltip.js +4 -0
  19. assets/js/select2.full.min.js +3 -0
  20. bin/install-wp-tests.sh +98 -0
  21. composer.json +23 -19
  22. includes/Builder.php +0 -48
  23. includes/Config.php +0 -138
  24. includes/Controls.php +0 -124
  25. includes/Controls/ColorAlphaControl.php +0 -28
  26. includes/Controls/CustomControl.php +0 -38
  27. includes/Controls/EditorControl.php +0 -39
  28. includes/Controls/MultiCheckControl.php +0 -84
  29. includes/Controls/NumberControl.php +0 -25
  30. includes/Controls/RadioButtonSetControl.php +0 -48
  31. includes/Controls/RadioImageControl.php +0 -48
  32. includes/Controls/SliderControl.php +0 -50
  33. includes/Controls/SwitchControl.php +0 -39
  34. includes/Controls/ToggleControl.php +0 -35
  35. includes/Fields.php +0 -585
  36. includes/Helpers/deprecated.php +0 -79
  37. includes/Helpers/helpers.php +0 -129
  38. includes/Helpers/libraries/class-kirki-color.php +0 -475
  39. includes/Helpers/libraries/class-kirki-colourlovers.php +0 -189
  40. includes/Helpers/sanitize.php +0 -134
  41. includes/Kirki.php +0 -99
  42. includes/Scripts/Customizer/Branding.php +0 -42
  43. includes/Scripts/Customizer/Dependencies.php +0 -33
  44. includes/Scripts/Customizer/PostMessage.php +0 -72
  45. includes/Scripts/Customizer/Required.php +0 -136
  46. includes/Scripts/Customizer/Stepper.php +0 -47
  47. includes/Scripts/Customizer/Tooltips.php +0 -51
  48. includes/Scripts/EnqueueScript.php +0 -22
  49. includes/Scripts/Frontend/GoogleFonts.php +0 -110
  50. includes/Scripts/ScriptRegistry.php +0 -31
  51. includes/Settings.php +0 -40
  52. includes/Styles.php +0 -16
  53. includes/Styles/Customizer.php +0 -96
  54. includes/Styles/Frontend.php +0 -239
  55. includes/class-kirki-color.php +338 -0
  56. includes/class-kirki-colourlovers.php +72 -0
  57. includes/class-kirki-explode-background-field.php +174 -0
  58. includes/class-kirki-field.php +714 -0
  59. includes/{Fonts/FontRegistry.php → class-kirki-fonts-font-registry.php} +81 -57
  60. includes/class-kirki-helper.php +94 -0
  61. includes/class-kirki-output.php +258 -0
  62. includes/class-kirki-sanitize.php +150 -0
  63. includes/class-kirki-scripts-customizer-branding.php +63 -0
  64. includes/class-kirki-scripts-customizer-default-scripts.php +50 -0
  65. includes/class-kirki-scripts-customizer-postmessage.php +73 -0
  66. includes/class-kirki-scripts-customizer-tooltips.php +73 -0
  67. includes/class-kirki-scripts-enqueue-script.php +60 -0
  68. includes/class-kirki-scripts-frontend-google-fonts.php +130 -0
  69. includes/class-kirki-scripts-registry.php +48 -0
  70. includes/class-kirki-styles-customizer.php +182 -0
  71. includes/class-kirki-styles-frontend.php +86 -0
  72. includes/class-kirki-toolkit.php +117 -0
  73. includes/class-kirki.php +508 -0
  74. includes/controls/color-alpha/class-kirki-controls-color-alpha-control.php +55 -0
  75. includes/controls/color-alpha/script.js +96 -0
  76. includes/controls/color-alpha/style.css +45 -0
  77. includes/controls/color-alpha/style.css.map +7 -0
  78. includes/controls/color-alpha/style.scss +52 -0
  79. {assets/images → includes/controls/color-alpha}/transparency-grid.png +0 -0
  80. includes/controls/custom/class-kirki-controls-custom-control.php +53 -0
  81. includes/controls/editor/class-kirki-controls-editor-control.php +57 -0
  82. includes/controls/editor/kirki-editor.js +55 -0
  83. includes/controls/multicheck/class-kirki-controls-multicheck-control.php +66 -0
  84. includes/controls/multicheck/kirki-multicheck.js +8 -0
  85. includes/controls/multicheck/style.css +46 -0
  86. includes/controls/multicheck/style.css.map +7 -0
  87. includes/controls/multicheck/style.scss +54 -0
  88. includes/controls/number/class-kirki-controls-number-control.php +69 -0
  89. includes/controls/number/formstone-core.js +3 -0
  90. includes/controls/number/formstone-number.js +3 -0
  91. includes/controls/number/style.css +88 -0
  92. includes/controls/number/style.css.map +7 -0
  93. includes/controls/number/style.scss +109 -0
  94. includes/{Controls/PaletteControl.php → controls/palette/class-kirki-controls-palette-control.php} +27 -12
  95. includes/controls/palette/style.css +31 -0
  96. includes/controls/palette/style.css.map +7 -0
  97. includes/controls/palette/style.scss +43 -0
  98. includes/controls/radio-buttonset/class-kirki-controls-radio-buttonset-control.php +61 -0
  99. includes/controls/radio-buttonset/style.css +14 -0
  100. includes/controls/radio-buttonset/style.css.map +7 -0
  101. includes/controls/radio-buttonset/style.scss +22 -0
  102. includes/controls/radio-image/class-kirki-controls-radio-image-control.php +60 -0
  103. includes/controls/radio-image/style.css +12 -0
  104. includes/controls/radio-image/style.css.map +7 -0
  105. includes/controls/radio-image/style.scss +18 -0
  106. includes/controls/select2-multiple/class-kirki-controls-select2-multiple-control.php +65 -0
  107. includes/controls/select2/class-kirki-controls-select2-control.php +65 -0
  108. includes/controls/slider/class-kirki-controls-slider-control.php +75 -0
  109. includes/controls/slider/style.css +38 -0
  110. includes/controls/slider/style.css.map +7 -0
  111. includes/controls/slider/style.scss +43 -0
  112. includes/{Controls/SortableControl.php → controls/sortable/class-kirki-controls-sortable-control.php} +38 -18
  113. includes/controls/sortable/kirki-sortable.js +45 -0
  114. includes/controls/sortable/style.css +15 -0
  115. includes/controls/sortable/style.css.map +7 -0
  116. includes/controls/sortable/style.scss +25 -0
  117. includes/controls/switch/class-kirki-controls-switch-control.php +61 -0
  118. includes/controls/switch/formstone-checkbox.js +3 -0
  119. includes/controls/switch/formstone-core.js +3 -0
  120. includes/controls/switch/formstone-touch.js +3 -0
  121. includes/controls/switch/style.css +189 -0
  122. includes/controls/switch/style.css.map +7 -0
  123. includes/controls/switch/style.scss +267 -0
  124. includes/controls/toggle/class-kirki-controls-toggle-control.php +51 -0
  125. includes/controls/toggle/formstone-checkbox.js +3 -0
  126. includes/controls/toggle/formstone-core.js +3 -0
  127. includes/controls/toggle/formstone-touch.js +3 -0
  128. includes/controls/toggle/style.css +190 -0
  129. includes/controls/toggle/style.css.map +7 -0
  130. includes/controls/toggle/style.scss +268 -0
  131. includes/deprecated.php +205 -0
  132. includes/functions.php +97 -0
  133. includes/redux-compatibility.php +199 -0
  134. kirki-user-tests.php +153 -0
  135. kirki.php +116 -18
  136. languages/kirki-en_US.mo +0 -0
  137. languages/kirki-en_US.po +331 -49
  138. package.json +24 -0
  139. phpunit.xml +18 -0
  140. readme.txt +164 -110
  141. sample-config.php +594 -0
  142. tests/test-bootstrap.php +15 -0
  143. tests/test-deprecated.php +55 -0
  144. tests/test-kirki-color.php +188 -0
  145. tests/test-kirki-explode-background-field.php +222 -0
  146. tests/test-kirki-field.php +386 -0
  147. tests/test-kirki-functions.php +18 -0
  148. tests/test-kirki-output.php +195 -0
  149. tests/test-kirki-scripts-customizer-branding.php +35 -0
  150. tests/test-kirki-scripts-customizer-postmessage.php +44 -0
  151. tests/test-kirki-scripts-customizer-tooltips.php +29 -0
  152. tests/test-kirki-scripts-frontend-google-fonts.php +152 -0
  153. tests/test-kirki-styles-customizer.php +26 -0
  154. tests/test-kirki-toolkit.php +32 -0
  155. tests/test-kirki.php +320 -0
  156. tests/test-textdomain.php +12 -0
.codeclimate.yml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ languages:
2
+ Ruby: false
3
+ JavaScript: true
4
+ PHP: true
5
+ exclude_paths:
6
+ - "assets/*"
7
+ - "sample-config.php"
8
+ - "kirki-user-tests.php"
9
+ - "tests/*"
10
+ - "bin/*"
.coveralls.yml ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ coverage_clover: build/logs/clover.xml
2
+ service_name: travis-ci
3
+ src_dir: .
.editorconfig ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is for unifying the coding style for different editors and IDEs
2
+ # editorconfig.org
3
+
4
+ # WordPress Coding Standards
5
+ # http://make.wordpress.org/core/handbook/coding-standards/
6
+
7
+ root = true
8
+
9
+ [*]
10
+ charset = utf-8
11
+ end_of_line = lf
12
+ insert_final_newline = true
13
+ trim_trailing_whitespace = true
14
+ indent_style = tab
15
+
16
+ [*.json]
17
+ indent_style = space
18
+ indent_size = 2
19
+
20
+ [*.css]
21
+ indent_style = space
22
+ indent_size = 2
23
+
24
+ [*.txt]
25
+ end_of_line = crlf
.gitignore ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # npm #
2
+ #######
3
+ node_modules
4
+ npm-debug.log
5
+
6
+ # grunt-contrib-sass #
7
+ ######################
8
+ .sass-cache
9
+
10
+ # OS generated files #
11
+ ######################
12
+ .DS_Store
13
+ .DS_Store?
14
+ ._*
15
+ .Spotlight-V100
16
+ .Trashes
17
+ ehthumbs.db
18
+ Thumbs.db
.simplecov ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
+ SimpleCov.start do
6
+ add_filter "/test/"
7
+ end
.travis.yml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ sudo: false
4
+
5
+ notifications:
6
+ on_success: never
7
+ on_failure: change
8
+
9
+ php:
10
+ - 5.3
11
+ - 5.4
12
+ - 5.5
13
+ - 5.6
14
+ - hhvm
15
+ - nightly
16
+
17
+ env:
18
+ - WP_VERSION=latest WP_MULTISITE=0
19
+
20
+ matrix:
21
+ include:
22
+ - php: 5.3
23
+ env: WP_VERSION=latest WP_MULTISITE=1
24
+
25
+ before_script:
26
+ - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
27
+ - curl -s http://getcomposer.org/installer | php
28
+ - php composer.phar install --dev --no-interaction
29
+
30
+ script:
31
+ - mkdir -p build/logs
32
+ - phpunit --coverage-clover build/logs/clover.xml
33
+ - find . \( -name '*kirki*.php' \) -exec php -lf {} \;
34
+
35
+ after_script:
36
+ - php vendor/bin/coveralls -v
37
+
38
+ after_success:
39
+ - coveralls
40
+ - bash <(curl -s https://codecov.io/bash)
Gruntfile.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+ module.exports = function(grunt) {
3
+
4
+ grunt.initConfig({
5
+ sass: {
6
+ dist: {
7
+ files: [{
8
+ expand: true,
9
+ cwd: 'includes/controls/',
10
+ src: ['**/*.scss'],
11
+ dest: 'includes/controls/',
12
+ ext: '.css'
13
+ }]
14
+ }
15
+ }
16
+ });
17
+
18
+ grunt.loadNpmTasks('grunt-contrib-sass');
19
+
20
+ grunt.registerTask('default', ['sass']);
21
+
22
+ };
README.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [Kirki](http://kirki.org) #
2
+
3
+ [![Build Status](https://travis-ci.org/reduxframework/kirki.svg?branch=master)](https://travis-ci.org/reduxframework/kirki) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/reduxframework/kirki/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/reduxframework/kirki/?branch=master) [![Code Climate](https://codeclimate.com/github/aristath/kirki/badges/gpa.svg)](https://codeclimate.com/github/aristath/kirki) [![Coverage Status](https://coveralls.io/repos/reduxframework/kirki/badge.svg?branch=master)](https://coveralls.io/r/reduxframework/kirki?branch=master) [![License](https://img.shields.io/badge/license-GPL--2.0%2B-red.svg)](https://raw.githubusercontent.com/reduxframework/kirki/master/LICENSE)
4
+
5
+ ## The Kirki Toolkit
6
+
7
+ Kirki allows developers to add advanced controls to their customizer as well as customize the way the customizer looks and feels.
8
+
9
+ You can add beautiful options to your theme's customizer panel and allow your users to tweak any aspect of their theme.
10
+ You've got 23 control types that you can use, [styling options for the customizer](https://github.com/reduxframework/kirki/wiki/Styling-the-Customizer), as well as [automatic calculations for your styles](https://github.com/reduxframework/kirki/wiki/output) using the `output` argument on your controls.
11
+
12
+ You can use the default WordPress customizer syntax or one of the 2 alternative syntaxes that we have provided for you. Each project has different needs and we understand that, so the choice is up to you.
13
+
14
+ Converting from the default customizer to the syntax used by Kirki will only take a few minutes and will save you a lot of time in the long run. :)
15
+
16
+ The following controls are included in the Kirki Toolkit:
17
+
18
+ * checkbox
19
+ * color-alpha
20
+ * color
21
+ * custom
22
+ * dropdown-pages
23
+ * editor
24
+ * image
25
+ * multicheck
26
+ * number
27
+ * palette
28
+ * radio-buttonset
29
+ * radio-image
30
+ * radio
31
+ * select
32
+ * select2
33
+ * select2-multiple
34
+ * slider
35
+ * sortable
36
+ * switch
37
+ * text
38
+ * textarea
39
+ * toggle
40
+ * upload
41
+
42
+ For documentation and examples on how to use these controls, please visit [kirki.org](http://kirki.org/#fields).
43
+
44
+
45
+ ## Installation
46
+
47
+ ### Method 1: Use as a plugin
48
+ From your dashboard go to Plugins => Add New.
49
+ Search for "Kirki" and install it.
50
+ Once you install it, activate it.
51
+ For configuration instructions please visit [the wiki](https://github.com/reduxframework/kirki/wiki)
52
+
53
+ ### Method 2: Embed in your theme
54
+ Please visit [the wiki page](https://github.com/reduxframework/kirki/wiki/Embedding-in-a-theme) for documentation and instructions.
55
+
56
+
57
+ ### Sample data
58
+
59
+ The 2 last lines on the [kirki.php](https://github.com/reduxframework/kirki/blob/master/kirki.php) file are commented-out but if you uncomment them you will see your customizer flood with dummy controls.
60
+
61
+ [Changelog](https://github.com/aristath/kirki/wiki/Changelog)
assets/css/customizer-dynamic-css-colors.css ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** Generic background color **/
2
+ .wp-full-overlay-sidebar {
3
+ background: COLOR_BACK;
4
+ }
5
+
6
+ /** Title background color **/
7
+ #customize-controls .customize-info .accordion-section-title,
8
+ #customize-controls .panel-meta.customize-info .accordion-section-title:hover {
9
+ background: COLOR_BACK
10
+ }
11
+
12
+ /** Borders **/
13
+ #customize-controls .customize-info {
14
+ border-top-color: BORDER_COLOR;
15
+ border-bottom-color: BORDER_COLOR;
16
+ }
17
+
18
+ .customize-section-title {
19
+ border-bottom-color: BORDER_COLOR;
20
+ }
21
+
22
+ .customize-panel-back,
23
+ .customize-section-back {
24
+ border-right-color:BORDER_COLOR;
25
+ }
26
+
27
+ #customize-header-actions {
28
+ border-bottom-color: BORDER_COLOR;
29
+ }
30
+
31
+ .customize-controls-close,
32
+ .customize-overlay-close {
33
+ border-right-color: BORDER_COLOR !important;
34
+ }
35
+
36
+ /** back & close buttons color **/
37
+ .customize-panel-back:focus,
38
+ .customize-panel-back:hover,
39
+ .customize-section-back:focus,
40
+ .customize-section-back:hover,
41
+ .customize-panel-back,
42
+ .customize-section-back,
43
+ .customize-controls-close,
44
+ .customize-overlay-close {
45
+ background: BUTTONS_COLOR;
46
+ }
47
+
48
+ .control-panel-back:focus,
49
+ .control-panel-back:hover,
50
+ .customize-controls-close:focus,
51
+ .customize-controls-close:hover,
52
+ .customize-controls-preview-toggle:focus,
53
+ .customize-controls-preview-toggle:hover,
54
+ .customize-overlay-close:focus,
55
+ .customize-overlay-close:hover {
56
+ background: BUTTONS_COLOR
57
+ }
58
+
59
+ /** Sections list titles **/
60
+ #customize-theme-controls .accordion-section-title {
61
+ background: COLOR_BACK;
62
+ color: COLOR_FONT;
63
+ }
64
+
65
+ #customize-controls .control-section .accordion-section-title:focus,
66
+ #customize-controls .control-section .accordion-section-title:hover,
67
+ #customize-controls .control-section.open .accordion-section-title,
68
+ #customize-controls .control-section:hover>.accordion-section-title {
69
+ background: COLOR_ACCENT;
70
+ color: CONTROLS_COLOR;
71
+ }
72
+
73
+ /** Arrows **/
74
+ .accordion-section-title:after,
75
+ .handlediv,
76
+ .item-edit,
77
+ .sidebar-name-arrow,
78
+ .widget-action {
79
+ color: ARROWS_COLOR;
80
+ }
81
+
82
+ #customize-theme-controls .control-section .accordion-section-title:focus:after,
83
+ #customize-theme-controls .control-section .accordion-section-title:hover:after,
84
+ #customize-theme-controls .control-section.open .accordion-section-title:after,
85
+ #customize-theme-controls .control-section:hover>.accordion-section-title:after {
86
+ color: COLOR_ACCENT_TEXT
87
+ }
88
+
89
+ /** Title for active section **/
90
+ .customize-section-title {
91
+ background: COLOR_BACK;
92
+ }
93
+
94
+ .customize-section-title h3,
95
+ h3.customize-section-title {
96
+ color: COLOR_FONT;
97
+ }
98
+
99
+ /** Active section background **/
100
+ #customize-theme-controls .accordion-section-content {
101
+ background: SECTION_BACKGROUND_COLOR;
102
+ }
103
+
104
+ /** Title color for active panels etc **/
105
+ #customize-controls .customize-info .preview-notice {
106
+ color: COLOR_FONT;
107
+ }
assets/css/customizer-dynamic-css-width.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ .wp-full-overlay-sidebar {
2
+ width: WIDTH;
3
+ }
4
+
5
+ .wp-full-overlay.expanded {
6
+ margin-left: WIDTH;
7
+ }
assets/css/customizer-dynamic-css.css ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** Button styles **/
2
+ .wp-core-ui .button-primary-disabled,
3
+ .wp-core-ui .button-primary.disabled,
4
+ .wp-core-ui .button-primary:disabled,
5
+ .wp-core-ui .button-primary[disabled] {
6
+ background: COLOR_ACCENT !important;
7
+ color: COLOR_ACCENT_TEXT !important;
8
+ border-color: rgba(0,0,0,.1) !important;
9
+ opacity: .7;
10
+ }
11
+
12
+ .wp-core-ui .button-primary {
13
+ background-color: COLOR_ACCENT;
14
+ color: COLOR_ACCENT_TEXT;
15
+ opacity: 1;
16
+ }
17
+
18
+ /** Tooltip styles **/
19
+ #customize-controls .customize-info .customize-help-toggle {
20
+ color: COLOR_ACCENT;
21
+ }
22
+
23
+ /** Image-Radio styles **/
24
+ .customize-control-radio-image .image.ui-buttonset label.ui-state-active {
25
+ border: 2px solid COLOR_ACCENT
26
+ }
27
+
28
+ /** Radio-Buttonset styles **/
29
+ .customize-control-radio-buttonset label.ui-state-active {
30
+ background-color: COLOR_ACCENT;
31
+ color: COLOR_ACCENT_TEXT;
32
+ }
33
+
34
+ /** Slider Controls **/
35
+ .customize-control-slider .ui-slider .ui-slider-handle {
36
+ background-color: COLOR_ACCENT;
37
+ }
38
+
39
+ /** Switch Controls **/
40
+ .customize-control-switch .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag {
41
+ background: COLOR_ACCENT;
42
+ }
43
+
44
+ /** Toggle Controls **/
45
+ .customize-control-toggle .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag {
46
+ background: COLOR_ACCENT;
47
+ }
48
+
49
+ /** Sortable Controls **/
50
+ .customize-control-sortable ul.ui-sortable li .dashicons.visibility {
51
+ color: COLOR_ACCENT;
52
+ }
53
+
54
+ /** Palette Controls **/
55
+ .customize-control-palette label.ui-state-active.ui-button.ui-widget span.ui-button-text {
56
+ border-color: COLOR_ACCENT;
57
+ }
assets/css/customizer.css CHANGED
@@ -73,7 +73,7 @@ li.customize-control {
73
  display: block;
74
  position: absolute;
75
  top: 5px;
76
- right: -20px;
77
  border-radius: 50%;
78
  color: #999;
79
  border: none;
@@ -81,344 +81,10 @@ li.customize-control {
81
  width: 20px;
82
  height: 20px; }
83
 
84
- .customize-control-radio-image .image.ui-buttonset input[type=radio] {
85
- height: auto; }
86
- .customize-control-radio-image .image.ui-buttonset label {
87
- border: 1px solid transparent;
88
- display: inline-block;
89
- margin-right: 5px;
90
- margin-bottom: 5px; }
91
- .customize-control-radio-image .image.ui-buttonset label.ui-state-active {
92
- background: none;
93
- border-color: #333; }
94
-
95
- .customize-control-multicheck input[type="checkbox"] {
96
- position: relative;
97
- margin: 0 1rem 0 0;
98
- cursor: pointer;
99
- margin-bottom: 5px;
100
- width: 22px;
101
- height: 22px; }
102
- .customize-control-multicheck input[type="checkbox"]:before {
103
- content: "";
104
- position: absolute;
105
- left: 0;
106
- z-index: 1;
107
- width: 100%;
108
- height: 100%;
109
- border: none; }
110
- .customize-control-multicheck input[type="checkbox"]:after {
111
- content: "";
112
- position: absolute;
113
- left: 0;
114
- top: 0;
115
- width: 100%;
116
- height: 100%;
117
- background: #fff;
118
- cursor: pointer; }
119
- .customize-control-multicheck input[type="checkbox"]:checked:before {
120
- border: 4px solid #4caf50;
121
- -webkit-transform: rotate(-45deg);
122
- -moz-transform: rotate(-45deg);
123
- -ms-transform: rotate(-45deg);
124
- -o-transform: rotate(-45deg);
125
- transform: rotate(-45deg);
126
- width: 14px;
127
- height: 6px;
128
- top: 6px;
129
- left: 5px;
130
- border-top-style: none;
131
- border-right-style: none; }
132
- .customize-control-multicheck input[type="checkbox"]:checked:after {
133
- background: #f2f2f2; }
134
-
135
- .customize-control-checkbox input[type="checkbox"] {
136
- position: relative;
137
- margin: 0 1rem 0 0;
138
- cursor: pointer;
139
- margin-bottom: 5px;
140
- width: 22px;
141
- height: 22px; }
142
- .customize-control-checkbox input[type="checkbox"]:before {
143
- content: "";
144
- position: absolute;
145
- left: 0;
146
- z-index: 1;
147
- width: 100%;
148
- height: 100%;
149
- border: none; }
150
- .customize-control-checkbox input[type="checkbox"]:after {
151
- content: "";
152
- position: absolute;
153
- left: 0;
154
- top: 0;
155
- width: 100%;
156
- height: 100%;
157
- background: #fff;
158
- cursor: pointer; }
159
- .customize-control-checkbox input[type="checkbox"]:checked:before {
160
- border: 4px solid #4caf50;
161
- -webkit-transform: rotate(-45deg);
162
- -moz-transform: rotate(-45deg);
163
- -ms-transform: rotate(-45deg);
164
- -o-transform: rotate(-45deg);
165
- transform: rotate(-45deg);
166
- width: 14px;
167
- height: 6px;
168
- top: 6px;
169
- left: 5px;
170
- border-top-style: none;
171
- border-right-style: none; }
172
- .customize-control-checkbox input[type="checkbox"]:checked:after {
173
- background: #f2f2f2; }
174
-
175
- .customize-control-radio-buttonset label {
176
- padding: 5px 10px;
177
- background: #f7f7f7;
178
- border-left: 1px solid #dedede; }
179
- .customize-control-radio-buttonset label.ui-state-active {
180
- background: #dedede; }
181
- .customize-control-radio-buttonset label.ui-corner-left {
182
- border-radius: 3px 0 0 3px;
183
- border-left: 0; }
184
- .customize-control-radio-buttonset label.ui-corner-right {
185
- border-radius: 0 3px 3px 0; }
186
-
187
- .customize-control-switch .Switch,
188
- .customize-control-toggle .Switch {
189
- position: relative;
190
- display: inline-block;
191
- font-size: 16px;
192
- font-weight: bold;
193
- color: #aaa;
194
- height: 18px;
195
- line-height: 27px;
196
- padding: 6px;
197
- border: 1px solid #ccc;
198
- border: 1px solid rgba(0, 0, 0, 0.2);
199
- background: #f2f2f2;
200
- cursor: pointer;
201
- float: right;
202
- transition: all 0.15s ease-in-out; }
203
- .customize-control-switch .Switch .Toggle,
204
- .customize-control-toggle .Switch .Toggle {
205
- position: absolute;
206
- top: 1px;
207
- width: 37px;
208
- height: 25px;
209
- border: 1px solid #aaa;
210
- border: 1px solid rgba(0, 0, 0, 0.2);
211
- background: #fff;
212
- z-index: 989;
213
- transition: all 0.15s ease-in-out; }
214
- .customize-control-switch .Switch .On,
215
- .customize-control-switch .Switch .Off,
216
- .customize-control-toggle .Switch .On,
217
- .customize-control-toggle .Switch .Off {
218
- display: inline-block;
219
- width: 35px;
220
- position: relative;
221
- top: -5px; }
222
- .customize-control-switch .Switch .On,
223
- .customize-control-toggle .Switch .On {
224
- color: #333; }
225
- .customize-control-switch .Switch.On .Toggle,
226
- .customize-control-toggle .Switch.On .Toggle {
227
- left: 54%; }
228
- .customize-control-switch .Switch.Off .Toggle,
229
- .customize-control-toggle .Switch.Off .Toggle {
230
- left: 2%; }
231
- .customize-control-switch .Switch.Round,
232
- .customize-control-toggle .Switch.Round {
233
- padding: 0 20px;
234
- border-radius: 40px;
235
- margin-top: 5px; }
236
- .customize-control-switch .Switch.Round .Toggle,
237
- .customize-control-toggle .Switch.Round .Toggle {
238
- border-radius: 40px;
239
- width: 14px;
240
- height: 14px; }
241
- .customize-control-switch .Switch.Round.Off .Toggle,
242
- .customize-control-toggle .Switch.Round.Off .Toggle {
243
- left: 3%; }
244
- .customize-control-switch .Switch.Round.On,
245
- .customize-control-toggle .Switch.Round.On {
246
- color: #fff;
247
- background: #333; }
248
- .customize-control-switch .Switch.Round.On .Toggle,
249
- .customize-control-toggle .Switch.Round.On .Toggle {
250
- left: 58%; }
251
-
252
- body.IE7 .Switch {
253
- width: 78px; }
254
-
255
- body.IE7 .Switch.Round {
256
- width: 1px; }
257
-
258
- .customize-control-sortable ul.ui-sortable li {
259
- padding: 5px 10px;
260
- border: 1px solid #333;
261
- background: #fff; }
262
- .customize-control-sortable ul.ui-sortable li .dashicons.dashicons-menu {
263
- float: right; }
264
- .customize-control-sortable ul.ui-sortable li .dashicons.visibility {
265
- margin-right: 10px; }
266
- .customize-control-sortable ul.ui-sortable li.invisible {
267
- color: #aaa;
268
- border: 1px dashed #aaa; }
269
- .customize-control-sortable ul.ui-sortable li.invisible .dashicons.visibility {
270
- color: #aaa; }
271
-
272
- .customize-control-palette label.ui-button.ui-widget {
273
- width: 95%;
274
- background: none;
275
- padding: 0; }
276
- .customize-control-palette label.ui-button.ui-widget .ui-button-text {
277
- border-top: 3px solid transparent;
278
- border-bottom: 3px solid transparent;
279
- margin-bottom: 5px;
280
- display: flex; }
281
- .customize-control-palette label.ui-button.ui-widget .ui-button-text span {
282
- padding: 10px 0;
283
- flex-grow: 1;
284
- font-size: 0;
285
- line-height: 10px;
286
- color: transparent;
287
- -webkit-transition: all 200ms ease-in-out;
288
- -moz-transition: all 200ms ease-in-out;
289
- -ms-transition: all 200ms ease-in-out;
290
- -o-transition: all 200ms ease-in-out;
291
- transition: all 200ms ease-in-out; }
292
- .customize-control-palette label.ui-button.ui-widget .ui-button-text span:hover {
293
- padding: 10px;
294
- flex-grow: 3;
295
- min-width: 60px;
296
- font-size: 10px;
297
- line-height: 10px;
298
- color: #000; }
299
- .customize-control-palette label.ui-state-active.ui-button.ui-widget span.ui-button-text {
300
- border: 3px solid #333; }
301
-
302
- .customize-control-slider input[type="text"] {
303
- border: none;
304
- text-align: center;
305
- padding: 0;
306
- margin: 0;
307
- font-size: 12px;
308
- box-shadow: none;
309
- color: #333; }
310
- .customize-control-slider .ui-slider {
311
- position: relative;
312
- text-align: left;
313
- height: 7px;
314
- border-radius: 3px;
315
- background: #f2f2f2;
316
- border: 1px solid #dedede;
317
- margin-top: 10px;
318
- margin-bottom: 20px; }
319
- .customize-control-slider .ui-slider .ui-slider-handle {
320
- position: absolute;
321
- z-index: 2;
322
- width: 15px;
323
- height: 15px;
324
- top: -5px;
325
- border-radius: 50%;
326
- cursor: default;
327
- -ms-touch-action: none;
328
- touch-action: none;
329
- background: #333;
330
- border: 1px solid #333; }
331
- .customize-control-slider .ui-slider .ui-slider-range {
332
- position: absolute;
333
- z-index: 1;
334
- font-size: 0.7em;
335
- display: block;
336
- border: 0;
337
- background-position: 0 0; }
338
-
339
- .customize-control-color-alpha .kirki-alpha-container {
340
- box-sizing: padding-box;
341
- display: none;
342
- border: 1px solid #dfdfdf;
343
- border-top: none;
344
- background: #fff;
345
- padding: 0 11px 6px; }
346
- .customize-control-color-alpha .kirki-alpha-container .transparency {
347
- height: 24px;
348
- width: 100%;
349
- background-color: #fff;
350
- background-image: url("../images/transparency-grid.png");
351
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.4) inset;
352
- -webkit-border-radius: 3px;
353
- -moz-border-radius: 3px;
354
- border-radius: 3px;
355
- padding: 0; }
356
- .customize-control-color-alpha .kirki-alpha-container .ui-slider-handle {
357
- color: #777;
358
- background-color: #fff;
359
- text-shadow: 0 1px 0 #fff;
360
- text-decoration: none;
361
- position: absolute;
362
- z-index: 2;
363
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
364
- border: 1px solid #aaa;
365
- -webkit-border-radius: 4px;
366
- -moz-border-radius: 4px;
367
- border-radius: 4px;
368
- opacity: 0.9;
369
- margin-top: -2px;
370
- height: 20px;
371
- cursor: ew-resize;
372
- font-size: 12px;
373
- padding: 3px; }
374
- .customize-control-color-alpha .kirki-alpha-container .ui-slider {
375
- position: relative;
376
- text-align: center;
377
- width: 88%; }
378
- .customize-control-color-alpha .wp-picker-container a.wp-picker-open ~ div.kirki-alpha-container {
379
- display: block; }
380
- .customize-control-color-alpha .customize-control-alphacolor .wp-picker-container .iris-picker {
381
- border-bottom: none; }
382
-
383
- .customize-control-number .stepper {
384
- border-radius: 0px;
385
- margin: 0 0 10px 0;
386
- overflow: hidden;
387
- position: relative;
388
- width: 50%; }
389
- .customize-control-number .stepper .stepper-input {
390
- background: #F9F9F9;
391
- border: 1px solid #ccc;
392
- border-radius: 0px;
393
- color: #333;
394
- font-size: 13px;
395
- line-height: 1.2;
396
- margin: 0;
397
- overflow: hidden;
398
- padding: 9px 10px 10px;
399
- width: 100%;
400
- z-index: 49;
401
- -moz-appearance: textfield; }
402
- .customize-control-number .stepper .stepper-input::-webkit-inner-spin-button, .customize-control-number .stepper .stepper-input::-webkit-outer-spin-button {
403
- -webkit-appearance: none;
404
- margin: 0; }
405
- .customize-control-number .stepper .stepper-input:focus {
406
- background-color: #fff; }
407
- .customize-control-number .stepper .stepper-arrow {
408
- background: #eee url("../images/jquery.fs.stepper-arrows.png") no-repeat;
409
- border: 1px solid #ccc;
410
- cursor: pointer;
411
- display: block;
412
- height: 50%;
413
- position: absolute;
414
- right: 0;
415
- text-indent: -99999px;
416
- width: 20px;
417
- z-index: 50; }
418
- .customize-control-number .stepper .stepper-arrow.up {
419
- background-position: center top;
420
- border-bottom: none;
421
- top: 0; }
422
- .customize-control-number .stepper .stepper-arrow.down {
423
- background-position: center bottom;
424
- bottom: 0; }
73
  display: block;
74
  position: absolute;
75
  top: 5px;
76
+ right: -10px;
77
  border-radius: 50%;
78
  color: #999;
79
  border: none;
81
  width: 20px;
82
  height: 20px; }
83
 
84
+ .select2-container {
85
+ min-width: 100px;
86
+ width: 100% !important; }
87
+ .select2-container--open .select2-dropdown--below,
88
+ .select2-container--open .select2-dropdown--above {
89
+ z-index: 9999999;
90
+ min-width: 100px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/customizer.scss CHANGED
@@ -1,49 +1,3 @@
1
- @mixin custom-checkbox() {
2
- position: relative;
3
- margin: 0 1rem 0 0;
4
- cursor: pointer;
5
- margin-bottom: 5px;
6
- width: 22px;
7
- height: 22px;
8
- &:before {
9
- content: "";
10
- position: absolute;
11
- left: 0;
12
- z-index: 1;
13
- width: 100%;
14
- height: 100%;
15
- border: none;
16
- }
17
- &:after {
18
- content: "";
19
- position: absolute;
20
- left: 0;
21
- top: 0;
22
- width: 100%;
23
- height: 100%;
24
- background: #fff;
25
- cursor: pointer;
26
- }
27
- &:checked {
28
- &:before {
29
- border: 4px solid #4caf50;
30
- -webkit-transform: rotate(-45deg);
31
- -moz-transform: rotate(-45deg);
32
- -ms-transform: rotate(-45deg);
33
- -o-transform: rotate(-45deg);
34
- transform: rotate(-45deg);
35
- width: 14px;
36
- height: 6px;
37
- top: 6px;
38
- left: 5px;
39
- border-top-style: none;
40
- border-right-style: none;
41
- }
42
- &:after {
43
- background: #f2f2f2;
44
- }
45
- }
46
- }
47
  // Generic styles
48
  #customize-controls {
49
  #customize-header-actions {
@@ -148,7 +102,7 @@ li.customize-control {
148
  display: block;
149
  position: absolute;
150
  top: 5px;
151
- right: -20px;
152
  border-radius: 50%;
153
  color: #999;
154
  border: none;
@@ -157,350 +111,15 @@ li.customize-control {
157
  height: 20px;
158
  }
159
  }
160
- // Radio-Image Controls
161
- .customize-control-radio-image {
162
- .image.ui-buttonset {
163
- input[type=radio] {
164
- height: auto;
165
- }
166
- label {
167
- border: 1px solid transparent;
168
- display: inline-block;
169
- margin-right: 5px;
170
- margin-bottom: 5px;
171
- &.ui-state-active {
172
- background: none;
173
- border-color: #333;
174
- }
175
- }
176
- }
177
- }
178
- // Multicheck Controls
179
- .customize-control-multicheck {
180
- input[type="checkbox"] {
181
- @include custom-checkbox();
182
- }
183
- }
184
- // Checkbox Controls
185
- // Multicheck Controls
186
- .customize-control-checkbox {
187
- input[type="checkbox"] {
188
- @include custom-checkbox();
189
- }
190
- }
191
- // Radio-Buttonset Controls
192
- .customize-control-radio-buttonset {
193
- input[type=radio] {
194
 
195
- }
196
- label {
197
- padding: 5px 10px;
198
- background: #f7f7f7;
199
- border-left: 1px solid #dedede;
200
- &.ui-state-active {
201
- background: #dedede;
202
- }
203
- &.ui-corner-left {
204
- border-radius: 3px 0 0 3px;
205
- border-left: 0;
206
- }
207
- &.ui-corner-right {
208
- border-radius: 0 3px 3px 0;
209
- }
210
- }
211
- }
212
- // Switch & toggle Controls
213
- .customize-control-switch,
214
- .customize-control-toggle {
215
- .Switch {
216
- position: relative;
217
- display: inline-block;
218
- font-size: 16px;
219
- font-weight: bold;
220
- color: #aaa;
221
- height: 18px;
222
- line-height: 27px;
223
- padding: 6px;
224
- border: 1px solid #ccc;
225
- border: 1px solid rgba(0,0,0,0.2);
226
- background: #f2f2f2;
227
- cursor: pointer;
228
- float: right;
229
- transition: all 0.15s ease-in-out;
230
- .Toggle {
231
- position: absolute;
232
- top: 1px;
233
- width: 37px;
234
- height: 25px;
235
- border: 1px solid #aaa;
236
- border: 1px solid rgba(0,0,0,0.2);
237
- background: #fff;
238
- z-index: 989;
239
- transition: all 0.15s ease-in-out;
240
- }
241
- .On,
242
- .Off {
243
- display: inline-block;
244
- width: 35px;
245
- position: relative;
246
- top: -5px;
247
- }
248
- .On {
249
- color: #333;
250
- }
251
- &.On {
252
- .Toggle {
253
- left: 54%;
254
- }
255
- }
256
- &.Off {
257
- .Toggle {
258
- left: 2%;
259
- }
260
- }
261
- &.Round {
262
- padding: 0 20px;
263
- border-radius: 40px;
264
- margin-top: 5px;
265
- .Toggle {
266
- border-radius: 40px;
267
- width: 14px;
268
- height: 14px;
269
- }
270
- &.Off {
271
- .Toggle {
272
- left: 3%;
273
- }
274
- }
275
- &.On {
276
- color: #fff;
277
- background: #333;
278
- .Toggle {
279
- left: 58%;
280
- }
281
- }
282
- }
283
- }
284
- }
285
- body.IE7 .Switch {
286
- width: 78px;
287
- }
288
- body.IE7 .Switch.Round {
289
- width: 1px;
290
- }
291
- // Sortable Controls
292
- .customize-control-sortable {
293
- ul.ui-sortable {
294
- li {
295
- padding: 5px 10px;
296
- border: 1px solid #333;
297
- background: #fff;
298
- .dashicons {
299
- &.dashicons-menu {
300
- float: right;
301
- }
302
- &.visibility {
303
- margin-right: 10px;
304
- }
305
- }
306
- &.invisible {
307
- color: #aaa;
308
- border: 1px dashed #aaa;
309
- .dashicons.visibility {
310
- color: #aaa;
311
- }
312
- }
313
- }
314
- }
315
- }
316
- // Palette controls
317
- .customize-control-palette {
318
- label {
319
- &.ui-button.ui-widget {
320
- width: 95%;
321
- background: none;
322
- padding: 0;
323
- .ui-button-text {
324
- border-top: 3px solid transparent;
325
- border-bottom: 3px solid transparent;
326
- margin-bottom: 5px;
327
- display: flex;
328
- span {
329
- padding: 10px 0;
330
- flex-grow: 1;
331
- font-size: 0;
332
- line-height: 10px;
333
- color: rgba(0,0,0,0);
334
- -webkit-transition: all 200ms ease-in-out;
335
- -moz-transition: all 200ms ease-in-out;
336
- -ms-transition: all 200ms ease-in-out;
337
- -o-transition: all 200ms ease-in-out;
338
- transition: all 200ms ease-in-out;
339
- &:hover {
340
- padding: 10px;
341
- flex-grow: 3;
342
- min-width: 60px;
343
- font-size: 10px;
344
- line-height: 10px;
345
- color: #000;
346
- }
347
- }
348
- }
349
- }
350
- &.ui-state-active {
351
- &.ui-button.ui-widget {
352
- span.ui-button-text {
353
- border: 3px solid #333;
354
- }
355
- }
356
- }
357
- }
358
- }
359
- // Slider Controls
360
- .customize-control-slider {
361
- input[type="text"] {
362
- border: none;
363
- text-align: center;
364
- padding: 0;
365
- margin: 0;
366
- font-size: 12px;
367
- box-shadow: none;
368
- color: #333;
369
- }
370
- .ui-slider {
371
- position: relative;
372
- text-align: left;
373
- height: 7px;
374
- border-radius: 3px;
375
- background: #f2f2f2;
376
- border: 1px solid #dedede;
377
- margin-top: 10px;
378
- margin-bottom: 20px;
379
- .ui-slider-handle {
380
- position: absolute;
381
- z-index: 2;
382
- width: 15px;
383
- height: 15px;
384
- top: -5px;
385
- border-radius: 50%;
386
- cursor: default;
387
- -ms-touch-action: none;
388
- touch-action: none;
389
- background: #333;
390
- border: 1px solid #333;
391
- }
392
- .ui-slider-range {
393
- position: absolute;
394
- z-index: 1;
395
- font-size: 0.7em;
396
- display: block;
397
- border: 0;
398
- background-position: 0 0;
399
- }
400
- }
401
- }
402
- // Color-Alpha Controls
403
- .customize-control-color-alpha {
404
- .kirki-alpha-container {
405
- box-sizing: padding-box;
406
- display: none;
407
- border: 1px solid #dfdfdf;
408
- border-top: none;
409
- background: #fff;
410
- padding: 0 11px 6px;
411
- .transparency {
412
- height: 24px;
413
- width: 100%;
414
- background-color: #fff;
415
- background-image: url("../images/transparency-grid.png");
416
- box-shadow: 0 0 5px rgba(0,0,0,0.4) inset;
417
- -webkit-border-radius: 3px;
418
- -moz-border-radius: 3px;
419
- border-radius: 3px;
420
- padding: 0;
421
- }
422
- .ui-slider-handle {
423
- color: #777;
424
- background-color: #fff;
425
- text-shadow: 0 1px 0 #fff;
426
- text-decoration: none;
427
- position: absolute;
428
- z-index: 2;
429
- box-shadow: 0 1px 2px rgba(0,0,0,0.2);
430
- border: 1px solid #aaa;
431
- -webkit-border-radius: 4px;
432
- -moz-border-radius: 4px;
433
- border-radius: 4px;
434
- opacity: 0.9;
435
- margin-top: -2px;
436
- height: 20px;
437
- cursor: ew-resize;
438
- font-size: 12px;
439
- padding: 3px;
440
- }
441
- .ui-slider {
442
- position: relative;
443
- text-align: center;
444
- width: 88%;
445
- }
446
- }
447
- .wp-picker-container a.wp-picker-open ~ div.kirki-alpha-container {
448
- display: block;
449
- }
450
- .customize-control-alphacolor .wp-picker-container .iris-picker {
451
- border-bottom: none;
452
- }
453
- }
454
-
455
- // Number Controls
456
- .customize-control-number {
457
- .stepper {
458
- border-radius: 0px;
459
- margin: 0 0 10px 0;
460
- overflow: hidden;
461
- position: relative;
462
- width: 50%;
463
- .stepper-input {
464
- background: #F9F9F9;
465
- border: 1px solid #ccc;
466
- border-radius: 0px;
467
- color: #333;
468
- font-size: 13px;
469
- line-height: 1.2;
470
- margin: 0;
471
- overflow: hidden;
472
- padding: 9px 10px 10px;
473
- width: 100%;
474
- z-index: 49;
475
- -moz-appearance: textfield;
476
- &::-webkit-inner-spin-button,
477
- &::-webkit-outer-spin-button {
478
- -webkit-appearance: none; margin: 0;
479
- }
480
- &:focus {
481
- background-color: #fff;
482
- }
483
- }
484
- .stepper-arrow {
485
- background: #eee url("../images/jquery.fs.stepper-arrows.png") no-repeat;
486
- border: 1px solid #ccc;
487
- cursor: pointer;
488
- display: block;
489
- height: 50%;
490
- position: absolute;
491
- right: 0;
492
- text-indent: -99999px;
493
- width: 20px;
494
- z-index: 50;
495
- &.up {
496
- background-position: center top;
497
- border-bottom: none;
498
- top: 0;
499
- }
500
- &.down {
501
- background-position: center bottom;
502
- bottom: 0;
503
- }
504
- }
505
- }
506
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  // Generic styles
2
  #customize-controls {
3
  #customize-header-actions {
102
  display: block;
103
  position: absolute;
104
  top: 5px;
105
+ right: -10px;
106
  border-radius: 50%;
107
  color: #999;
108
  border: none;
111
  height: 20px;
112
  }
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
+ .select2-container {
116
+ min-width: 100px;
117
+ width: 100% !important;
118
+ &--open {
119
+ .select2-dropdown--below,
120
+ .select2-dropdown--above {
121
+ z-index: 9999999;
122
+ min-width: 100px;
123
+ }
124
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  }
assets/css/jquery-ui-1.10.0.custom.css DELETED
File without changes
assets/css/select2.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle;}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px;}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap;}.select2-container .select2-search--inline{float:left;}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051;}.select2-results{display:block;}.select2-results__options{list-style:none;margin:0;padding:0;}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none;}.select2-results__option[aria-selected]{cursor:pointer;}.select2-container--open .select2-dropdown{left:0;}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-search--dropdown{display:block;padding:4px;}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box;}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-search--dropdown.select2-search--hide{display:none;}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0);}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px;}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px;}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto;}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none;}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%;}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left;}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder{float:right;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0;}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none;}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0;}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa;}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--default .select2-results__option[role=group]{padding:0;}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999;}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd;}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em;}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white;}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic .select2-selection--single{background-color:#f6f6f6;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:-o-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:linear-gradient(to bottom, #ffffff 50%, #eeeeee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px;}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0);}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto;}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:-o-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:linear-gradient(to bottom, #ffffff 0%, #eeeeee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #ffffff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0);}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0;}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none;}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0;}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;}.select2-container--classic .select2-dropdown{background-color:white;border:1px solid transparent;}.select2-container--classic .select2-dropdown--above{border-bottom:none;}.select2-container--classic .select2-dropdown--below{border-top:none;}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--classic .select2-results__option[role=group]{padding:0;}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey;}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:white;}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb;}
assets/js/customizer.js DELETED
@@ -1,215 +0,0 @@
1
- jQuery.noConflict();
2
- /** Fire up jQuery - let's dance! */
3
- jQuery(document).ready(function($) {
4
- $("a.tooltip").tooltip();
5
- });
6
-
7
- jQuery(document).ready(function($) {
8
- "use strict";
9
- // initialize
10
- $('.kirki-sortable > ul ~ input').each(function() {
11
- var value = $(this).val();
12
- try {
13
- value = unserialize(value);
14
- } catch (err) {
15
- return;
16
- }
17
- var ul = $(this).siblings('ul:eq(0)');
18
- ul.find('li').addClass('invisible').find('i.visibility').toggleClass('dashicons-visibility-faint');
19
- $.each(value, function(i, val) {
20
- ul.find('li[data-value=' + val + ']').removeClass('invisible').find('i.visibility').toggleClass('dashicons-visibility-faint');
21
- });
22
- });
23
- $('.kirki-sortable > ul').each(function() {
24
- $(this).sortable()
25
- .disableSelection()
26
- .on("sortstop", function(event, ui) {
27
- kirkiUpdateSortable(ui.item.parent());
28
- })
29
- .find('li').each(function() {
30
- $(this).find('i.visibility').click(function() {
31
- $(this).toggleClass('dashicons-visibility-faint').parents('li:eq(0)').toggleClass('invisible');
32
- });
33
- })
34
- .click(function() {
35
- kirkiUpdateSortable($(this).parents('ul:eq(0)'));
36
- })
37
- });
38
-
39
-
40
- // Switch Click
41
- $('.Switch').click(function() {
42
- if ($(this).hasClass('On')) {
43
- $(this).parent().find('input:checkbox').attr('checked', true);
44
- $(this).removeClass('On').addClass('Off');
45
- } else {
46
- $(this).parent().find('input:checkbox').attr('checked', false);
47
- $(this).removeClass('Off').addClass('On');
48
- }
49
- });
50
-
51
- });
52
-
53
- function kirkiUpdateSortable(ul) {
54
- "use strict";
55
- var $ = jQuery;
56
- var values = [];
57
- ul.find('li').each(function() {
58
- if (!$(this).is('.invisible')) {
59
- values.push($(this).attr('data-value'));
60
- }
61
- });
62
- ul.siblings('input').eq(0).val(serialize(values)).trigger('change');
63
- }
64
-
65
-
66
- (function($) {
67
- wp.customizerCtrlEditor = {
68
-
69
- init: function() {
70
-
71
- $(window).load(function() {
72
-
73
- $('textarea.wp-editor-area').each(function() {
74
- var tArea = $(this),
75
- id = tArea.attr('id'),
76
- input = $('input[data-customize-setting-link="' + id + '"]'),
77
- editor = tinyMCE.get(id),
78
- setChange,
79
- content;
80
-
81
- if (editor) {
82
- editor.onChange.add(function(ed, e) {
83
- ed.save();
84
- content = editor.getContent();
85
- clearTimeout(setChange);
86
- setChange = setTimeout(function() {
87
- input.val(content).trigger('change');
88
- }, 500);
89
- });
90
- }
91
-
92
- if (editor) {
93
- editor.onChange.add(function(ed, e) {
94
- ed.save();
95
- content = editor.getContent();
96
- clearTimeout(setChange);
97
- setChange = setTimeout(function() {
98
- input.val(content).trigger('change');
99
- }, 500);
100
- });
101
- }
102
-
103
- tArea.css({
104
- visibility: 'visible'
105
- }).on('keyup', function() {
106
- content = tArea.val();
107
- clearTimeout(setChange);
108
- setChange = setTimeout(function() {
109
- input.val(content).trigger('change');
110
- }, 500);
111
- });
112
- });
113
- });
114
- }
115
-
116
- };
117
-
118
- wp.customizerCtrlEditor.init();
119
-
120
- })(jQuery);
121
-
122
- jQuery(document).ready(function($) {
123
-
124
- Color.prototype.toString = function(remove_alpha) {
125
- if (remove_alpha == 'no-alpha') {
126
- return this.toCSS('rgba', '1').replace(/\s+/g, '');
127
- }
128
- if (this._alpha < 1) {
129
- return this.toCSS('rgba', this._alpha).replace(/\s+/g, '');
130
- }
131
- var hex = parseInt(this._color, 10).toString(16);
132
- if (this.error) return '';
133
- if (hex.length < 6) {
134
- for (var i = 6 - hex.length - 1; i >= 0; i--) {
135
- hex = '0' + hex;
136
- }
137
- }
138
- return '#' + hex;
139
- };
140
-
141
- $('.kirki-color-control').each(function() {
142
- var $control = $(this),
143
- value = $control.val().replace(/\s+/g, '');
144
- // Manage Palettes
145
- var palette_input = $control.attr('data-palette');
146
- if (palette_input == 'false' || palette_input == false) {
147
- var palette = false;
148
- } else if (palette_input == 'true' || palette_input == true) {
149
- var palette = true;
150
- } else {
151
- var palette = $control.attr('data-palette').split(",");
152
- }
153
- $control.wpColorPicker({ // change some things with the color picker
154
- clear: function(event, ui) {
155
- // TODO reset Alpha Slider to 100
156
- },
157
- change: function(event, ui) {
158
- // send ajax request to wp.customizer to enable Save & Publish button
159
- var _new_value = $control.val();
160
- var key = $control.attr('data-customize-setting-link');
161
- wp.customize(key, function(obj) {
162
- obj.set(_new_value);
163
- });
164
- // change the background color of our transparency container whenever a color is updated
165
- var $transparency = $control.parents('.wp-picker-container:first').find('.transparency');
166
- // we only want to show the color at 100% alpha
167
- $transparency.css('backgroundColor', ui.color.toString('no-alpha'));
168
- },
169
- palettes: palette // remove the color palettes
170
- });
171
- $('<div class="kirki-alpha-container"><div class="slider-alpha"></div><div class="transparency"></div></div>').appendTo($control.parents('.wp-picker-container'));
172
- var $alpha_slider = $control.parents('.wp-picker-container:first').find('.slider-alpha');
173
- // if in format RGBA - grab A channel value
174
- if (value.match(/rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/)) {
175
- var alpha_val = parseFloat(value.match(/rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/)[1]) * 100;
176
- var alpha_val = parseInt(alpha_val);
177
- } else {
178
- var alpha_val = 100;
179
- }
180
- $alpha_slider.slider({
181
- slide: function(event, ui) {
182
- $(this).find('.ui-slider-handle').text(ui.value); // show value on slider handle
183
- // send ajax request to wp.customizer to enable Save & Publish button
184
- var _new_value = $control.val();
185
- var key = $control.attr('data-customize-setting-link');
186
- wp.customize(key, function(obj) {
187
- obj.set(_new_value);
188
- });
189
- },
190
- create: function(event, ui) {
191
- var v = $(this).slider('value');
192
- $(this).find('.ui-slider-handle').text(v);
193
- },
194
- value: alpha_val,
195
- range: "max",
196
- step: 1,
197
- min: 1,
198
- max: 100
199
- }); // slider
200
- $alpha_slider.slider().on('slidechange', function(event, ui) {
201
- var new_alpha_val = parseFloat(ui.value),
202
- iris = $control.data('a8cIris'),
203
- color_picker = $control.data('wpWpColorPicker');
204
- iris._color._alpha = new_alpha_val / 100.0;
205
- $control.val(iris._color.toString());
206
- color_picker.toggler.css({
207
- backgroundColor: $control.val()
208
- });
209
- // fix relationship between alpha slider and the 'side slider not updating.
210
- var get_val = $control.val();
211
- $($control).wpColorPicker('color', get_val);
212
- });
213
- }); // each
214
-
215
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/jquery.fs.stepper.min.js DELETED
@@ -1,9 +0,0 @@
1
- /*
2
- * Stepper v3.0.7 - 2014-11-25
3
- * A jQuery plugin for cross browser number inputs. Part of the Formstone Library.
4
- * http://formstone.it/stepper/
5
- *
6
- * Copyright 2014 Ben Plum; MIT Licensed
7
- */
8
-
9
- !function(a){"use strict";function b(b){b=a.extend({},l,b||{});for(var d=a(this),e=0,f=d.length;f>e;e++)c(d.eq(e),b);return d}function c(b,c){if(!b.hasClass("stepper-input")){c=a.extend({},c,b.data("stepper-options"));var f=parseFloat(b.attr("min")),g=parseFloat(b.attr("max")),h=parseFloat(b.attr("step"))||1;b.addClass("stepper-input").wrap('<div class="stepper '+c.customClass+'" />').after('<span class="stepper-arrow up">'+c.labels.up+'</span><span class="stepper-arrow down">'+c.labels.down+"</span>");var i=b.parent(".stepper"),k=a.extend({$stepper:i,$input:b,$arrow:i.find(".stepper-arrow"),min:void 0===typeof f||isNaN(f)?!1:f,max:void 0===typeof g||isNaN(g)?!1:g,step:void 0===typeof h||isNaN(h)?1:h,timer:null},c);k.digits=j(k.step),b.is(":disabled")&&i.addClass("disabled"),i.on("keypress",".stepper-input",k,d),i.on("touchstart.stepper mousedown.stepper",".stepper-arrow",k,e),b.data("stepper",k)}}function d(a){var b=a.data;(38===a.keyCode||40===a.keyCode)&&(a.preventDefault(),g(b,38===a.keyCode?b.step:-b.step))}function e(b){b.preventDefault(),b.stopPropagation(),f(b);var c=b.data;if(!c.$input.is(":disabled")&&!c.$stepper.hasClass("disabled")){var d=a(b.target).hasClass("up")?c.step:-c.step;c.timer=h(c.timer,125,function(){g(c,d,!1)}),g(c,d),a("body").on("touchend.stepper mouseup.stepper",c,f)}}function f(b){b.preventDefault(),b.stopPropagation();var c=b.data;i(c.timer),a("body").off(".stepper")}function g(a,b){var c=parseFloat(a.$input.val()),d=b;void 0===typeof c||isNaN(c)?d=a.min!==!1?a.min:0:a.min!==!1&&c<a.min?d=a.min:d+=c;var e=(d-a.min)%a.step;0!==e&&(d-=e),a.min!==!1&&d<a.min&&(d=a.min),a.max!==!1&&d>a.max&&(d-=a.step),d!==c&&(d=k(d,a.digits),a.$input.val(d).trigger("change"))}function h(a,b,c){return i(a),setInterval(c,b)}function i(a){a&&(clearInterval(a),a=null)}function j(a){var b=String(a);return b.indexOf(".")>-1?b.length-b.indexOf(".")-1:0}function k(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c}var l={customClass:"",labels:{up:"Up",down:"Down"}},m={defaults:function(b){return l=a.extend(l,b||{}),"object"==typeof this?a(this):!0},destroy:function(){return a(this).each(function(){var b=a(this).data("stepper");b&&(b.$stepper.off(".stepper").find(".stepper-arrow").remove(),b.$input.unwrap().removeClass("stepper-input"))})},disable:function(){return a(this).each(function(){var b=a(this).data("stepper");b&&(b.$input.attr("disabled","disabled"),b.$stepper.addClass("disabled"))})},enable:function(){return a(this).each(function(){var b=a(this).data("stepper");b&&(b.$input.attr("disabled",null),b.$stepper.removeClass("disabled"))})}};a.fn.stepper=function(a){return m[a]?m[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?this:b.apply(this,arguments)},a.stepper=function(a){"defaults"===a&&m.defaults.apply(this,Array.prototype.slice.call(arguments,1))}}(jQuery,this);
 
 
 
 
 
 
 
 
 
assets/js/kirki-tooltip.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /** Fire up jQuery - let's dance! */
2
+ jQuery(document).ready(function($) {
3
+ $("a.tooltip").tooltip();
4
+ });
assets/js/select2.full.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){return n.apply(b,v.call(arguments,0).concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice;this.listeners=this.listeners||{},a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),this.$results.append(d)},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")});var f=e.filter("[aria-selected=true]");f.length>0?f.first().trigger("mouseenter"):e.first().trigger("mouseenter")})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";{a(h)}this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b){var c=this,d=b.id+"-results";this.$results.attr("id",d),b.on("results:all",function(a){c.clear(),c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("results:append",function(a){c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("query",function(a){c.showLoading(a)}),b.on("select",function(){b.isOpen()&&c.setClasses()}),b.on("unselect",function(){b.isOpen()&&c.setClasses()}),b.on("open",function(){c.$results.attr("aria-expanded","true"),c.$results.attr("aria-hidden","false"),c.setClasses(),c.ensureHighlightVisible()}),b.on("close",function(){c.$results.attr("aria-expanded","false"),c.$results.attr("aria-hidden","true"),c.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=c.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=c.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?c.trigger("close"):c.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a);if(0!==d){var e=d-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top,h=f.offset().top,i=c.$results.scrollTop()+(h-g);0===e?c.$results.scrollTop(0):0>h-g&&c.$results.scrollTop(i)}}),b.on("results:next",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a),e=d+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top+c.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=c.$results.scrollTop()+h-g;0===e?c.$results.scrollTop(0):h>g&&c.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){c.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=c.$results.scrollTop(),d=c.$results.get(0).scrollHeight-c.$results.scrollTop()+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&d<=c.$results.height();e?(c.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(c.$results.scrollTop(c.$results.get(0).scrollHeight-c.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var d=a(this),e=d.data("data");return"true"===d.attr("aria-selected")?void(c.options.get("multiple")?c.trigger("unselect",{originalEvent:b,data:e}):c.trigger("close")):void c.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var b=a(this).data("data");c.getHighlightedResults().removeClass("select2-results__option--highlighted"),c.trigger("results:focus",{data:b,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a){var b=this,d=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){b.trigger("focus",a)}),this.$selection.on("blur",function(a){b.trigger("blur",a)}),this.$selection.on("keydown",function(a){b.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){b.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){b.update(a.data)}),a.on("open",function(){b.$selection.attr("aria-expanded","true"),b.$selection.attr("aria-owns",d),b._attachCloseHandler(a)}),a.on("close",function(){b.$selection.attr("aria-expanded","false"),b.$selection.removeAttr("aria-activedescendant"),b.$selection.removeAttr("aria-owns"),b.$selection.focus(),b._detachCloseHandler(a)}),a.on("enable",function(){b.$selection.attr("tabindex",b._tabindex)}),a.on("disable",function(){b.$selection.attr("tabindex","-1")})},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},d.prototype.bind=function(a){var b=this;d.__super__.bind.apply(this,arguments);var c=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",c),this.$selection.attr("aria-labelledby",c),this.$selection.on("mousedown",function(a){1===a.which&&b.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),a.on("selection:update",function(a){b.update(a.data)})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){return a("<span></span>")},d.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.display(b),d=this.$selection.find(".select2-selection__rendered");d.empty().append(c),d.prop("title",b.title||b.text)},d}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(){var b=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){b.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(c){var d=a(this),e=d.parent(),f=e.data("data");b.trigger("unselect",{originalEvent:c,data:f})})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.display(e),g=this.selectionContainer();g.append(f),g.prop("title",e.title||e.text),g.data("data",e),b.push(g)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(){function a(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},a.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},a}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle")}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">&times;</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus()}),b.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.focus()}),b.on("enable",function(){e.$search.prop("disabled",!1)}),b.on("disable",function(){e.$search.prop("disabled",!0)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e.trigger("blur",a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}}),this.$selection.on("input",".select2-search--inline",function(){e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input",".select2-search--inline",function(a){e.handleSearch(a)})},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.trigger("open"),this.$search.val(b.text+" ")},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a){var b=this;this.container=a,a.on("select",function(a){b.select(a.data)}),a.on("unselect",function(a){b.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};
2
+ if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=(c.extend(!0,{},l,j),this.option(l));k.replaceWith(m)}else{var n=this.option(j);if(j.children){var o=this.convertToOptions(j.children);b.appendMany(n,o)}h.push(n)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(b,c){this.ajaxOptions=this._applyDefaults(c.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),a.__super__.constructor.call(this,b,c)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return{q:a.term}},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url(a)),"function"==typeof f.data&&(f.data=f.data(a)),this.ajaxOptions.delay&&""!==a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");if(void 0!==f&&(this.createTag=f),b.call(this,c,d),a.isArray(e))for(var g=0;g<e.length;g++){var h=e[g],i=this._normalizeItem(h),j=this.option(i);this.$element.append(j)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(){var b=(this._lastTag,this.$element.find("option[data-select2-tag]"));b.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(a,b,c){function d(a){e.select(a)}var e=this;b.term=b.term||"";var f=this.tokenizer(b,this.options,d);f.term!==b.term&&(this.$search.length&&(this.$search.val(f.term),this.$search.focus()),b.term=f.term),a.call(this,b,c)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);e(m),g=g.substr(h+1)||"",h=0}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.position=function(){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a){function b(){}return b.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},b.prototype.handleSearch=function(){if(!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},b.prototype.showSearch=function(){return!0},b}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="option load-more" role="treeitem"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(a,b,c){this.$dropdownParent=c.get("dropdownParent")||document.body,a.call(this,b,c)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c){var d=this,e="scroll.select2."+c.id,f="resize.select2."+c.id,g="orientationchange.select2."+c.id,h=this.$container.parents().filter(b.hasScroll);h.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),h.on(e,function(){var b=a(this).data("select2-scroll-position");a(this).scrollTop(b.y)}),a(window).on(e+" "+f+" "+g,function(){d._positionDropdown(),d._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c){var d="scroll.select2."+c.id,e="resize.select2."+c.id,f="orientationchange.select2."+c.id,g=this.$container.parents().filter(b.hasScroll);g.off(d),a(window).off(d+" "+e+" "+f)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=(this.$container.position(),this.$container.offset());f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom};c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){this.$dropdownContainer.width();var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(){d._handleSelectOnClose()})},a.prototype._handleSelectOnClose=function(){var a=this.getHighlightedResults();a.length<1||this.trigger("select",{data:a.data("data")})},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close")},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend({},this.defaults,l),null==l.dataAdapter){if(l.dataAdapter=null!=l.ajax?o:null!=l.data?n:m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.selectionAdapter=l.multiple?e:d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(this.options.dir=a.prop("dir")?a.prop("dir"):a.closest("[dir]").prop("dir")?a.closest("[dir]").prop("dir"):"ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this._sync=c.bind(this._syncAttributes,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._sync);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._sync)}),this._observer.observe(this.$element[0],{attributes:!0,subtree:!1})):this.$element[0].addEventListener&&this.$element[0].addEventListener("DOMAttrModified",b._sync,!1)},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("focus",function(){a.$container.addClass("select2-container--focus")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open"),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ENTER?(a.trigger("results:select"),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle"),b.preventDefault()):c===d.UP?(a.trigger("results:previous"),b.preventDefault()):c===d.DOWN?(a.trigger("results:next"),b.preventDefault()):(c===d.ESC||c===d.TAB)&&(a.close(),b.preventDefault()):(c===d.ENTER||c===d.SPACE||(c===d.DOWN||c===d.UP)&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable")):this.trigger("enable")},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||(this.trigger("query",{}),this.trigger("open"))},e.prototype.close=function(){this.isOpen()&&this.trigger("close")},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._sync),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&this.$element[0].removeEventListener("DOMAttrModified",this._sync,!1),this._sync=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&(f=d(this),null!=f&&g.push(f))})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;return this._isInitialized?void b.call(this,c):void this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f<this._currentData.length;f++){var g=this._currentData[f];e.push.apply(e,d(g,this.$element.val().split(this._valueSeparator)))}c(e)},b.prototype.select=function(b,c){if(this.options.get("multiple")){var d=this.$element.val();d+=this._valueSeparator+c.id,this.$element.val(d),this.$element.trigger("change")}else this.current(function(b){a.map(b,function(a){a.selected=!1})}),this.$element.val(c.id),this.$element.trigger("change")},b.prototype.unselect=function(a,b){var c=this;b.selected=!1,this.current(function(a){for(var d=[],e=0;e<a.length;e++){var f=a[e];
3
+ b.id!=f.id&&d.push(f.id)}c.$element.val(d.join(c._valueSeparator)),c.$element.trigger("change")})},b.prototype.query=function(a,b,c){for(var d=[],e=0;e<this._currentData.length;e++){var f=this._currentData[e],g=this.matches(b,f);null!==g&&d.push(g)}c({results:d})},b.prototype.addOptions=function(b,c){var d=a.map(c,function(b){return a.data(b[0],"data")});this._currentData.push.apply(this._currentData,d)},b}),b.define("select2/compat/matcher",["jquery"],function(a){function b(b){function c(c,d){var e=a.extend(!0,{},d);if(null==c.term||""===a.trim(c.term))return e;if(d.children){for(var f=d.children.length-1;f>=0;f--){var g=d.children[f],h=b(c.term,g.text,g);h||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c;var d=this.options.get("query");d.call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){var d=c.find(".dropdown-wrapper");d.append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("jquery.select2",["jquery","require","./select2/core","./select2/defaults"],function(a,b,c,d){if(b("jquery.mousewheel"),null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){{var d=a.extend({},b,!0);new c(a(this),d)}}),this;if("string"==typeof b){var d=this.data("select2");null==d&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2.");var f=Array.prototype.slice.call(arguments,1),g=d[b](f);return a.inArray(b,e)>-1?this:g}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery.mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
bin/install-wp-tests.sh ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ if [ $# -lt 3 ]; then
4
+ echo "usage: $0 <db-name> <db-user> <db-pass> [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/includes}
15
+ WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
16
+
17
+ set -ex
18
+
19
+ download() {
20
+ if [ `which curl` ]; then
21
+ curl -s "$1" > "$2";
22
+ elif [ `which wget` ]; then
23
+ wget -nv -O "$2" "$1"
24
+ fi
25
+ }
26
+
27
+ install_wp() {
28
+
29
+ if [ -d $WP_CORE_DIR ]; then
30
+ return;
31
+ fi
32
+
33
+ mkdir -p $WP_CORE_DIR
34
+
35
+ if [ $WP_VERSION == 'latest' ]; then
36
+ local ARCHIVE_NAME='latest'
37
+ else
38
+ local ARCHIVE_NAME="wordpress-$WP_VERSION"
39
+ fi
40
+
41
+ download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
42
+ tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
43
+
44
+ download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
45
+ }
46
+
47
+ install_test_suite() {
48
+ # portable in-place argument for both GNU sed and Mac OSX sed
49
+ if [[ $(uname -s) == 'Darwin' ]]; then
50
+ local ioption='-i .bak'
51
+ else
52
+ local ioption='-i'
53
+ fi
54
+
55
+ # set up testing suite if it doesn't yet exist
56
+ if [ ! "$(ls -A $WP_TESTS_DIR)" ]; then
57
+ # set up testing suite
58
+ mkdir -p $WP_TESTS_DIR
59
+ svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR
60
+ fi
61
+
62
+ cd $WP_TESTS_DIR
63
+
64
+ if [ ! -f wp-tests-config.php ]; then
65
+ download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
66
+ sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
67
+ sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
68
+ sed $ioption "s/yourusernamehere/$DB_USER/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
69
+ sed $ioption "s/yourpasswordhere/$DB_PASS/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
70
+ sed $ioption "s|localhost|${DB_HOST}|" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php
71
+ fi
72
+
73
+ }
74
+
75
+ install_db() {
76
+ # parse DB_HOST for port or socket references
77
+ local PARTS=(${DB_HOST//\:/ })
78
+ local DB_HOSTNAME=${PARTS[0]};
79
+ local DB_SOCK_OR_PORT=${PARTS[1]};
80
+ local EXTRA=""
81
+
82
+ if ! [ -z $DB_HOSTNAME ] ; then
83
+ if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
84
+ EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
85
+ elif ! [ -z $DB_SOCK_OR_PORT ] ; then
86
+ EXTRA=" --socket=$DB_SOCK_OR_PORT"
87
+ elif ! [ -z $DB_HOSTNAME ] ; then
88
+ EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
89
+ fi
90
+ fi
91
+
92
+ # create database
93
+ mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
94
+ }
95
+
96
+ install_wp
97
+ install_test_suite
98
+ install_db
composer.json CHANGED
@@ -1,22 +1,26 @@
1
  {
2
- "name": "aristath/kirki",
3
- "type": "library",
4
- "description": "Extending the WordPress customizer",
5
- "homepage": "http://kirki.org",
6
- "license": "GPLv2 or later",
7
- "authors": [
8
- {
9
- "name" : "aristath",
10
- "email" : "aristath@gmail.com",
11
- "homepage" : "http://aristeides.com"
12
- },
13
- {
14
- "name" : "fovoc",
15
- "email" : "kalliris.d@gmail.com",
16
- "homepage" : "https://github.com/fovoc"
17
- }
18
- ],
19
- "require": {
20
- "php": ">=5.3"
21
  }
 
 
 
 
 
 
 
 
22
  }
1
  {
2
+ "name": "aristath/kirki",
3
+ "type": "library",
4
+ "description": "Extending the WordPress customizer",
5
+ "homepage": "http://kirki.org",
6
+ "license": "GPLv2 or later",
7
+ "authors": [
8
+ {
9
+ "name" : "aristath",
10
+ "email" : "aristath@gmail.com",
11
+ "homepage" : "http://aristeides.com"
12
+ },
13
+ {
14
+ "name" : "fovoc",
15
+ "email" : "kalliris.d@gmail.com",
16
+ "homepage" : "https://github.com/fovoc"
 
 
 
 
17
  }
18
+ ],
19
+ "require": {
20
+ "php": ">=5.2"
21
+ },
22
+ "require-dev": {
23
+ "phpunit/phpunit": "~4.0",
24
+ "satooshi/php-coveralls": "dev-master"
25
+ }
26
  }
includes/Builder.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
-
5
- use Kirki;
6
- use Kirki\Settings;
7
- use Kirki\Controls;
8
-
9
- class Builder {
10
-
11
- public $settings;
12
- private $controls;
13
-
14
- public function __construct() {
15
-
16
- $this->settings = new Settings();
17
- $this->controls = new Controls();
18
- add_action( 'customize_register', array( $this, 'build' ), 99 );
19
-
20
- }
21
-
22
- /**
23
- * Build the customizer fields.
24
- * Parses all fields and creates the setting & control for each of them.
25
- */
26
- public function build( $wp_customize ) {
27
- $fields = Kirki::fields()->get_all();
28
-
29
- // Early exit if controls are not set or if they're empty
30
- if ( empty( $fields ) ) {
31
- return;
32
- }
33
-
34
- foreach ( $fields as $field ) {
35
- $this->build_field( $wp_customize, $field );
36
- }
37
-
38
- }
39
-
40
- /**
41
- * Build a single field
42
- */
43
- public function build_field( $wp_customize, $field ) {
44
- $this->settings->add( $wp_customize, $field );
45
- $this->controls->add( $wp_customize, $field );
46
- }
47
-
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Config.php DELETED
@@ -1,138 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
-
5
- class Config {
6
-
7
- /** @var array The configuration values for Kirki */
8
- private $config = null;
9
-
10
- /**
11
- * Constructor
12
- */
13
- public function __construct() {
14
- }
15
-
16
- /**
17
- * Get a configuration value
18
- *
19
- * @param string $key The configuration key we are interested in
20
- * @param string $default The default value if that configuration is not set
21
- *
22
- * @return mixed
23
- */
24
- public function get( $key, $default='' ) {
25
-
26
- $cfg = $this->get_all();
27
- return isset( $cfg[$key] ) ? $cfg[$key] : $default;
28
-
29
- }
30
-
31
- /**
32
- * Get a configuration value or throw an exception if that value is mandatory
33
- *
34
- * @param string $key The configuration key we are interested in
35
- *
36
- * @return mixed
37
- */
38
- public function getOrThrow( $key ) {
39
-
40
- $cfg = $this->get_all();
41
- if ( isset( $cfg[$key] ) ) {
42
- return $cfg[$key];
43
- }
44
-
45
- throw new RuntimeException( sprintf( "Configuration key %s is mandatory and has not been specified", $key ) );
46
-
47
- }
48
-
49
- /**
50
- * Get the configuration options for the Kirki customizer.
51
- *
52
- * @uses 'kirki/config' filter.
53
- */
54
- public function get_all() {
55
-
56
- if ( is_null( $this->config ) ) {
57
-
58
- // Get configuration from the filter
59
- $this->config = apply_filters( 'kirki/config', array() );
60
-
61
- // Merge a default configuration with the one we got from the user to make sure nothing is missing
62
- $default_config = array(
63
- 'stylesheet_id' => 'kirki-styles',
64
- 'capability' => 'edit_theme_options',
65
- 'logo_image' => '',
66
- 'description' => '',
67
- 'url_path' => '',
68
- 'options_type' => 'theme_mod',
69
- );
70
- $this->config = array_merge( $default_config, $this->config );
71
-
72
- $this->config['logo_image'] = esc_url_raw( $this->config['logo_image'] );
73
- $this->config['description'] = esc_html( $this->config['description'] );
74
- $this->config['url_path'] = esc_url_raw( $this->config['url_path'] );
75
-
76
- // Get the translation strings.
77
- $this->config['i18n'] = ( ! isset( $this->config['i18n'] ) ) ? array() : $this->config['i18n'];
78
- $this->config['i18n'] = array_merge( $this->translation_strings(), $this->config['i18n'] );
79
-
80
- }
81
-
82
- return $this->config;
83
-
84
- }
85
-
86
- /**
87
- * The i18n strings
88
- */
89
- public function translation_strings() {
90
-
91
- $strings = array(
92
- 'background-color' => __( 'Background Color', 'kirki' ),
93
- 'background-image' => __( 'Background Image', 'kirki' ),
94
- 'no-repeat' => __( 'No Repeat', 'kirki' ),
95
- 'repeat-all' => __( 'Repeat All', 'kirki' ),
96
- 'repeat-x' => __( 'Repeat Horizontally', 'kirki' ),
97
- 'repeat-y' => __( 'Repeat Vertically', 'kirki' ),
98
- 'inherit' => __( 'Inherit', 'kirki' ),
99
- 'background-repeat' => __( 'Background Repeat', 'kirki' ),
100
- 'cover' => __( 'Cover', 'kirki' ),
101
- 'contain' => __( 'Contain', 'kirki' ),
102
- 'background-size' => __( 'Background Size', 'kirki' ),
103
- 'fixed' => __( 'Fixed', 'kirki' ),
104
- 'scroll' => __( 'Scroll', 'kirki' ),
105
- 'background-attachment' => __( 'Background Attachment', 'kirki' ),
106
- 'left-top' => __( 'Left Top', 'kirki' ),
107
- 'left-center' => __( 'Left Center', 'kirki' ),
108
- 'left-bottom' => __( 'Left Bottom', 'kirki' ),
109
- 'right-top' => __( 'Right Top', 'kirki' ),
110
- 'right-center' => __( 'Right Center', 'kirki' ),
111
- 'right-bottom' => __( 'Right Bottom', 'kirki' ),
112
- 'center-top' => __( 'Center Top', 'kirki' ),
113
- 'center-center' => __( 'Center Center', 'kirki' ),
114
- 'center-bottom' => __( 'Center Bottom', 'kirki' ),
115
- 'background-position' => __( 'Background Position', 'kirki' ),
116
- 'background-opacity' => __( 'Background Opacity', 'kirki' ),
117
- 'ON' => __( 'ON', 'kirki' ),
118
- 'OFF' => __( 'OFF', 'kirki' ),
119
- 'all' => __( 'All', 'kirki' ),
120
- 'cyrillic' => __( 'Cyrillic', 'kirki' ),
121
- 'cyrillic-ext' => __( 'Cyrillic Extended', 'kirki' ),
122
- 'devanagari' => __( 'Devanagari', 'kirki' ),
123
- 'greek' => __( 'Greek', 'kirki' ),
124
- 'greek-ext' => __( 'Greek Extended', 'kirki' ),
125
- 'khmer' => __( 'Khmer', 'kirki' ),
126
- 'latin' => __( 'Latin', 'kirki' ),
127
- 'latin-ext' => __( 'Latin Extended', 'kirki' ),
128
- 'vietnamese' => __( 'Vietnamese', 'kirki' ),
129
- 'serif' => _x( 'Serif', 'font style', 'kirki' ),
130
- 'sans-serif' => _x( 'Sans Serif', 'font style', 'kirki' ),
131
- 'monospace' => _x( 'Monospace', 'font style', 'kirki' ),
132
- );
133
-
134
- return $strings;
135
-
136
- }
137
-
138
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls.php DELETED
@@ -1,124 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
-
5
- use Kirki;
6
- use Kirki\Controls\CustomControl;
7
- use Kirki\Controls\EditorControl;
8
- use Kirki\Controls\MultiCheckControl;
9
- use Kirki\Controls\NumberControl;
10
- use Kirki\Controls\PaletteControl;
11
- use Kirki\Controls\RadioButtonSetControl;
12
- use Kirki\Controls\RadioImageControl;
13
- use Kirki\Controls\SliderControl;
14
- use Kirki\Controls\SortableControl;
15
- use Kirki\Controls\SwitchControl;
16
- use Kirki\Controls\ToggleControl;
17
- use Kirki\Controls\ColorAlphaControl;
18
-
19
- class Controls {
20
-
21
- public function __construct() {
22
- global $wp_customize;
23
- // add_action( 'customize_register', array( $this, 'register_control_type' ) );
24
- }
25
-
26
- public function register_control_type( $wp_customize ) {
27
- $wp_customize->register_control_type( '\Kirki\Controls\CustomControl' );
28
- $wp_customize->register_control_type( '\Kirki\Controls\EditorControl' );
29
- $wp_customize->register_control_type( '\Kirki\Controls\MulticheckControl' );
30
- $wp_customize->register_control_type( '\Kirki\Controls\NumberControl' );
31
- $wp_customize->register_control_type( '\Kirki\Controls\PaletteControl' );
32
- $wp_customize->register_control_type( '\Kirki\Controls\RadioImageControl' );
33
- $wp_customize->register_control_type( '\Kirki\Controls\SliderControl' );
34
- $wp_customize->register_control_type( '\Kirki\Controls\SortableControl' );
35
- $wp_customize->register_control_type( '\Kirki\Controls\SwitchControl' );
36
- $wp_customize->register_control_type( '\Kirki\Controls\ToggleControl' );
37
- $wp_customize->register_control_type( '\Kirki\Controls\ColorAlphaControl' );
38
- $wp_customize->register_control_type( '\Kirki\Controls\TabControl' );
39
- }
40
-
41
- /**
42
- * Add our fields.
43
- * We use the default WordPress Core Customizer fields when possible
44
- * and only add our own custom controls when needed.
45
- */
46
- public function add( $wp_customize, $field ) {
47
-
48
- switch ( $field['type'] ) {
49
-
50
- case 'color' :
51
- $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, $field['id'], $field ) );
52
- break;
53
-
54
- case 'color-alpha' :
55
- $wp_customize->add_control( new ColorAlphaControl( $wp_customize, $field['id'], $field ) );
56
- break;
57
-
58
- case 'image' :
59
- $wp_customize->add_control( new \WP_Customize_Image_Control( $wp_customize, $field['id'], $field ) );
60
- break;
61
-
62
- case 'upload' :
63
- $wp_customize->add_control( new \WP_Customize_Upload_Control( $wp_customize, $field['id'], $field ) );
64
- break;
65
-
66
- case 'switch' :
67
- $wp_customize->add_control( new SwitchControl( $wp_customize, $field['id'], $field ) );
68
- break;
69
-
70
- case 'toggle' :
71
- $wp_customize->add_control( new ToggleControl( $wp_customize, $field['id'], $field ) );
72
- break;
73
-
74
- case 'radio-buttonset' :
75
- $wp_customize->add_control( new RadioButtonSetControl( $wp_customize, $field['id'], $field ) );
76
- break;
77
-
78
- case 'radio-image' :
79
- $wp_customize->add_control( new RadioImageControl( $wp_customize, $field['id'], $field ) );
80
- break;
81
-
82
- case 'sortable' :
83
- $wp_customize->add_control( new SortableControl( $wp_customize, $field['id'], $field ) );
84
- break;
85
-
86
- case 'slider' :
87
- $wp_customize->add_control( new SliderControl( $wp_customize, $field['id'], $field ) );
88
- break;
89
-
90
- case 'number' :
91
- $wp_customize->add_control( new NumberControl( $wp_customize, $field['id'], $field ) );
92
- break;
93
-
94
- case 'multicheck' :
95
- $wp_customize->add_control( new MultiCheckControl( $wp_customize, $field['id'], $field ) );
96
- break;
97
-
98
- case 'palette' :
99
- $wp_customize->add_control( new PaletteControl( $wp_customize, $field['id'], $field ) );
100
- break;
101
-
102
- case 'custom' :
103
- $wp_customize->add_control( new CustomControl( $wp_customize, $field['id'], $field ) );
104
- break;
105
-
106
- case 'editor' :
107
- $wp_customize->add_control( new EditorControl( $wp_customize, $field['id'], $field ) );
108
- break;
109
-
110
- case 'background' :
111
- // Do nothing.
112
- // The 'background' field is just the sum of its sub-fields
113
- // which are created individually.
114
- break;
115
-
116
- default :
117
- $wp_customize->add_control( new \WP_Customize_Control( $wp_customize, $field['id'], $field ) );
118
- break;
119
-
120
- }
121
-
122
- }
123
-
124
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/ColorAlphaControl.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class ColorAlphaControl extends \WP_Customize_Control {
6
-
7
- public $type = 'color-alpha';
8
- public $palette = true;
9
- public $default = '#FFFFFF';
10
-
11
- protected function render() {
12
- $id = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
13
- $class = 'customize-control customize-control-' . $this->type; ?>
14
- <li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
15
- <?php $this->render_content(); ?>
16
- </li>
17
- <?php }
18
-
19
- public function render_content() { ?>
20
- <label>
21
- <?php
22
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
23
- ?>
24
- <span class="customize-control-title"><?php echo $this->label; ?></span>
25
- <input type="text" data-palette="<?php echo esc_textarea( $this->palette ); ?>" data-default-color="<?php echo $this->default; ?>" value="<?php echo intval( $this->value() ); ?>" class="kirki-color-control" <?php $this->link(); ?> />
26
- </label>
27
- <?php }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/CustomControl.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class CustomControl extends \WP_Customize_Control {
6
-
7
- public $type = 'custom';
8
-
9
- public function render_content() { ?>
10
- <label>
11
- <?php
12
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
13
- ?>
14
- <?php if ( ! empty( $this->label ) ) : ?>
15
- <span class="customize-control-title"><?php echo $this->label; ?></span>
16
- <?php endif;
17
- if ( ! empty( $this->description ) ) : ?>
18
- <?php
19
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
20
- ?>
21
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
22
- <?php endif; ?>
23
- <?php
24
- /**
25
- * The value is defined by the developer in the field configuration as the default value.
26
- * There is no user input on this field, it's a raw HTML/JS field and we don not sanitize it.
27
- * Do not be alarmed, this is not a security issue.
28
- * In order for someone to be able to change this they would have to have access to your filesystem.
29
- * If that happens, they can change whatever they want anyways. This field is not a concern.
30
- */
31
- ?>
32
- <?php echo $this->value(); ?>
33
- </label>
34
- <?php
35
-
36
- }
37
-
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/EditorControl.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class EditorControl extends \WP_Customize_Control {
6
-
7
- public $type = 'editor';
8
-
9
- public function render_content() { ?>
10
-
11
- <label>
12
- <span class="customize-control-title">
13
- <?php
14
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
15
- ?>
16
- <?php echo $this->label; ?>
17
- <?php if ( ! empty( $this->description ) ) : ?>
18
- <?php
19
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
20
- ?>
21
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
22
- <?php endif; ?>
23
- </span>
24
- <input type="hidden" <?php $this->link(); ?> value="<?php echo esc_textarea( $this->value() ); ?>">
25
- <?php
26
- $settings = array(
27
- 'textarea_name' => $this->id,
28
- 'teeny' => true
29
- );
30
- wp_editor( esc_textarea( $this->value() ), $this->id, $settings );
31
-
32
- do_action('admin_footer');
33
- do_action('admin_print_footer_scripts');
34
- ?>
35
- </label>
36
- <?php
37
- }
38
-
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/MultiCheckControl.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- /**
6
- * Control inspired by the Titan Framework MultiCheck control.
7
- * See https://github.com/gambitph/Titan-Framework/blob/v1.4.2/class-option-multicheck.php for more details.
8
- */
9
- class MultiCheckControl extends \WP_Customize_Control {
10
-
11
- public $type = 'multicheck';
12
-
13
- private static $firstLoad = true;
14
-
15
- // Since theme_mod cannot handle multichecks, we will do it with some JS
16
- public function render_content() {
17
- // the saved value is an array. convert it to csv
18
- if ( is_array( $this->value() ) ) {
19
- $savedValueCSV = implode( ',', $this->value() );
20
- $values = $this->value();
21
- } else {
22
- $savedValueCSV = $this->value();
23
- $values = explode( ',', $this->value() );
24
- }
25
-
26
- if ( self::$firstLoad ) {
27
- self::$firstLoad = false;
28
-
29
- ?>
30
- <script>
31
- jQuery(document).ready(function($) {
32
- "use strict";
33
-
34
- $('input.tf-multicheck').change(function(event) {
35
- event.preventDefault();
36
- var csv = '';
37
-
38
- $(this).parents('li:eq(0)').find('input[type=checkbox]').each(function() {
39
- if ($(this).is(':checked')) {
40
- csv += $(this).attr('value') + ',';
41
- }
42
- });
43
-
44
- csv = csv.replace(/,+$/, "");
45
-
46
- $(this).parents('li:eq(0)').find('input[type=hidden]').val(csv)
47
- // we need to trigger the field afterwards to enable the save button
48
- .trigger('change');
49
- return true;
50
- });
51
- });
52
- </script>
53
- <?php
54
- } ?>
55
- <label class='tf-multicheck-container'>
56
- <span class="customize-control-title">
57
- <?php
58
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
59
- ?>
60
- <?php echo $this->label; ?>
61
- <?php if ( ! empty( $this->description ) ) : ?>
62
- <?php
63
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
64
- ?>
65
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
66
- <?php endif; ?>
67
- </span>
68
- <?php
69
- foreach ( $this->choices as $value => $label ) {
70
- printf('<label for="%s"><input class="tf-multicheck" id="%s" type="checkbox" value="%s" %s/> %s</label><br>',
71
- $this->id . $value,
72
- $this->id . $value,
73
- esc_attr( $value ),
74
- checked( in_array( $value, $values ), true, false ),
75
- $label
76
- );
77
- }
78
- ?>
79
- <input type="hidden" value="<?php echo esc_attr( $savedValueCSV ); ?>" <?php $this->link(); ?> />
80
- </label>
81
- <?php
82
-
83
- }
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/NumberControl.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class NumberControl extends \WP_Customize_Control {
6
-
7
- public $type = 'number';
8
-
9
- public function content_template() { ?>
10
-
11
- <label class="customizer-text">
12
- <span class="customize-control-title">
13
- <# if ( data.label ) { #>{{ data.label }}<# } #>
14
- <# if ( data.description ) { #>
15
- <span class="description customize-control-description">{{ data.description }}</span>
16
- <# } #>
17
- </span>
18
- <input type="number" <?php $this->link(); ?> value="<?php echo intval( $this->value() ); ?>"/>
19
- <# if ( data.help ) { #>
20
- <a href="#" class="button tooltip hint--left" data-hint="{{ data.help }}">?</a>
21
- <# } #>
22
- </label>
23
- <?php
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/RadioButtonSetControl.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class RadioButtonSetControl extends \WP_Customize_Control {
6
-
7
- public $type = 'radio-buttonset';
8
-
9
- public function enqueue() {
10
- wp_enqueue_script( 'jquery-ui-button' );
11
- }
12
-
13
- public function render_content() {
14
-
15
- if ( empty( $this->choices ) ) {
16
- return;
17
- }
18
-
19
- $name = '_customize-radio-' . $this->id;
20
-
21
- ?>
22
- <span class="customize-control-title">
23
- <?php
24
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
25
- ?>
26
- <?php echo $this->label; ?>
27
- <?php if ( ! empty( $this->description ) ) : ?>
28
- <?php
29
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
30
- ?>
31
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
32
- <?php endif; ?>
33
- </span>
34
-
35
- <div id="input_<?php echo $this->id; ?>" class="buttonset">
36
- <?php foreach ( $this->choices as $value => $label ) : ?>
37
- <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id . $value; ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
38
- <label for="<?php echo $this->id . $value; ?>">
39
- <?php echo esc_html( $label ); ?>
40
- </label>
41
- </input>
42
- <?php endforeach; ?>
43
- </div>
44
- <script>jQuery(document).ready(function($) { $( '[id="input_<?php echo $this->id; ?>"]' ).buttonset(); });</script>
45
- <?php
46
- }
47
-
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/RadioImageControl.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class RadioImageControl extends \WP_Customize_Control {
6
-
7
- public $type = 'radio-image';
8
-
9
- public function enqueue() {
10
- wp_enqueue_script( 'jquery-ui-button' );
11
- }
12
-
13
- public function render_content() {
14
-
15
- if ( empty( $this->choices ) ) {
16
- return;
17
- }
18
-
19
- $name = '_customize-radio-' . $this->id;
20
-
21
- ?>
22
- <span class="customize-control-title">
23
- <?php
24
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
25
- ?>
26
- <?php echo $this->label; ?>
27
- <?php if ( ! empty( $this->description ) ) : ?>
28
- <?php
29
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
30
- ?>
31
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
32
- <?php endif; ?>
33
- </span>
34
-
35
- <div id="input_<?php echo $this->id; ?>" class="image">
36
- <?php foreach ( $this->choices as $value => $label ) : ?>
37
- <input class="image-select" type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id . $value; ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
38
- <label for="<?php echo $this->id . $value; ?>">
39
- <img src="<?php echo esc_html( $label ); ?>">
40
- </label>
41
- </input>
42
- <?php endforeach; ?>
43
- </div>
44
- <script>jQuery(document).ready(function($) { $( '[id="input_<?php echo $this->id; ?>"]' ).buttonset(); });</script>
45
- <?php
46
- }
47
-
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/SliderControl.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class SliderControl extends \WP_Customize_Control {
6
-
7
- public $type = 'slider';
8
-
9
- public function enqueue() {
10
- wp_enqueue_script( 'jquery-ui' );
11
- wp_enqueue_script( 'jquery-ui-slider' );
12
- }
13
-
14
- public function render_content() { ?>
15
- <label>
16
-
17
- <span class="customize-control-title">
18
- <?php
19
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
20
- ?>
21
- <?php echo $this->label; ?>
22
- <?php if ( ! empty( $this->description ) ) : ?>
23
- <?php
24
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
25
- ?>
26
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
27
- <?php endif; ?>
28
- </span>
29
-
30
- <input type="text" class="kirki-slider" id="input_<?php echo $this->id; ?>" disabled value="<?php echo $this->value(); ?>" <?php $this->link(); ?>/>
31
-
32
- </label>
33
-
34
- <div id="slider_<?php echo $this->id; ?>" class="ss-slider"></div>
35
- <script>
36
- jQuery(document).ready(function($) {
37
- $( '[id="slider_<?php echo $this->id; ?>"]' ).slider({
38
- value : <?php echo $this->value(); ?>,
39
- min : <?php echo $this->choices['min']; ?>,
40
- max : <?php echo $this->choices['max']; ?>,
41
- step : <?php echo $this->choices['step']; ?>,
42
- slide : function( event, ui ) { $( '[id="input_<?php echo $this->id; ?>"]' ).val(ui.value).keyup(); }
43
- });
44
- $( '[id="input_<?php echo $this->id; ?>"]' ).val( $( '[id="slider_<?php echo $this->id; ?>"]' ).slider( "value" ) );
45
- });
46
- </script>
47
- <?php
48
-
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/SwitchControl.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- use Kirki;
6
-
7
- class SwitchControl extends \WP_Customize_Control {
8
-
9
- public $type = 'switch';
10
-
11
- /**
12
- * Render the control's content.
13
- */
14
- protected function render_content() { ?>
15
- <?php $i18n = Kirki::i18n(); ?>
16
- <label>
17
- <div class="switch-info">
18
- <input style="display: none;" type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
19
- </div>
20
- <?php
21
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
22
- ?>
23
- <?php echo $this->label; ?>
24
- <?php if ( ! empty( $this->description ) ) : ?>
25
- <?php
26
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
27
- ?>
28
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
29
- <?php endif; ?>
30
- <?php $classes = ( esc_attr( $this->value() ) ) ? ' On' : ' Off'; ?>
31
- <div class="Switch <?php echo $classes; ?>">
32
- <div class="Toggle"></div>
33
- <span class="On"><?php echo $i18n['ON']; ?></span>
34
- <span class="Off"><?php echo $i18n['OFF']; ?></span>
35
- </div>
36
- </label>
37
- <?php
38
- }
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Controls/ToggleControl.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Controls;
4
-
5
- class ToggleControl extends \WP_Customize_Control {
6
-
7
- public $type = 'toggle';
8
-
9
- /**
10
- * Render the control's content.
11
- */
12
- protected function render_content() { ?>
13
- <label>
14
- <div class="switch-info">
15
- <input style="display: none;" type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
16
- </div>
17
- <?php
18
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
19
- ?>
20
- <?php echo $this->label; ?>
21
- <?php if ( ! empty( $this->description ) ) : ?>
22
- <?php
23
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
24
- ?>
25
- <span class="description customize-control-description"><?php echo $this->description; ?></span>
26
- <?php endif; ?>
27
- <?php $classes = ( esc_attr( $this->value() ) ) ? ' On' : ' Off'; ?>
28
- <?php $classes .= ' Round'; ?>
29
- <div class="Switch <?php echo $classes; ?>">
30
- <div class="Toggle"></div>
31
- </div>
32
- </label>
33
- <?php
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Fields.php DELETED
@@ -1,585 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
-
5
- use Kirki;
6
-
7
- class Fields {
8
-
9
- /** @var array The controls */
10
- private $fields = null;
11
-
12
- /**
13
- * Get an array of all the fields
14
- */
15
- public function get_all() {
16
-
17
- if ( $this->fields == null ) {
18
-
19
- $fields = apply_filters( 'kirki/controls', array() );
20
- $fields = apply_filters( 'kirki/fields', $fields );
21
- $fields = $this->build_background_fields( $fields );
22
-
23
- $this->fields = array();
24
- foreach ( $fields as $field ) {
25
- $field = $this->sanitize_field( $field );
26
- $this->fields[$field['settings']] = $field;
27
- }
28
-
29
- }
30
-
31
- return $this->fields;
32
- }
33
-
34
- /**
35
- * Sanitizes the field
36
- *
37
- * @param array the field definition
38
- * @return array
39
- */
40
- public function sanitize_field( $field ) {
41
-
42
- $field['default'] = $this->sanitize_default( $field );
43
- $field['label'] = $this->sanitize_label( $field );
44
- $field['help'] = $this->sanitize_help( $field );
45
- $field['description'] = $this->sanitize_description( $field );
46
- $field['required'] = $this->sanitize_required( $field );
47
- $field['transport'] = $this->sanitize_transport( $field );
48
- $field['type'] = $this->sanitize_control_type( $field );
49
- $field['option_type'] = $this->sanitize_type( $field );
50
- $field['section'] = $this->sanitize_section( $field );
51
- $field['settings'] = $this->sanitize_settings( $field );
52
- $field['priority'] = $this->sanitize_priority( $field );
53
- $field['choices'] = $this->sanitize_choices( $field );
54
- $field['output'] = $this->sanitize_output( $field );
55
- $field['sanitize_callback'] = $this->sanitize_callback( $field );
56
- $field['js_vars'] = $this->sanitize_js_vars( $field );
57
- $field['id'] = $this->sanitize_id( $field );
58
- $field['capability'] = $this->sanitize_capability( $field );
59
-
60
- return $field;
61
-
62
- }
63
-
64
- /**
65
- * Sanitizes the control type.
66
- *
67
- * @param array the field definition
68
- * @return string. If not set, then defaults to text.
69
- */
70
- public function sanitize_control_type( $field ) {
71
-
72
- if ( ! isset( $field['type'] ) ) {
73
- return 'text';
74
- }
75
-
76
- if ( 'checkbox' == $field['type'] ) {
77
-
78
- $field['type'] = ( isset( $field['mode'] ) && 'switch' == $field['mode'] ) ? 'switch' : $field['type'];
79
- $field['type'] = ( isset( $field['mode'] ) && 'toggle' == $field['mode'] ) ? 'toggle' : $field['type'];
80
-
81
- } elseif ( 'radio' == $field['type'] ) {
82
-
83
- $field['type'] = ( isset( $field['mode'] ) && 'buttonset' == $field['mode'] ) ? 'radio-buttonset' : $field['type'];
84
- $field['type'] = ( isset( $field['mode'] ) && 'image' == $field['mode'] ) ? 'radio-image' : $field['type'];
85
-
86
- } elseif ( 'group-title' == $field['type'] || 'group_title' == $field['type'] ) {
87
-
88
- $field['type'] = 'custom';
89
-
90
- } elseif ( 'color' == $field['type'] && false !== strpos( $field['default'], 'rgba' ) ) {
91
-
92
- $field['type'] = 'color-alpha';
93
-
94
- }
95
-
96
- return esc_attr( $field['type'] );
97
-
98
- }
99
-
100
- /**
101
- * Sanitizes the setting type.
102
- *
103
- * @param array the field definition
104
- * @return string. (theme_mod|option)
105
- */
106
- public function sanitize_type( $field ) {
107
- $config = Kirki::config()->get_all();
108
- return esc_attr( $config['options_type'] );
109
- }
110
-
111
- /**
112
- * Sanitizes the setting permissions.
113
- *
114
- * @param array the field definition
115
- * @return string. (theme_mod|option)
116
- */
117
- public function sanitize_capability( $field ) {
118
- if ( ! isset( $field['capability'] ) ) {
119
- $config = Kirki::config()->get_all();
120
- return esc_attr( $config['capability'] );
121
- } else {
122
- return esc_attr( $field['capability'] );
123
- }
124
- }
125
-
126
- /**
127
- * Sanitizes the setting name
128
- *
129
- * @param array the field definition
130
- * @return string.
131
- */
132
- public function sanitize_settings( $field ) {
133
-
134
- /**
135
- * Compatibility tweak
136
- * Previous versions of the Kirki customizer used 'setting' istead of 'settings'.
137
- */
138
- if ( ! isset( $field['settings'] ) && isset( $field['setting'] ) ) {
139
- $field['settings'] = $field['setting'];
140
- }
141
-
142
- return esc_attr( $field['settings'] );
143
-
144
- }
145
-
146
- /**
147
- * Sanitizes the control label.
148
- *
149
- * @param array the field definition
150
- * @return string
151
- */
152
- public function sanitize_label( $field ) {
153
- return ( isset( $field['label'] ) ) ? esc_html( $field['label'] ) : '';
154
- }
155
-
156
- /**
157
- * Sanitizes the control section
158
- *
159
- * @param array the field definition
160
- * @return string
161
- */
162
- public function sanitize_section( $field ) {
163
- return sanitize_key( $field['section'] );
164
- }
165
-
166
- /**
167
- * Sanitizes the control id
168
- *
169
- * @param array the field definition
170
- * @return string
171
- */
172
- public function sanitize_id( $field ) {
173
- $id = str_replace( '[', '-', str_replace( ']', '', $field['settings'] ) );
174
- return sanitize_key( $id );
175
- }
176
-
177
- /**
178
- * Sanitizes the setting default value
179
- *
180
- * @param array the field definition
181
- * @return mixed
182
- */
183
- public function sanitize_default( $field ) {
184
- // If ['default'] is not set, set an empty value
185
- if ( ! isset( $field['default'] ) ) {
186
- $field['default'] = '';
187
- }
188
-
189
- /**
190
- * Sortable controls need a serialized array as the default value.
191
- * Since we're using normal arrays to set our defaults when defining the fields, we need to serialize that value here.
192
- */
193
- if ( 'sortable' == $field['type'] && isset( $field['default'] ) && ! empty( $field['default'] ) ) {
194
- $field['default'] = maybe_serialize( $field['default'] );
195
- }
196
-
197
- return $field['default'];
198
-
199
- }
200
-
201
- /**
202
- * Sanitizes the control description
203
- *
204
- * @param array the field definition
205
- * @return string
206
- */
207
- public function sanitize_description( $field ) {
208
-
209
- /**
210
- * Compatibility tweak
211
- *
212
- * Previous verions of the Kirki Customizer had the 'description' field mapped to the new 'help'
213
- * and instead of 'description' we were using 'subtitle'.
214
- * This has been deprecated in favor of WordPress core's 'description' field that was recently introduced.
215
- *
216
- */
217
- if ( isset( $field['subtitle'] ) ) {
218
- $field['description'] = $field['subtitle'];
219
- }
220
-
221
- return ( isset( $field['description'] ) ) ? esc_html( $field['description'] ) : '';
222
-
223
- }
224
-
225
- /**
226
- * Sanitizes the control help
227
- *
228
- * @param array the field definition
229
- * @return string
230
- */
231
- public function sanitize_help( $field ) {
232
-
233
- /**
234
- * Compatibility tweak
235
- *
236
- * Previous verions of the Kirki Customizer had the 'description' field mapped to the new 'help'
237
- * and instead of 'description' we were using 'subtitle'.
238
- * This has been deprecated in favor of WordPress core's 'description' field that was recently introduced.
239
- *
240
- */
241
- if ( isset( $field['subtitle'] ) ) {
242
- // Use old arguments form.
243
- $field['help'] = ( isset( $field['description'] ) ) ? $field['description'] : '';
244
- }
245
- return isset( $field['help'] ) ? esc_html( $field['help'] ) : '';
246
-
247
- }
248
-
249
- /**
250
- * Sanitizes the control choices.
251
- *
252
- * @param array the field definition
253
- * @return array
254
- */
255
- public function sanitize_choices( $field ) {
256
- return isset( $field['choices'] ) ? $field['choices'] : array();
257
- }
258
-
259
- /**
260
- * Sanitizes the control output
261
- *
262
- * @param array the field definition
263
- * @return array
264
- */
265
- public function sanitize_output( $field ) {
266
- // Further sanitization on the values of the array happens near the output.
267
- // This just makes sure the value is defined to avoid errors.
268
- return isset( $field['output'] ) ? $field['output'] : null;
269
- }
270
-
271
- /**
272
- * Sanitizes the control transport.
273
- *
274
- * @param array the field definition
275
- * @return string postMessage|refresh (defaults to refresh)
276
- */
277
- public function sanitize_transport( $field ) {
278
- return ( isset( $field['transport'] ) && 'postMessage' == $field['transport'] ) ? 'postMessage' : 'refresh';
279
- }
280
-
281
- /**
282
- * Sanitizes the setting sanitize_callback
283
- *
284
- * @param array the field definition
285
- * @return mixed the sanitization callback for this setting
286
- */
287
- public function sanitize_callback( $field ) {
288
-
289
- if ( isset( $field['sanitize_callback'] ) && ! empty( $field['sanitize_callback'] ) ) {
290
- return $field['sanitize_callback'];
291
- } else { // Fallback callback
292
- return self::fallback_callback( $field['type'] );
293
- }
294
-
295
- }
296
-
297
- /**
298
- * Sanitizes the control js_vars.
299
- *
300
- * @param array the field definition
301
- * @return array
302
- */
303
- public function sanitize_js_vars( $field ) {
304
- if ( isset( $field['js_vars'] ) ) {
305
- return $field['js_vars'];
306
- } else {
307
- return null;
308
- }
309
- }
310
-
311
- /**
312
- * Sanitizes the control required argument.
313
- *
314
- * @param array the field definition
315
- * @return array
316
- */
317
- public function sanitize_required( $field ) {
318
- // The individual options of the array get sanitized in the Required class.
319
- // We're just making sure this is defined here.
320
- return isset( $field['required'] ) ? $field['required'] : array();
321
- }
322
-
323
- /**
324
- * Sanitizes the control priority
325
- *
326
- * @param array the field definition
327
- * @return int
328
- */
329
- public function sanitize_priority( $field ) {
330
-
331
- if ( isset( $field['priority'] ) ) {
332
- return intval( $field['priority'] );
333
- } else {
334
- return 10;
335
- }
336
-
337
- }
338
-
339
- /**
340
- * Build the background fields.
341
- * Takes a single field with type = background and explodes it to multiple controls.
342
- */
343
- public function build_background_fields( $fields ) {
344
- $i18n = Kirki::i18n();
345
-
346
- foreach ( $fields as $field ) {
347
-
348
- if ( 'background' == $field['type'] ) {
349
-
350
- // Set any unset values to avoid PHP warnings below.
351
- $field['settings'] = ( ! isset( $field['settings'] ) && isset( $field['setting'] ) ) ? $field['setting'] : $field['settings'];
352
- $field['section'] = ( isset( $field['section'] ) ) ? $field['section'] : 'background';
353
- $field['help'] = ( isset( $field['help'] ) ) ? $field['help'] : '';
354
- $field['description'] = ( isset( $field['description'] ) ) ? $field['description'] : $i18n['background-color'];
355
- $field['required'] = ( isset( $field['required'] ) ) ? $field['required'] : array();
356
- $field['transport'] = ( isset( $field['transport'] ) ) ? $field['transport'] : 'refresh';
357
- $field['default'] = ( isset( $field['default'] ) ) ? $field['default'] : array();
358
- $field['priority'] = ( isset( $field['priority'] ) ) ? $field['priority'] : 10;
359
-
360
- if ( isset( $field['default']['color'] ) ) {
361
- $color_mode = ( false !== strpos( $field['default']['color'], 'rgba' ) ) ? 'color-alpha' : 'color';
362
- $fields[] = array(
363
- 'type' => $color_mode,
364
- 'label' => isset( $field['label'] ) ? $field['label'] : '',
365
- 'section' => $field['section'],
366
- 'settings' => $field['settings'] . '_color',
367
- 'priority' => $field['priority'],
368
- 'help' => $field['help'],
369
- 'description' => $field['description'],
370
- 'required' => $field['required'],
371
- 'transport' => $field['transport'],
372
- 'default' => $field['default']['color'],
373
- );
374
- }
375
-
376
- if ( isset( $field['default']['image'] ) ) {
377
- $fields[] = array(
378
- 'type' => 'image',
379
- 'label' => '',
380
- 'section' => $field['section'],
381
- 'settings' => $field['settings'] . '_image',
382
- 'priority' => $field['priority'] + 1,
383
- 'help' => '',
384
- 'description' => $i18n['background-image'],
385
- 'required' => $field['required'],
386
- 'transport' => $field['transport'],
387
- 'default' => $field['default']['image'],
388
- );
389
- }
390
-
391
- if ( isset( $field['default']['repeat'] ) ) {
392
- $fields[] = array(
393
- 'type' => 'select',
394
- 'label' => '',
395
- 'section' => $field['section'],
396
- 'settings' => $field['settings'] . '_',
397
- 'priority' => $field['priority'] + 2,
398
- 'choices' => array(
399
- 'no-repeat' => $i18n['no-repeat'],
400
- 'repeat' => $i18n['repeat-all'],
401
- 'repeat-x' => $i18n['repeat-x'],
402
- 'repeat-y' => $i18n['repeat-y'],
403
- 'inherit' => $i18n['inherit'],
404
- ),
405
- 'help' => '',
406
- 'description' => $i18n['background-repeat'],
407
- 'required' => $field['required'],
408
- 'transport' => $field['transport'],
409
- 'default' => $field['default']['repeat'],
410
- );
411
- }
412
-
413
- if ( isset( $field['default']['size'] ) ) {
414
- $fields[] = array(
415
- 'type' => 'radio-buttonset',
416
- 'label' => '',
417
- 'section' => $field['section'],
418
- 'settings' => $field['settings'] . '_size',
419
- 'priority' => $field['priority'] + 3,
420
- 'choices' => array(
421
- 'inherit' => $i18n['inherit'],
422
- 'cover' => $i18n['cover'],
423
- 'contain' => $i18n['contain'],
424
- ),
425
- 'help' => '',
426
- 'description' => $i18n['background-size'],
427
- 'required' => $field['required'],
428
- 'transport' => $field['transport'],
429
- 'default' => $field['default']['size'],
430
- );
431
- }
432
-
433
- if ( isset( $field['default']['attach'] ) ) {
434
- $fields[] = array(
435
- 'label' => '',
436
- 'type' => 'radio-buttonset',
437
- 'section' => $field['section'],
438
- 'settings' => $field['settings'] . '_attach',
439
- 'priority' => $field['priority'] + 4,
440
- 'choices' => array(
441
- 'inherit' => $i18n['inherit'],
442
- 'fixed' => $i18n['fixed'],
443
- 'scroll' => $i18n['scroll'],
444
- ),
445
- 'help' => '',
446
- 'description' => $i18n['background-attachment'],
447
- 'required' => $field['required'],
448
- 'transport' => $field['transport'],
449
- 'default' => $field['default']['attach'],
450
- );
451
- }
452
-
453
- if ( isset( $field['default']['position'] ) ) {
454
- $fields[] = array(
455
- 'type' => 'select',
456
- 'label' => '',
457
- 'section' => $field['section'],
458
- 'settings' => $field['settings'] . '_position',
459
- 'priority' => $field['priority'] + 5,
460
- 'choices' => array(
461
- 'left-top' => $i18n['left-top'],
462
- 'left-center' => $i18n['left-center'],
463
- 'left-bottom' => $i18n['left-bottom'],
464
- 'right-top' => $i18n['right-top'],
465
- 'right-center' => $i18n['right-center'],
466
- 'right-bottom' => $i18n['right-bottom'],
467
- 'center-top' => $i18n['center-top'],
468
- 'center-center' => $i18n['center-center'],
469
- 'center-bottom' => $i18n['center-bottom'],
470
- ),
471
- 'help' => '',
472
- 'description' => $i18n['background-position'],
473
- 'required' => $field['required'],
474
- 'transport' => $field['transport'],
475
- 'default' => $field['default']['position'],
476
- );
477
- }
478
-
479
- if ( isset( $field['default']['opacity'] ) && $field['default']['opacity'] ) {
480
- $fields[] = array(
481
- 'type' => 'slider',
482
- 'label' => '',
483
- 'section' => $field['section'],
484
- 'settings' => $field['settings'] . '_opacity',
485
- 'priority' => $field['priority'] + 6,
486
- 'choices' => array(
487
- 'min' => 0,
488
- 'max' => 100,
489
- 'step' => 1,
490
- ),
491
- 'help' => '',
492
- 'description' => $i18n['background-opacity'],
493
- 'required' => $field['required'],
494
- 'transport' => $field['transport'],
495
- 'default' => $field['default']['opacity'],
496
- );
497
-
498
- }
499
-
500
- }
501
-
502
- }
503
-
504
- return $fields;
505
-
506
- }
507
-
508
- /**
509
- * Sanitizes the control transport.
510
- *
511
- * @param string the control type
512
- * @return string the function name of a sanitization callback
513
- */
514
- public static function fallback_callback( $field_type ) {
515
-
516
- switch ( $field_type ) {
517
- case 'checkbox' :
518
- $sanitize_callback = 'kirki_sanitize_checkbox';
519
- break;
520
- case 'color' :
521
- $sanitize_callback = 'sanitize_hex_color';
522
- break;
523
- case 'color-alpha' :
524
- $sanitize_callback = 'esc_js';
525
- break;
526
- case 'image' :
527
- $sanitize_callback = 'esc_url_raw';
528
- break;
529
- case 'radio' :
530
- $sanitize_callback = 'kirki_sanitize_choice';
531
- break;
532
- case 'radio-image' :
533
- $sanitize_callback = 'kirki_sanitize_choice';
534
- break;
535
- case 'radio-buttonset' :
536
- $sanitize_callback = 'kirki_sanitize_choice';
537
- break;
538
- case 'toggle' :
539
- $sanitize_callback = 'kirki_sanitize_checkbox';
540
- break;
541
- case 'switch' :
542
- $sanitize_callback = 'kirki_sanitize_checkbox';
543
- break;
544
- case 'select' :
545
- $sanitize_callback = 'kirki_sanitize_choice';
546
- break;
547
- case 'dropdown-pages' :
548
- $sanitize_callback = 'kirki_sanitize_choice';
549
- break;
550
- case 'slider' :
551
- $sanitize_callback = 'kirki_sanitize_number';
552
- break;
553
- case 'text' :
554
- $sanitize_callback = 'esc_textarea';
555
- break;
556
- case 'textarea' :
557
- $sanitize_callback = 'esc_textarea';
558
- break;
559
- case 'editor' :
560
- $sanitize_callback = 'esc_textarea';
561
- break;
562
- case 'upload' :
563
- $sanitize_callback = 'esc_url_raw';
564
- break;
565
- case 'number' :
566
- $sanitize_callback = 'kirki_sanitize_number';
567
- break;
568
- case 'multicheck' :
569
- $sanitize_callback = 'esc_attr';
570
- break;
571
- case 'sortable' :
572
- $sanitize_callback = 'kirki_sanitize_sortable';
573
- break;
574
- case 'palette' :
575
- $sanitize_callback = 'kirki_sanitize_choice';
576
- break;
577
- default :
578
- $sanitize_callback = 'kirki_sanitize_unfiltered';
579
- }
580
-
581
- return $sanitize_callback;
582
-
583
- }
584
-
585
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/deprecated.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This file contains all the deprecated functions
5
- */
6
-
7
- function kirki_sanitize_hex( $color ) {
8
- Kirki_Color::sanitize_hex( $color );
9
- }
10
-
11
- function kirki_get_rgb( $hex, $implode = false ) {
12
- Kirki_Color::get_rgb( $hex, $implode );
13
- }
14
-
15
- function kirki_get_rgba( $hex = '#fff', $opacity = 100 ) {
16
- Kirki_Color::get_rgba( $hex, $opacity );
17
- }
18
-
19
- function kirki_get_brightness( $hex ) {
20
- Kirki_Color::get_brightness( $hex );
21
- }
22
-
23
- if ( ! class_exists( 'Kirki_Fonts' ) ) {
24
-
25
- class Kirki_Fonts {
26
-
27
- public static function get_all_fonts() {
28
- $font_registry = Kirki::fonts();
29
- return $font_registry->get_all_fonts();
30
- }
31
-
32
- public static function get_font_choices() {
33
- $font_registry = Kirki::fonts();
34
- return $font_registry->get_font_choices();
35
- }
36
-
37
- public static function is_google_font( $font ) {
38
- $font_registry = Kirki::fonts();
39
- return $font_registray->is_google_font( $font );
40
- }
41
-
42
- public static function get_google_font_uri( $fonts, $weight = 400, $subset = 'all' ) {
43
- $font_registry = Kirki::fonts();
44
- return $font_registry->get_google_font_uri( $fonts, $weight, $subset );
45
- }
46
-
47
- public static function get_google_font_subsets() {
48
- $font_registry = Kirki::fonts();
49
- return $font_registry->get_google_font_subsets();
50
- }
51
-
52
- public static function choose_google_font_variants( $font, $variants = array() ) {
53
- $font_registry = Kirki::fonts();
54
- return $font_registry->choose_google_font_variants( $font, $variants );
55
- }
56
-
57
- public static function get_standard_fonts() {
58
- $font_registry = Kirki::fonts();
59
- return $font_registry->get_standard_fonts();
60
- }
61
-
62
- public static function get_font_stack( $font ) {
63
- $font_registry = Kirki::fonts();
64
- return $font_registry->get_font_stack( $font );
65
- }
66
-
67
- public static function sanitize_font_choice( $value ) {
68
- $font_registry = Kirki::fonts();
69
- return $font_registry->sanitize_font_choice( $value );
70
- }
71
-
72
- public static function get_google_fonts() {
73
- $font_registry = Kirki::fonts();
74
- return $font_registry->get_google_fonts();
75
- }
76
-
77
- }
78
-
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/helpers.php DELETED
@@ -1,129 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Helper function
5
- *
6
- * removes an item from an array
7
- */
8
- function kirki_array_delete( $idx, $array ) {
9
-
10
- unset( $array[$idx] );
11
- return ( is_array( $array ) ) ? array_values( $array ) : null;
12
-
13
- }
14
-
15
- /**
16
- * Takes care of all the migration and compatibility issues with previous versions.
17
- */
18
- function kirki_update() {
19
-
20
- $version = get_option( 'kirki_version' );
21
- $version = ( ! $version ) ? '0' : $version;
22
- // < 0.6.1 -> 0.6.2
23
- if ( ! $version ) {
24
- /**
25
- * In versions 0.6.0 & 0.6.1 there was a bug and some fields were saved as ID_opacity istead if ID
26
- * This will fix the wrong settings naming and save new settings.
27
- */
28
- $field_ids = array();
29
- $fields = Kirki::fields()->get_all();
30
-
31
- foreach ( $fields as $field ) {
32
- $field = Kirki::field()->sanitize( $field );
33
-
34
- if ( 'background' != $field['type'] ) {
35
- $field_ids[] = $field['settings'];
36
- }
37
-
38
- }
39
-
40
- foreach ( $field_ids as $field_id ) {
41
-
42
- if ( get_theme_mod( $field_id . '_opacity' ) && ! get_theme_mod( $field_id ) ) {
43
- set_theme_mod( $field_id, get_theme_mod( $field_id . '_opacity' ) );
44
- }
45
-
46
- }
47
-
48
- }
49
-
50
- if ( ! $version || version_compare( Kirki::$version, $version ) ) {
51
- update_option( 'kirki_version', Kirki::$version );
52
- }
53
-
54
- }
55
- // add_action( 'wp', 'kirki_update' );
56
-
57
- /**
58
- * Get the value of a field.
59
- */
60
- function kirki_get_option( $option = '' ) {
61
-
62
- // Make sure the class is instanciated
63
- Kirki::get_instance();
64
-
65
- // Get the array of all the fields.
66
- $fields = Kirki::fields()->get_all();
67
- // Get the config.
68
- $config = Kirki::config()->get_all();
69
-
70
- /**
71
- * If no setting has been defined then return all.
72
- */
73
- if ( '' == $option ) {
74
- if ( 'option' == $config['options_type'] ) {
75
- $values = array();
76
- foreach ( $fields as $field ) {
77
- $values[] = get_option( $field['settings'], $field['default'] );
78
- }
79
- } else {
80
- $values = get_theme_mods();
81
- }
82
-
83
- return $values;
84
-
85
- }
86
- // If a value has been defined then we proceed.
87
-
88
- // Early exit if this option does not exist
89
- if ( ! isset( $fields[$option] ) ) {
90
- return;
91
- }
92
-
93
- $option_name = $fields[$option]['settings'];
94
- $default = $fields[$option]['default'];
95
-
96
- if ( 'option' == $config['options_type'] ) {
97
- $value = get_option( $option_name, $default );
98
- } else {
99
- $value = get_theme_mod( $option_name, $default );
100
- }
101
-
102
- return $value;
103
-
104
- }
105
-
106
- /**
107
- * Load plugin textdomain.
108
- *
109
- * @since 0.8.0
110
- */
111
- function kirki_load_textdomain() {
112
- $textdomain = 'kirki';
113
-
114
- // Look for WP_LANG_DIR/{$domain}-{$locale}.mo
115
- if ( file_exists( WP_LANG_DIR . '/' . $textdomain . '-' . get_locale() . '.mo' ) ) {
116
- $file = WP_LANG_DIR . '/' . $textdomain . '-' . get_locale() . '.mo';
117
- }
118
- // Look for KIRKI_PATH/languages/{$domain}-{$locale}.mo
119
- if ( ! isset( $file ) && file_exists( KIRKI_PATH . '/languages/' . $textdomain . '-' . get_locale() . '.mo' ) ) {
120
- $file = KIRKI_PATH . '/languages/' . $textdomain . '-' . get_locale() . '.mo';
121
- }
122
-
123
- if ( isset( $file ) ) {
124
- load_textdomain( $textdomain, $file );
125
- }
126
-
127
- load_plugin_textdomain( $textdomain, false, KIRKI_PATH . '/languages' );
128
- }
129
- add_action( 'plugins_loaded', 'kirki_load_textdomain' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/libraries/class-kirki-color.php DELETED
@@ -1,475 +0,0 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Color Calculations class for Kirki
6
- * (initially built for the Shoestrap-3 theme)
7
- */
8
- class Kirki_Color {
9
-
10
- /**
11
- * Sanitises a HEX value.
12
- * The way this works is by splitting the string in 6 substrings.
13
- * Each sub-string is individually sanitized, and the result is then returned.
14
- *
15
- * @var string The hex value of a color
16
- * @param boolean Whether we want to include a hash (#) at the beginning or not
17
- * @return string The sanitized hex color.
18
- */
19
- public static function sanitize_hex( $color = '#FFFFFF', $hash = true ) {
20
-
21
- // Remove any spaces and special characters before and after the string
22
- $color = trim( $color. ' \t\n\r\0\x0B' );
23
-
24
- // Remove any trailing '#' symbols from the color value
25
- $color = str_replace( '#', '', $color );
26
-
27
- // If the string is 6 characters long then use it in pairs.
28
- if ( 3 == strlen( $color ) ) {
29
- $color = substr( $color, 0, 1 ) . substr( $color, 0, 1 ) . substr( $color, 1, 1 ) . substr( $color, 1, 1 ) . substr( $color, 2, 1 ) . substr( $color, 2, 1 );
30
- }
31
-
32
- $substr = array();
33
- for ( $i = 0; $i <= 5; $i++ ) {
34
- $default = ( 0 == $i ) ? 'F' : ( $substr[$i-1] );
35
- $substr[$i] = substr( $color, $i, 1 );
36
- $substr[$i] = ( false === $substr[$i] || ! ctype_xdigit( $substr[$i] ) ) ? $default : $substr[$i];
37
- }
38
- $hex = implode( '', $substr );
39
-
40
- return ( ! $hash ) ? $hex : '#' . $hex;
41
-
42
- }
43
-
44
- /**
45
- * Gets the rgb value of the $hex color.
46
- *
47
- * @var string The hex value of a color
48
- * @param boolean Whether we want to implode the values or not
49
- * @return mixed array|string
50
- */
51
- public static function get_rgb( $hex, $implode = false ) {
52
-
53
- // Remove any trailing '#' symbols from the color value
54
- $hex = self::sanitize_hex( $hex, false );
55
-
56
- $red = hexdec( substr( $hex, 0, 2 ) );
57
- $green = hexdec( substr( $hex, 2, 2 ) );
58
- $blue = hexdec( substr( $hex, 4, 2 ) );
59
-
60
- // rgb is an array
61
- $rgb = array( $red, $green, $blue );
62
-
63
- return ( $implode ) ? implode( ',', $rgb ) : $rgb;
64
-
65
- }
66
-
67
- /**
68
- * Gets the rgb value of the $hex color.
69
- *
70
- * @var string The hex value of a color
71
- * @param int Opacity level (1-100)
72
- * @return string
73
- */
74
- public static function get_rgba( $hex = '#fff', $opacity = 100 ) {
75
-
76
- $hex = self::sanitize_hex( $hex, false );
77
- // Make sure that opacity is properly formatted :
78
- // Set the opacity to 100 if a larger value has been entered by mistake.
79
- // If a negative value is used, then set to 0.
80
- // If an opacity value is entered in a decimal form (for example 0.25), then multiply by 100.
81
- if ( $opacity >= 100 ) {
82
- $opacity = 100;
83
- } elseif ( $opacity < 0 ) {
84
- $opacity = 0;
85
- } elseif ( $opacity < 1 && $opacity != 0 ) {
86
- $opacity = ( $opacity * 100 );
87
- } else {
88
- $opacity = $opacity;
89
- }
90
-
91
- // Divide the opacity by 100 to end-up with a CSS value for the opacity
92
- $opacity = ( $opacity / 100 );
93
-
94
- $color = 'rgba(' . self::get_rgb( $hex, true ) . ', ' . $opacity . ')';
95
-
96
- return $color;
97
-
98
- }
99
-
100
- /**
101
- * Gets the brightness of the $hex color.
102
- *
103
- * @var string The hex value of a color
104
- * @return int value between 0 and 255
105
- */
106
- public static function get_brightness( $hex ) {
107
-
108
- $hex = self::sanitize_hex( $hex, false );
109
- // returns brightness value from 0 to 255
110
-
111
- $red = hexdec( substr( $hex, 0, 2 ) );
112
- $green = hexdec( substr( $hex, 2, 2 ) );
113
- $blue = hexdec( substr( $hex, 4, 2 ) );
114
-
115
- return ( ( $red * 299 ) + ( $green * 587 ) + ( $blue * 114 ) ) / 1000;
116
-
117
- }
118
-
119
- /**
120
- * Adjusts brightness of the $hex color.
121
- *
122
- * @var string The hex value of a color
123
- * @param int a value between -255 (darken) and 255 (lighten)
124
- * @return string returns hex color
125
- */
126
- public static function adjust_brightness( $hex, $steps ) {
127
-
128
- $hex = self::sanitize_hex( $hex, false );
129
- // Steps should be between -255 and 255. Negative = darker, positive = lighter
130
- $steps = max( -255, min( 255, $steps ) );
131
-
132
- // Get decimal values
133
- $red = hexdec( substr( $hex, 0, 2 ) );
134
- $green = hexdec( substr( $hex, 2, 2 ) );
135
- $blue = hexdec( substr( $hex, 4, 2 ) );
136
-
137
- // Adjust number of steps and keep it inside 0 to 255
138
- $red = max( 0, min( 255, $red + $steps ) );
139
- $green = max( 0, min( 255, $green + $steps ) );
140
- $blue = max( 0, min( 255, $blue + $steps ) );
141
-
142
- $red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
143
- $green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
144
- $blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
145
-
146
- return self::sanitize_hex( $red_hex . $green_hex . $blue_hex );
147
-
148
- }
149
-
150
- /**
151
- * Mixes 2 hex colors.
152
- * the "percentage" variable is the percent of the first color
153
- * to be used it the mix. default is 50 (equal mix)
154
- *
155
- * @var string The hex value of color 1
156
- * @var string The hex value of color 2
157
- * @param int a value between 0 and 100
158
- * @return string returns hex color
159
- */
160
- public static function mix_colors( $hex1, $hex2, $percentage ) {
161
-
162
- $hex1 = self::sanitize_hex( $hex1, false );
163
- $hex2 = self::sanitize_hex( $hex2, false );
164
-
165
- // Get decimal values
166
- $red_1 = hexdec( substr( $hex1, 0, 2 ) );
167
- $green_1 = hexdec( substr( $hex1, 2, 2 ) );
168
- $blue_1 = hexdec( substr( $hex1, 4, 2 ) );
169
- $red_2 = hexdec( substr( $hex2, 0, 2 ) );
170
- $green_2 = hexdec( substr( $hex2, 2, 2 ) );
171
- $blue_2 = hexdec( substr( $hex2, 4, 2 ) );
172
-
173
- $red = ( $percentage * $red_1 + ( 100 - $percentage ) * $red_2 ) / 100;
174
- $green = ( $percentage * $green_1 + ( 100 - $percentage ) * $green_2 ) / 100;
175
- $blue = ( $percentage * $blue_1 + ( 100 - $percentage ) * $blue_2 ) / 100;
176
-
177
- $red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
178
- $green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
179
- $blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
180
-
181
- return self::sanitize_hex( $red_hex . $green_hex . $blue_hex );
182
-
183
- }
184
-
185
- /**
186
- * Convert hex color to hsv
187
- *
188
- * @var string The hex value of color 1
189
- * @return array returns array( 'h', 's', 'v' )
190
- */
191
- public static function hex_to_hsv( $hex ) {
192
-
193
- $hex = self::sanitize_hex( $hex, false );
194
- $rgb = self::get_rgb( $hex );
195
- $hsv = self::rgb_to_hsv( $rgb );
196
-
197
- return $hsv;
198
-
199
- }
200
-
201
- /**
202
- * Convert hex color to hsv
203
- *
204
- * @var array The rgb color to conver array( 'r', 'g', 'b' )
205
- * @return array returns array( 'h', 's', 'v' )
206
- */
207
- public static function rgb_to_hsv( $color = array() ) {
208
- $r = $color[0];
209
- $g = $color[1];
210
- $b = $color[2];
211
-
212
- $hsl = array();
213
-
214
- $var_r = ( $r / 255 );
215
- $var_g = ( $g / 255 );
216
- $var_b = ( $b / 255 );
217
-
218
- $var_min = min( $var_r, $var_g, $var_b);
219
- $var_max = max( $var_r, $var_g, $var_b);
220
- $del_max = $var_max - $var_min;
221
-
222
- $v = $var_max;
223
-
224
- if ( $del_max == 0 ) {
225
- $h = 0;
226
- $s = 0;
227
- } else {
228
- $s = $del_max / $var_max;
229
-
230
- $del_r = ( ( ( $var_max - $var_r ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
231
- $del_g = ( ( ( $var_max - $var_g ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
232
- $del_b = ( ( ( $var_max - $var_b ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
233
-
234
- if ( $var_r == $var_max ) {
235
- $h = $del_b - $del_g;
236
- } elseif ( $var_g == $var_max ) {
237
- $h = ( 1 / 3 ) + $del_r - $del_b;
238
- } elseif ( $var_b == $var_max ) {
239
- $h = ( 2 / 3 ) + $del_g - $del_r;
240
- }
241
-
242
- if ( $h < 0 ) {
243
- $h++;
244
- }
245
-
246
- if ( $h > 1 ) {
247
- $h--;
248
- }
249
- }
250
-
251
- $hsl['h'] = $h;
252
- $hsl['s'] = $s;
253
- $hsl['v'] = $v;
254
-
255
- return $hsl;
256
- }
257
-
258
- /**
259
- * Get the brightest color from an array of colors.
260
- * Return the key of the array if $context = 'key'
261
- * Return the hex value of the color if $context = 'value'
262
- *
263
- * @var array flat array of hex colors
264
- * @param string 'key' or 'value'
265
- * @return mixed int|string
266
- */
267
- public static function brightest_color( $colors = array(), $context = 'key' ) {
268
-
269
- $brightest = false;
270
-
271
- foreach ( $colors as $color ) {
272
- $color = self::sanitize_hex( $color, false );
273
- $brightness = self::get_brightness( $color );
274
-
275
- if ( ! $brightest || self::get_brightness( $color ) > self::get_brightness( $brightest ) ) {
276
- $brightest = $color;
277
- }
278
- }
279
-
280
- if ( $context == 'key' ) {
281
- return array_search( $brightest, $colors );
282
- } elseif ( $context == 'value' ) {
283
- return $brightest;
284
- }
285
-
286
- }
287
-
288
- /*
289
- * Get the most saturated color from an array of colors.
290
- * Return the key of the array if $context = 'key'
291
- * Return the hex value of the color if $context = 'value'
292
- */
293
- public static function most_saturated_color( $colors = array(), $context = 'key' ) {
294
-
295
- $most_saturated = false;
296
-
297
- foreach ( $colors as $color ) {
298
- $color = self::sanitize_hex( $color, false );
299
- $hsv = self::hex_to_hsv( $hex );
300
- $saturation = $hsv['s'];
301
-
302
- if ( $most_saturated ) {
303
- $hsv_old = self::hex_to_hsv( $most_saturated );
304
- }
305
-
306
- if ( ! $most_saturated || $saturation > $hsv_old['s'] ) {
307
- $most_saturated = $hex;
308
- }
309
- }
310
-
311
- if ( $context == 'key' ) {
312
- return array_search( $most_saturated, $colors );
313
- } elseif ( $context == 'value' ) {
314
- return $most_saturated;
315
- }
316
-
317
- }
318
-
319
- /*
320
- * Get the most intense color from an array of colors.
321
- * Return the key of the array if $context = 'key'
322
- * Return the hex value of the color if $context = 'value'
323
- */
324
- public static function most_intense_color( $colors = array(), $context = 'key' ) {
325
-
326
- $most_intense = false;
327
-
328
- foreach ( $colors as $color ) {
329
- $color = self::sanitize_hex( $color, false );
330
- $hsv = self::hex_to_hsv( $hex );
331
- $saturation = $hsv['s'];
332
-
333
- if ( $most_intense ) {
334
- $hsv_old = self::hex_to_hsv( $most_intense );
335
- }
336
-
337
- if ( ! $most_intense || $saturation > $hsv_old['s'] ) {
338
- $most_intense = $hex;
339
- }
340
- }
341
-
342
- if ( $context == 'key' ) {
343
- return array_search( $most_intense, $colors );
344
- } elseif ( $context == 'value' ) {
345
- return $most_intense;
346
- }
347
-
348
- }
349
-
350
- /*
351
- * Get the brightest color from an array of colors.
352
- * Return the key of the array if $context = 'key'
353
- * Return the hex value of the color if $context = 'value'
354
- */
355
- public static function brightest_dull_color( $colors = array(), $context = 'key' ) {
356
-
357
- $brightest_dull = false;
358
-
359
- foreach ( $colors as $color ) {
360
- $color = self::sanitize_hex( $color, false );
361
- $hsv = self::hex_to_hsv( $hex );
362
-
363
- $brightness = self::get_brightness( $hex );
364
- // Prevent "division by zero" messages.
365
- $hsv['s'] = ( $hsv['s'] == 0 ) ? 0.0001 : $hsv['s'];
366
- $dullness = 1 / $hsv['s'];
367
-
368
- if ( $brightest_dull ) {
369
- $hsv_old = self::hex_to_hsv( $brightest_dull );
370
- // Prevent "division by zero" messages.
371
- $hsv_old['s'] = ( $hsv_old['s'] == 0 ) ? 0.0001 : $hsv_old['s'];
372
- $dullness_old = 1 / $hsv_old['s'];
373
- }
374
-
375
- if ( ! $brightest_dull || self::get_brightness( $hex ) * $dullness > self::get_brightness( $brightest_dull ) * $dullness_old ) {
376
- $brightest_dull = $hex;
377
- }
378
- }
379
-
380
- if ( $context == 'key' ) {
381
- return array_search( $brightest_dull, $colors );
382
- } elseif ( $context == 'value' ) {
383
- return $brightest_dull;
384
- }
385
-
386
- }
387
-
388
- /*
389
- * This is a very simple algorithm that works by summing up the differences between the three color components red, green and blue.
390
- * A value higher than 500 is recommended for good readability.
391
- */
392
- public static function color_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
393
-
394
- $color_1 = self::sanitize_hex( $color_1, false );
395
- $color_2 = self::sanitize_hex( $color_2, flase );
396
-
397
- $color_1_rgb = self::get_rgb( $color_1 );
398
- $color_2_rgb = self::get_rgb( $color_2 );
399
-
400
- $r1 = $color_1_rgb[0];
401
- $g1 = $color_1_rgb[1];
402
- $b1 = $color_1_rgb[2];
403
-
404
- $r2 = $color_2_rgb[0];
405
- $g2 = $color_2_rgb[1];
406
- $b2 = $color_2_rgb[2];
407
-
408
- $r_diff = max( $r1, $r2 ) - min( $r1, $r2 );
409
- $g_diff = max( $g1, $g2 ) - min( $g1, $g2 );
410
- $b_diff = max( $b1, $b2 ) - min( $b1, $b2 );
411
-
412
- $color_diff = $r_diff + $g_diff + $b_diff;
413
-
414
- return $color_diff;
415
-
416
- }
417
-
418
- /*
419
- * This function tries to compare the brightness of the colors.
420
- * A return value of more than 125 is recommended.
421
- * Combining it with the color_difference function above might make sense.
422
- */
423
- public static function brightness_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
424
-
425
- $color_1 = self::sanitize_hex( $color_1, false );
426
- $color_2 = self::sanitize_hex( $color_2, false );
427
-
428
- $color_1_rgb = self::get_rgb( $color_1 );
429
- $color_2_rgb = self::get_rgb( $color_2 );
430
-
431
- $r1 = $color_1_rgb[0];
432
- $g1 = $color_1_rgb[1];
433
- $b1 = $color_1_rgb[2];
434
-
435
- $r2 = $color_2_rgb[0];
436
- $g2 = $color_2_rgb[1];
437
- $b2 = $color_2_rgb[2];
438
-
439
- $br_1 = ( 299 * $r1 + 587 * $g1 + 114 * $b1 ) / 1000;
440
- $br_2 = ( 299 * $r2 + 587 * $g2 + 114 * $b2 ) / 1000;
441
-
442
- return abs( $br_1 - $br_2 );
443
-
444
- }
445
-
446
- /*
447
- * Uses the luminosity to calculate the difference between the given colors.
448
- * The returned value should be bigger than 5 for best readability.
449
- */
450
- public static function lumosity_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
451
-
452
- $color_1 = self::sanitize_hex( $color_1, false );
453
- $color_2 = self::sanitize_hex( $color_2, false );
454
-
455
- $color_1_rgb = self::get_rgb( $color_1 );
456
- $color_2_rgb = self::get_rgb( $color_2 );
457
-
458
- $r1 = $color_1_rgb[0];
459
- $g1 = $color_1_rgb[1];
460
- $b1 = $color_1_rgb[2];
461
-
462
- $r2 = $color_2_rgb[0];
463
- $g2 = $color_2_rgb[1];
464
- $b2 = $color_2_rgb[2];
465
-
466
- $l1 = 0.2126 * pow( $r1 / 255, 2.2 ) + 0.7152 * pow( $g1 / 255, 2.2 ) + 0.0722 * pow( $b1 / 255, 2.2 );
467
- $l2 = 0.2126 * pow( $r2 / 255, 2.2 ) + 0.7152 * pow( $g2 / 255, 2.2 ) + 0.0722 * pow( $b2 / 255, 2.2 );
468
-
469
- $lum_diff = ( $l1 > $l2 ) ? ( $l1 + 0.05 ) / ( $l2 + 0.05 ) : ( $l2 + 0.05 ) / ( $l1 + 0.05 );
470
-
471
- return $lum_diff;
472
-
473
- }
474
-
475
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/libraries/class-kirki-colourlovers.php DELETED
@@ -1,189 +0,0 @@
1
- <?php
2
-
3
- class Kirki_Colourlovers {
4
-
5
- public static function get_palettes( $palettes_nr = 5, $order_by = 'none', $xml = '' ) {
6
-
7
- $palettes = self::parse( $xml );
8
- $palettes = array_slice( $palettes, 0, $palettes_nr );
9
-
10
- $final_palettes = array();
11
-
12
- foreach ( $palettes as $palette ) {
13
- $final_palettes[] = self::order_by( $palette, $order_by );
14
- }
15
-
16
- return $final_palettes;
17
-
18
- }
19
-
20
- public static function parse( $xml = null ) {
21
-
22
- // XML copied from http://www.colourlovers.com/api/palettes/top?numResults=100
23
- $root = ( '' != $config['url_path'] ) ? $config['url_path'] : KIRKI_URL;
24
- $xml_url = ( is_null( $xml ) ) ? trailingslashit( $root ) . 'assets/xml/colourlovers-top.xml' : $xml;
25
- $feed_xml = simplexml_load_file( $xml_url );
26
- $palettes = array();
27
-
28
- foreach( $feed_xml->palette as $result ) {
29
- $id = $result->id;
30
- $content = $result->content;
31
- $title = $result->title;
32
- $badgeurl = $result->badgeUrl;
33
- $imageurl = $result->imageUrl;
34
- $palette = (array) $result->colors->hex;
35
-
36
- $palettes[] = $palette;
37
-
38
- }
39
-
40
- return $palettes;
41
-
42
- }
43
-
44
- public static function order_by( $palette = array(), $order = 'none' ) {
45
-
46
- $palette = ( empty( $palette ) ) ? array() : $palette;
47
-
48
- if ( 'none' == $order ) {
49
-
50
- $palette = array(
51
- Kirki_Color::sanitize_hex( $palette[0] ),
52
- Kirki_Color::sanitize_hex( $palette[1] ),
53
- Kirki_Color::sanitize_hex( $palette[2] ),
54
- Kirki_Color::sanitize_hex( $palette[3] ),
55
- Kirki_Color::sanitize_hex( $palette[4] ),
56
-
57
- );
58
-
59
- } elseif ( 'brightness' == $order ) {
60
-
61
- // Get the ligtness of all the colors in our palette and arrange them according to it.
62
- $colors_array_0b = $palette;
63
- $brightest_0_key = Kirki_Color::brightest_color( $colors_array_0b, 'key' );
64
- $brightest_0_val = Kirki_Color::brightest_color( $colors_array_0b, 'value' );
65
-
66
- $colors_array_1b = kirki_array_delete( $brightest_0_key, $colors_array_0b );
67
- $brightest_1_key = Kirki_Color::brightest_color( $colors_array_1b, 'key' );
68
- $brightest_1_val = Kirki_Color::brightest_color( $colors_array_1b, 'value' );
69
-
70
- $colors_array_2b = kirki_array_delete( $brightest_1_key, $colors_array_1b );
71
- $brightest_2_key = Kirki_Color::brightest_color( $colors_array_2b, 'key' );
72
- $brightest_2_val = Kirki_Color::brightest_color( $colors_array_2b, 'value' );
73
-
74
- $colors_array_3b = kirki_array_delete( $brightest_2_key, $colors_array_2b );
75
- $brightest_3_key = Kirki_Color::brightest_color( $colors_array_3b, 'key' );
76
- $brightest_3_val = Kirki_Color::brightest_color( $colors_array_3b, 'value' );
77
-
78
- $colors_array_4b = kirki_array_delete( $brightest_3_key, $colors_array_3b );
79
- $brightest_4_key = Kirki_Color::brightest_color( $colors_array_4b, 'key' );
80
- $brightest_4_val = Kirki_Color::brightest_color( $colors_array_4b, 'value' );
81
-
82
- $palette = array(
83
- Kirki_Color::sanitize_hex( $brightest_0_val ),
84
- Kirki_Color::sanitize_hex( $brightest_1_val ),
85
- Kirki_Color::sanitize_hex( $brightest_2_val ),
86
- Kirki_Color::sanitize_hex( $brightest_3_val ),
87
- Kirki_Color::sanitize_hex( $brightest_4_val ),
88
- );
89
-
90
- } elseif ( 'saturation' == $order ) {
91
-
92
- // Get the saturation of all the colors in our palette and arrange them according to it.
93
- $colors_array_0s = $palette;
94
- $most_saturated_0_key = Kirki_Color::most_saturated_color( $colors_array_0s, 'key' );
95
- $most_saturated_0_val = Kirki_Color::most_saturated_color( $colors_array_0s, 'value' );
96
-
97
- $colors_array_1s = kirki_array_delete( $most_saturated_0_key, $colors_array_0s );
98
- $most_saturated_1_key = Kirki_Color::most_saturated_color( $colors_array_1s, 'key' );
99
- $most_saturated_1_val = Kirki_Color::most_saturated_color( $colors_array_1s, 'value' );
100
-
101
- $colors_array_2s = kirki_array_delete( $most_saturated_1_key, $colors_array_1s );
102
- $most_saturated_2_key = Kirki_Color::most_saturated_color( $colors_array_2s, 'key' );
103
- $most_saturated_2_val = Kirki_Color::most_saturated_color( $colors_array_2s, 'value' );
104
-
105
- $colors_array_3s = kirki_array_delete( $most_saturated_2_key, $colors_array_2s );
106
- $most_saturated_3_key = Kirki_Color::most_saturated_color( $colors_array_3s, 'key' );
107
- $most_saturated_3_val = Kirki_Color::most_saturated_color( $colors_array_3s, 'value' );
108
-
109
- $colors_array_4s = kirki_array_delete( $most_saturated_3_key, $colors_array_3s );
110
- $most_saturated_3_key = Kirki_Color::most_saturated_color( $colors_array_4s, 'key' );
111
- $most_saturated_4_val = Kirki_Color::most_saturated_color( $colors_array_4s, 'value' );
112
-
113
- $palette = array(
114
- Kirki_Color::sanitize_hex( $most_saturated_0_val ),
115
- Kirki_Color::sanitize_hex( $most_saturated_1_val ),
116
- Kirki_Color::sanitize_hex( $most_saturated_2_val ),
117
- Kirki_Color::sanitize_hex( $most_saturated_3_val ),
118
- Kirki_Color::sanitize_hex( $most_saturated_4_val ),
119
- );
120
-
121
- } elseif ( 'intensity' == $order ) {
122
-
123
- // Get the intensity of all the colors in our palette and arrange them according to it.
124
- $colors_array_0i = $palette;
125
- $most_intense_0_key = Kirki_Color::most_intense_color( $colors_array_0i, 'key' );
126
- $most_intense_0_val = Kirki_Color::most_intense_color( $colors_array_0i, 'value' );
127
-
128
- $colors_array_1i = kirki_array_delete( $most_intense_0_key, $colors_array_0i );
129
- $most_intense_1_key = Kirki_Color::most_intense_color( $colors_array_1i, 'key' );
130
- $most_intense_1_val = Kirki_Color::most_intense_color( $colors_array_1i, 'value' );
131
-
132
- $colors_array_2i = kirki_array_delete( $most_intense_1_key, $colors_array_1i );
133
- $most_intense_2_key = Kirki_Color::most_intense_color( $colors_array_2i, 'key' );
134
- $most_intense_2_val = Kirki_Color::most_intense_color( $colors_array_2i, 'value' );
135
-
136
- $colors_array_3i = kirki_array_delete( $most_intense_2_key, $colors_array_2i );
137
- $most_intense_3_key = Kirki_Color::most_intense_color( $colors_array_3i, 'key' );
138
- $most_intense_3_val = Kirki_Color::most_intense_color( $colors_array_3i, 'value' );
139
-
140
- $colors_array_4i = kirki_array_delete( $most_intense_3_key, $colors_array_3i );
141
- $most_intense_3_key = Kirki_Color::most_intense_color( $colors_array_4i, 'key' );
142
- $most_intense_4_val = Kirki_Color::most_intense_color( $colors_array_4i, 'value' );
143
-
144
- $palette = array(
145
- Kirki_Color::sanitize_hex( $most_intense_0_val ),
146
- Kirki_Color::sanitize_hex( $most_intense_1_val ),
147
- Kirki_Color::sanitize_hex( $most_intense_2_val ),
148
- Kirki_Color::sanitize_hex( $most_intense_3_val ),
149
- Kirki_Color::sanitize_hex( $most_intense_4_val ),
150
- );
151
-
152
- } elseif ( 'dullness' == $order ) {
153
-
154
- // Get the lightness and "dullness" of all the colors in our palette and arrange them according to it.
155
- $colors_array_0d = $palette;
156
- $bright_dull_0_key = Kirki_Color::brightest_dull_color( $colors_array_0d, 'key' );
157
- $bright_dull_0_val = Kirki_Color::brightest_dull_color( $colors_array_0d, 'value' );
158
-
159
- $colors_array_1d = kirki_array_delete( $bright_dull_0_key, $colors_array_0d );
160
- $bright_dull_1_key = Kirki_Color::brightest_dull_color( $colors_array_1d, 'key' );
161
- $bright_dull_1_val = Kirki_Color::brightest_dull_color( $colors_array_1d, 'value' );
162
-
163
- $colors_array_2d = kirki_array_delete( $bright_dull_1_key, $colors_array_1d );
164
- $bright_dull_2_key = Kirki_Color::brightest_dull_color( $colors_array_2d, 'key' );
165
- $bright_dull_2_val = Kirki_Color::brightest_dull_color( $colors_array_2d, 'value' );
166
-
167
- $colors_array_3d = kirki_array_delete( $bright_dull_2_key, $colors_array_2d );
168
- $bright_dull_3_key = Kirki_Color::brightest_dull_color( $colors_array_3d, 'key' );
169
- $bright_dull_3_val = Kirki_Color::brightest_dull_color( $colors_array_3d, 'value' );
170
-
171
- $colors_array_4d = kirki_array_delete( $bright_dull_3_key, $colors_array_3d );
172
- $bright_dull_3_key = Kirki_Color::brightest_dull_color( $colors_array_4d, 'key' );
173
- $bright_dull_4_val = Kirki_Color::brightest_dull_color( $colors_array_4d, 'value' );
174
-
175
- $palette = array(
176
- Kirki_Color::sanitize_hex( $bright_dull_0_val ),
177
- Kirki_Color::sanitize_hex( $bright_dull_1_val ),
178
- Kirki_Color::sanitize_hex( $bright_dull_2_val ),
179
- Kirki_Color::sanitize_hex( $bright_dull_3_val ),
180
- Kirki_Color::sanitize_hex( $bright_dull_4_val ),
181
- );
182
-
183
- }
184
-
185
- return $palette;
186
-
187
- }
188
-
189
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/sanitize.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Sanitize checkbox options
5
- *
6
- * @since 0.5
7
- */
8
- function kirki_sanitize_checkbox( $value ) {
9
- return ( 'on' != $value ) ? false : $value;
10
- }
11
-
12
- /**
13
- * Sanitize number options
14
- *
15
- * @since 0.5
16
- */
17
- function kirki_sanitize_number( $value ) {
18
- return ( is_int( $value ) || is_float( $value ) ) ? $value : intval( $value );
19
- }
20
-
21
- /**
22
- * Sanitize a value from a list of allowed values.
23
- *
24
- * @since 0.5
25
- *
26
- * @param mixed $input The value to sanitize.
27
- * @param mixed $setting The setting for which the sanitizing is occurring.
28
- */
29
- function kirki_sanitize_choice( $input, $setting ) {
30
-
31
- global $wp_customize;
32
- $field = $wp_customize->get_control( $setting->id );
33
-
34
- return ( array_key_exists( $input, $field->choices ) ) ? $input : $setting->default;
35
-
36
- }
37
-
38
- /**
39
- * Sanitize background repeat values
40
- *
41
- * @since 0.5
42
- */
43
- function kirki_sanitize_bg_repeat( $value ) {
44
- $i18n = Kirki::i18n();
45
- $valid = array(
46
- 'no-repeat' => $i18n['no-repeat'],
47
- 'repeat' => $i18n['repeat-all'],
48
- 'repeat-x' => $i18n['repeat-x'],
49
- 'repeat-y' => $i18n['repeat-y'],
50
- 'inherit' => $i18n['inherit'],
51
- );
52
-
53
- return ( array_key_exists( $value, $valid ) ) ? $value : 'inherit';
54
-
55
- }
56
-
57
- /**
58
- * Sanitize background size values
59
- *
60
- * @since 0.5
61
- */
62
- function kirki_sanitize_bg_size( $value ) {
63
- $i18n = Kirki::i18n();
64
- $valid = array(
65
- 'inherit' => $i18n['inherit'],
66
- 'cover' => $i18n['cover'],
67
- 'contain' => $i18n['contain'],
68
- );
69
-
70
- return ( array_key_exists( $value, $valid ) ) ? $value : 'inherit';
71
-
72
- }
73
-
74
- /**
75
- * Sanitize background attachment values
76
- *
77
- * @since 0.5
78
- */
79
- function kirki_sanitize_bg_attach( $value ) {
80
- $i18n = Kirki::i18n();
81
- $valid = array(
82
- 'inherit' => $i18n['inherit'],
83
- 'fixed' => $i18n['fixed'],
84
- 'scroll' => $i18n['scroll'],
85
- );
86
-
87
- return ( array_key_exists( $value, $valid ) ) ? $value : 'inherit';
88
-
89
- }
90
-
91
- /**
92
- * Sanitize background position values
93
- *
94
- * @since 0.5
95
- */
96
- function kirki_sanitize_bg_position( $value ) {
97
- $i18n = Kirki::i18n();
98
- $valid = array(
99
- 'left-top' => $i18n['left-top'],
100
- 'left-center' => $i18n['left-center'],
101
- 'left-bottom' => $i18n['left-bottom'],
102
- 'right-top' => $i18n['right-top'],
103
- 'right-center' => $i18n['right-center'],
104
- 'right-bottom' => $i18n['right-bottom'],
105
- 'center-top' => $i18n['center-top'],
106
- 'center-center' => $i18n['center-center'],
107
- 'center-bottom' => $i18n['center-bottom'],
108
- );
109
-
110
- return ( array_key_exists( $value, $valid ) ) ? $value : 'center-center';
111
-
112
- }
113
-
114
- /**
115
- * Sanitize sortable controls
116
- *
117
- * @since 0.8.3
118
- */
119
-
120
- function kirki_sanitize_sortable( $value ) {
121
- if ( is_serialized( $value ) ) {
122
- return $value;
123
- } else {
124
- return serialize( $value );
125
- }
126
- }
127
- /**
128
- * DOES NOT SANITIZE ANYTHING.
129
- *
130
- * @since 0.5
131
- */
132
- function kirki_sanitize_unfiltered( $value ) {
133
- return $value;
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Kirki.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
-
3
- use Kirki\Fonts\FontRegistry;
4
- use Kirki\Scripts\ScriptRegistry;
5
- use Kirki\Config;
6
- use Kirki\Styles;
7
- use Kirki\Fields;
8
- use Kirki\Builder;
9
-
10
- spl_autoload_register( function( $class ) {
11
- if ( stripos( $class, 'Kirki' ) === 0 ) {
12
- @include( KIRKI_PATH . DIRECTORY_SEPARATOR . 'includes' . str_replace( '\\', DIRECTORY_SEPARATOR, substr( $class, strlen( 'Kirki' ) ) ) . '.php' );
13
- }
14
- });
15
-
16
- /**
17
- * Class Kirki
18
- *
19
- * The main Kirki object
20
- */
21
- class Kirki {
22
-
23
- /** @var Kirki The only instance of this class */
24
- public static $instance = null;
25
-
26
- /** @var string Version number */
27
- public static $version = '0.8.4';
28
-
29
- /** @var Config Configuration */
30
- public $config = null;
31
-
32
- /** @var FontRegistry The font registry */
33
- public $font_registry = null;
34
-
35
- /** @var scripts */
36
- public $scripts = null;
37
-
38
- /** @var field */
39
- public $fields = null;
40
-
41
- /**
42
- * Access the single instance of this class
43
- * @return Kirki
44
- */
45
- public static function get_instance() {
46
- if ( self::$instance==null ) {
47
- self::$instance = new Kirki();
48
- }
49
- return self::$instance;
50
- }
51
-
52
- /**
53
- * Shortcut method to call the Field class
54
- */
55
- public static function fields() {
56
- return self::get_instance()->fields;
57
- }
58
-
59
- /**
60
- * Shortcut method to get the configuration of the single instance.
61
- */
62
- public static function config() {
63
- return self::get_instance()->config;
64
- }
65
-
66
- /**
67
- * Shortcut method to get the translation strings
68
- */
69
- public static function i18n() {
70
- $config = self::config();
71
- $options = $config->get_all();
72
- return $options['i18n'];
73
- }
74
-
75
- /**
76
- * Shortcut method to get the font registry.
77
- */
78
- public static function fonts() {
79
- return self::get_instance()->font_registry;
80
- }
81
-
82
- /**
83
- * Constructor is private, should only be called by get_instance()
84
- */
85
- private function __construct() {
86
-
87
- // Create our main objects
88
- $this->font_registry = new FontRegistry();
89
- $this->config = new Config();
90
- $this->fields = new Fields();
91
- $this->scripts = new ScriptRegistry();
92
- $this->styles = new Styles();
93
-
94
- // Hook into WP
95
- $init = new Builder();
96
-
97
- }
98
-
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/Branding.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
- use Kirki\Scripts\ScriptRegistry;
8
-
9
- class Branding extends EnqueueScript {
10
-
11
- /**
12
- * If we've specified an image to be used as logo,
13
- * replace the default theme description with a div that will include our logo.
14
- */
15
- public function customize_controls_print_scripts() {
16
-
17
- $options = Kirki::config()->get_all();
18
- $script = '';
19
- if ( '' != $options['logo_image'] || '' != $options['description'] ) {
20
-
21
- if ( '' != $options['logo_image'] ) {
22
- $script .= '$( \'div#customize-info .preview-notice\' ).replaceWith( \'<img src="' . $options['logo_image'] . '">\' );';
23
- }
24
- if ( '' != $options['description'] ) {
25
- $script .= '$( \'div#customize-info .accordion-section-content\' ).replaceWith( \'<div class="accordion-section-content"><div class="theme-description">' . $options['description'] . '</div></div>\' );';
26
- }
27
-
28
- }
29
-
30
- if ( '' != $script ) {
31
- echo ScriptRegistry::prepare( $script );
32
- }
33
-
34
- }
35
-
36
- public function customize_controls_enqueue_scripts() {}
37
-
38
- public function customize_controls_print_footer_scripts() {}
39
-
40
- public function wp_footer() {}
41
-
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/Dependencies.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
-
8
- class Dependencies extends EnqueueScript {
9
-
10
- /**
11
- * Enqueue the scripts required.
12
- */
13
- public function customize_controls_enqueue_scripts() {
14
-
15
- $config = Kirki::config()->get_all();
16
- $kirki_url = ( '' != $config['url_path'] )? $config['url_path'] : KIRKI_URL;
17
-
18
- wp_enqueue_script( 'kirki_customizer_js', trailingslashit( $kirki_url ) . 'assets/js/customizer.js', array( 'jquery', 'customize-controls' ) );
19
- wp_enqueue_script( 'serialize-js', trailingslashit( $kirki_url ) . 'assets/js/serialize.js' );
20
- wp_enqueue_script( 'jquery-stepper-min-js', trailingslashit( $kirki_url ) . 'assets/js/jquery.fs.stepper.min.js', array( 'jquery' ) );
21
- wp_enqueue_script( 'jquery-ui-core' );
22
- wp_enqueue_script( 'jquery-ui-tooltip' );
23
- wp_enqueue_script( 'jquery-stepper-min-js' );
24
-
25
- }
26
-
27
- public function customize_controls_print_scripts() {}
28
-
29
- public function customize_controls_print_footer_scripts() {}
30
-
31
- public function wp_footer() {}
32
-
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/PostMessage.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
- use Kirki\Scripts\ScriptRegistry;
8
-
9
- class PostMessage extends EnqueueScript {
10
-
11
- /**
12
- * Try to automatically generate the script necessary for postMessage to work.
13
- * Something like this will have to be added to the control arguments:
14
- *
15
-
16
- 'transport' => 'postMessage',
17
- 'js_vars' => array(
18
- array(
19
- 'element' => 'body',
20
- 'function' => 'css',
21
- 'property' => 'color',
22
- ),
23
- array(
24
- 'element' => '#content',
25
- 'function' => 'css',
26
- 'property' => 'background-color',
27
- ),
28
- array(
29
- 'element' => 'body',
30
- 'function' => 'html',
31
- )
32
- )
33
- *
34
- */
35
- public function wp_footer() {
36
-
37
- global $wp_customize;
38
- // Early exit if we're not in the customizer
39
- if ( ! isset( $wp_customize ) ) {
40
- return;
41
- }
42
-
43
- $fields = Kirki::fields()->get_all();
44
- $script = '';
45
- foreach ( $fields as $field ) {
46
- if ( isset( $field['transport'] ) && ! is_null( $field['js_vars'] ) && 'postMessage' == $field['transport'] ) {
47
- foreach ( $field['js_vars'] as $js_vars ) {
48
- $script .= 'wp.customize( \'' . $field['settings'] . '\', function( value ) {';
49
- $script .= 'value.bind( function( newval ) {';
50
- if ( 'html' == $js_vars['function'] ) {
51
- $script .= '$( \'' . esc_js( $js_vars["element"] ) . '\' ).html( newval );';
52
- } elseif ( 'css' == $js_vars['function'] ) {
53
- $script .= '$(\'' . esc_js( $js_vars["element"] ) . '\').css(\'' . esc_js( $js_vars["property"] ) . '\', newval );';
54
- }
55
- $script .= '}); });';
56
- }
57
- }
58
- }
59
-
60
- if ( '' != $script ) {
61
- echo ScriptRegistry::prepare( $script );
62
- }
63
-
64
- }
65
-
66
- public function customize_controls_print_scripts() {}
67
-
68
- public function customize_controls_enqueue_scripts() {}
69
-
70
- public function customize_controls_print_footer_scripts() {}
71
-
72
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/Required.php DELETED
@@ -1,136 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
- use Kirki\Scripts\ScriptRegistry;
8
-
9
- class Required extends EnqueueScript {
10
-
11
- /**
12
- * Add the required script.
13
- */
14
- function customize_controls_print_footer_scripts() {
15
-
16
- $fields = Kirki::fields()->get_all();
17
-
18
- // Early exit if no controls are defined
19
- if ( empty( $fields ) ) {
20
- return;
21
- }
22
-
23
- $script = '';
24
-
25
- foreach ( $fields as $field ) {
26
-
27
- $required = ( isset( $field['required'] ) ) ? $field['required'] : false;
28
-
29
- if ( $required ) {
30
-
31
- $show = false;
32
- foreach ( $required as $dependency ) {
33
- // Find the type of the dependency control
34
- $type = $fields[$dependency['setting']]['type'];
35
-
36
- // If "operator" is not set then set it to "=="
37
- if ( ! isset( $dependency['operator'] ) ) {
38
- $dependency['operator'] = '==';
39
- }
40
- $dependency['operator'] = esc_js( $dependency['operator'] );
41
-
42
- // Set the control type
43
- $type = ( 'dropdown-pages' == $type ) ? 'select' : $type;
44
- $type = ( 'radio-image' == $type ) ? 'radio' : $type;
45
- $type = ( 'radio-buttonset' == $type ) ? 'radio' : $type;
46
- $type = ( 'toggle' == $type ) ? 'checkbox' : $type;
47
- $type = ( 'switch' == $type ) ? 'checkbox' : $type;
48
-
49
- // Set the controller used in the script
50
- $controller = '#customize-control-' . $dependency['setting'] . ' input';
51
- if ( 'select' == $type ) {
52
- $controller = '#customize-control-' . $dependency['setting'] . ' select';
53
- } elseif ( 'radio' == $type ) {
54
- $controller = '#customize-control-' . $dependency['setting'] . ' input[value="' . $dependency['value'] . '"]';
55
- }
56
-
57
- // The target element
58
- $target = '#customize-control-' . $field['settings'];
59
- // if this is a background control then make sure we target all sub-controls
60
- if ( 'background' == $field['type'] ) {
61
- $target = '#customize-control-' . $control['settings'] . '_color, ';
62
- $target .= '#customize-control-' . $control['settings'] . '_image, ';
63
- $target .= '#customize-control-' . $control['settings'] . '_repeat, ';
64
- $target .= '#customize-control-' . $control['settings'] . '_size, ';
65
- $target .= '#customize-control-' . $control['settings'] . '_position, ';
66
- $target .= '#customize-control-' . $control['settings'] . '_attach';
67
- }
68
-
69
- if ( ! isset( $dependency['operator'] ) ) {
70
- $dependency['operator'] = '==';
71
- }
72
-
73
- $action_1 = '.show()';
74
- $action_2 = '.hide()';
75
- // Allow checking both checked and unchecked checkboxes
76
- if ( 'checkbox' == $type ) {
77
- if ( 0 == $dependency['value'] && '==' == $dependency['operator'] ) {
78
- $action_1 = '.hide()';
79
- $action_2 = '.show()';
80
- $show = true;
81
- }
82
- if ( 1 == $dependency['value'] && '!=' == $dependency['operator'] ) {
83
- $action_1 = '.hide()';
84
- $action_2 = '.show()';
85
- }
86
- }
87
-
88
- // Get the initial status
89
- $value = kirki_get_option( $field['settings'] );
90
- if ( '==' == $dependency['operator'] ) {
91
- $show = ( $show && ( $dependency['value'] == $value ) ) ? true : $show;
92
- } elseif ( '!=' == $dependency['operator'] ) {
93
- $show = ( $show && ( $dependency['value'] != $value ) ) ? true : $show;
94
- } elseif ( '>=' == $dependency['operator'] ) {
95
- $show = ( $show && ( $dependency['value'] >= $value ) ) ? true : $show;
96
- } elseif ( '<=' == $dependency['operator'] ) {
97
- $show = ( $show && ( $dependency['value'] <= $value ) ) ? true : $show;
98
- } elseif ( '>' == $dependency['operator'] ) {
99
- $show = ( $show && ( $dependency['value'] > $value ) ) ? true : $show;
100
- } elseif ( '<' == $dependency['operator'] ) {
101
- $show = ( $show && ( $dependency['value'] < $value ) ) ? true : $show;
102
- }
103
-
104
- // if initial status is hidden then hide the control
105
- if ( false == $show ) {
106
- $script .= '$("' . $target . '").hide();';
107
- }
108
-
109
- $script .= '$("' . $controller . '").';
110
- $script .= ( 'checkbox' == $type ) ? 'click' : 'change';
111
- $script .= '(function(){';
112
- $script .= 'if ($("' . $controller . '").';
113
- $script .= ( 'checkbox' == $type ) ? 'is(":checked") ) {' : 'val() ' . $dependency['operator'] . ' "' . $dependency['value'] . '") {';
114
- $script .= '$("' . $target . '")' . $action_1 . ';';
115
- $script .= '} else {';
116
- $script .= '$("' . $target . '")' . $action_2 . ';';
117
- $script .= '}});';
118
- $script .= ( 'checkbox' != $type ) ? '$("' . $controller . '").trigger("change");' : '';
119
- }
120
- }
121
- }
122
-
123
- // If there's a script then echo it wrapped.
124
- if ( ! empty( $script ) ) {
125
- echo ScriptRegistry::prepare( $script );
126
- }
127
-
128
- }
129
-
130
- public function customize_controls_print_scripts() {}
131
-
132
- public function customize_controls_enqueue_scripts() {}
133
-
134
- public function wp_footer() {}
135
-
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/Stepper.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
- use Kirki\Scripts\ScriptRegistry;
8
-
9
- class Stepper extends EnqueueScript {
10
-
11
- /**
12
- * Add the help bubble
13
- */
14
- function customize_controls_print_footer_scripts() {
15
-
16
- $fields = Kirki::fields()->get_all();
17
- $scripts = array();
18
-
19
- foreach ( $fields as $field ) {
20
-
21
- if ( 'number' == $field['type'] ) {
22
- $scripts[] = '$( "#customize-control-' . $field['settings'] . ' input[type=\'number\']").stepper();';
23
- }
24
-
25
- }
26
-
27
- // No need to echo anything if the script is empty
28
- if ( empty( $scripts ) ) {
29
- return;
30
- }
31
-
32
- // Make sure we don't add any duplicates
33
- $scripts = array_unique( $scripts );
34
- // Convert array to string
35
- $script = implode( '', $scripts );
36
-
37
- echo ScriptRegistry::prepare( $script );
38
-
39
- }
40
-
41
- public function customize_controls_print_scripts() {}
42
-
43
- public function customize_controls_enqueue_scripts() {}
44
-
45
- public function wp_footer() {}
46
-
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Customizer/Tooltips.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Customizer;
4
-
5
- use Kirki;
6
- use Kirki\Scripts\EnqueueScript;
7
- use Kirki\Scripts\ScriptRegistry;
8
-
9
- class Tooltips extends EnqueueScript {
10
-
11
- /**
12
- * Add the help bubble
13
- */
14
- function customize_controls_print_footer_scripts() {
15
-
16
- $fields = Kirki::fields()->get_all();
17
-
18
- $scripts = array();
19
- $script = '';
20
-
21
- foreach ( $fields as $field ) {
22
-
23
- if ( ! empty( $field['help'] ) ) {
24
- $bubble_content = $field['help'];
25
- $content = "<a href='#' class='tooltip hint--left' data-hint='" . strip_tags( esc_html( $bubble_content ) ) . "'><span class='dashicons dashicons-info'></span></a>";
26
- $scripts[] = '$( "' . $content . '" ).prependTo( "#customize-control-' . $field['settings'] . '" );';
27
- }
28
-
29
- }
30
-
31
- // No need to echo anything if the script is empty
32
- if ( empty( $scripts ) ) {
33
- return;
34
- }
35
-
36
- // Make sure we don't add any duplicates
37
- $scripts = array_unique( $scripts );
38
- // Convert array to string
39
- $script = implode( '', $scripts );
40
-
41
- echo ScriptRegistry::prepare( $script );
42
-
43
- }
44
-
45
- public function customize_controls_print_scripts() {}
46
-
47
- public function customize_controls_enqueue_scripts() {}
48
-
49
- public function wp_footer() {}
50
-
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/EnqueueScript.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts;
4
-
5
- abstract class EnqueueScript extends ScriptRegistry {
6
-
7
- function __construct() {
8
- add_action( 'customize_controls_print_scripts', array( $this, 'customize_controls_print_scripts' ), 999 );
9
- add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) );
10
- add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_controls_print_footer_scripts' ) );
11
- add_action( 'wp_footer', array( $this, 'wp_footer' ), 21 );
12
- }
13
-
14
- public abstract function customize_controls_print_scripts();
15
-
16
- public abstract function customize_controls_enqueue_scripts();
17
-
18
- public abstract function customize_controls_print_footer_scripts();
19
-
20
- public abstract function wp_footer();
21
-
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/Frontend/GoogleFonts.php DELETED
@@ -1,110 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts\Frontend;
4
-
5
- use Kirki;
6
-
7
- class GoogleFonts {
8
-
9
- public function __construct() {
10
- add_action( 'wp_enqueue_scripts', array( $this, 'google_font' ), 105 );
11
- }
12
-
13
- function google_link() {
14
-
15
- $fields = Kirki::fields()->get_all();
16
-
17
- // Early exit if no fields are found.
18
- if ( ! $fields || empty( $fields ) ) {
19
- return;
20
- }
21
-
22
- // Get an array of all the google fonts
23
- $google_fonts = Kirki::fonts()->get_google_fonts();
24
-
25
- $fonts = array();
26
- foreach ( $fields as $field ) {
27
-
28
- if ( isset( $field['output'] ) ) {
29
-
30
- // Check if this is a font-family control
31
- $is_font_family = isset( $field['output']['property'] ) && 'font-family' == $field['output']['property'] ? true : false;
32
-
33
- // Check if this is a font-weight control
34
- $is_font_weight = isset( $field['output']['property'] ) && 'font-weight' == $field['output']['property'] ? true : false;
35
-
36
- // Check if this is a font subset control
37
- $is_font_subset = isset( $field['output']['property'] ) && 'font-subset' == $field['output']['property'] ? true : false;
38
-
39
- if ( $is_font_family || $is_font_weight || $is_font_subset ) {
40
- // The value of this control
41
- $value = kirki_get_option( $field['settings'] );
42
-
43
- if ( $is_font_family ) {
44
- $fonts[]['font-family'] = $value;
45
- } else if ( $is_font_weight ) {
46
- $fonts[]['font-weight'] = $value;
47
- } else if ( $is_font_subset ) {
48
- $fonts[]['subsets'] = $value;
49
- }
50
-
51
- }
52
-
53
- }
54
-
55
- }
56
-
57
- foreach ( $fonts as $font ) {
58
-
59
- if ( isset( $font['font-family'] ) ) {
60
-
61
- $font_families = ( ! isset( $font_families ) ) ? array() : $font_families;
62
- $font_families[] = $font['font-family'];
63
-
64
- if ( Kirki::fonts()->is_google_font( $font['font-family'] ) ) {
65
- $has_google_font = true;
66
- }
67
-
68
- }
69
-
70
- if ( isset( $font['font-weight'] ) ) {
71
-
72
- $font_weights = ( ! isset( $font_weights ) ) ? array() : $font_weights;
73
- $font_weights[] = $font['font-weight'];
74
-
75
- }
76
-
77
- if ( isset( $font['subsets'] ) ) {
78
-
79
- $font_subsets = ( ! isset( $font_subsets ) ) ? array() : $font_subsets;
80
- $font_subsets[] = $font['subsets'];
81
-
82
- }
83
-
84
- }
85
-
86
- $font_families = ( ! isset( $font_families ) || empty( $font_families ) ) ? false : $font_families;
87
- $font_weights = ( ! isset( $font_weights ) || empty( $font_weights ) ) ? '400' : $font_weights;
88
- $font_subsets = ( ! isset( $font_subsets ) || empty( $font_subsets ) ) ? 'all' : $font_subsets;
89
-
90
- if ( ! isset( $has_google_font ) || ! $has_google_font ) {
91
- $font_families = false;
92
- }
93
-
94
- return ( $font_families ) ? Kirki::fonts()->get_google_font_uri( $font_families, $font_weights, $font_subsets ) : false;
95
-
96
- }
97
-
98
- /**
99
- * Enqueue Google fonts if necessary
100
- */
101
- function google_font() {
102
- $google_link = $this->google_link();
103
-
104
- if ( $google_link ) {
105
- wp_register_style( 'kirki_google_fonts', $google_link );
106
- wp_enqueue_style( 'kirki_google_fonts' );
107
- }
108
- }
109
-
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Scripts/ScriptRegistry.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Scripts;
4
-
5
- use Kirki\Scripts\Customizer\Dependencies;
6
- use Kirki\Scripts\Customizer\Branding;
7
- use Kirki\Scripts\Customizer\PostMessage;
8
- use Kirki\Scripts\Customizer\Required;
9
- use Kirki\Scripts\Customizer\Tooltips;
10
- use Kirki\Scripts\Customizer\Stepper;
11
- use Kirki\Scripts\Frontend\GoogleFonts;
12
-
13
- class ScriptRegistry {
14
-
15
- public function __construct() {
16
-
17
- $dependencies = new Dependencies();
18
- $branding = new Branding();
19
- $postmessage = new PostMessage();
20
- $required = new Required();
21
- $tooltips = new Tooltips();
22
- $googlefonts = new GoogleFonts();
23
- $stepper = new Stepper();
24
-
25
- }
26
-
27
- public static function prepare( $script ) {
28
- return '<script>jQuery(document).ready(function($) { "use strict"; ' . $script . '});</script>';
29
- }
30
-
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Settings.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
-
5
- use Kirki;
6
-
7
- class Settings {
8
-
9
- /**
10
- * Add a setting
11
- */
12
- public function add( $wp_customize, $field ) {
13
-
14
- if ( 'background' == $field['type'] ) {
15
- // Do nothing.
16
- // The 'background' field is just the sum of its sub-fields
17
- // which are created individually.
18
- } else {
19
- $this->add_setting( $wp_customize, $field );
20
- }
21
-
22
- }
23
-
24
- public function add_setting( $wp_customize, $field, $id_override = null, $default_override = null, $callback = null ) {
25
-
26
- $id = ( ! is_null( $id_override ) ) ? $id_override : $field['settings'];
27
- $default = ( ! is_null( $default_override ) ) ? $default_override : $field['default'];
28
- $callback = ( ! is_null( $callback ) ) ? $callback : $field['sanitize_callback'];
29
-
30
- $wp_customize->add_setting( $id, array(
31
- 'default' => $default,
32
- 'type' => $field['option_type'],
33
- 'capability' => 'edit_theme_options',
34
- 'transport' => $field['transport'],
35
- 'sanitize_callback' => $callback,
36
- ) );
37
-
38
- }
39
-
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Styles.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki;
4
- use Kirki\Styles\Customizer;
5
- use Kirki\Styles\Frontend;
6
-
7
- class Styles {
8
-
9
- public function __construct() {
10
-
11
- $customizer_styles = new Customizer();
12
- $frontend_styles = new Frontend();
13
-
14
- }
15
-
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Styles/Customizer.php DELETED
@@ -1,96 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Styles;
4
- use Kirki;
5
- use Kirki\Styles;
6
-
7
- class Customizer {
8
-
9
- function __construct() {
10
- add_action( 'customize_controls_print_styles', array( $this, 'custom_css' ), 999 );
11
- add_action( 'customize_controls_print_styles', array( $this, 'customizer_styles' ) );
12
- }
13
-
14
- /**
15
- * Enqueue the stylesheets required.
16
- */
17
- function customizer_styles() {
18
- $config = Kirki::config()->get_all();
19
- $root = ( '' != $config['url_path'] ) ? $config['url_path'] : KIRKI_URL;
20
- wp_enqueue_style( 'kirki-customizer-css', trailingslashit( $root ) . 'assets/css/customizer.css', NULL, '0.5' );
21
- }
22
-
23
- /**
24
- * Add custom CSS rules to the head, applying our custom styles
25
- */
26
- function custom_css() {
27
-
28
- $color = $this->get_admin_colors();
29
- $config = Kirki::config();
30
-
31
- $color_font = false;
32
- $color_accent = $config->get( 'color_accent', $color['icon_colors']['focus']);
33
- $color_back = $config->get( 'color_back', '#ffffff' );
34
- $color_font = ( 170 > \Kirki_Color::get_brightness( $color_back ) ) ? '#f2f2f2' : '#222';
35
-
36
- $styles = '<style>';
37
-
38
- // Background styles
39
- $styles .= '#customize-controls .wp-full-overlay-sidebar-content{background-color:' . $color_back . ';}';
40
- $styles .= '#customize-theme-controls .accordion-section-title, #customize-info .accordion-section-title,#customize-info .accordion-section-title:hover,#customize-info.open .accordion-section-title{background-color:' . $color_back . ';color:' . $color_font . ';}';
41
- $styles .= '#customize-theme-controls .control-section .accordion-section-title:hover,#customize-theme-controls .control-section .accordion-section-title:focus,.control-section.control-panel>.accordion-section-title:after{background-color:' . \Kirki_Color::adjust_brightness( $color_back, -10 ) . ';color:' . $color_font . ';}';
42
- $styles .= '#customize-theme-controls .control-section.control-panel>h3.accordion-section-title:focus:after, #customize-theme-controls .control-section.control-panel>h3.accordion-section-title:hover:after{background-color:' . \Kirki_Color::adjust_brightness( $color_back, -20 ) . ';color:' . $color_font . ';}';
43
- $styles .= '#customize-theme-controls .control-section.open .accordion-section-title{background-color:' . $color_accent . ' !important;color:' . $color_font . ' !important;}';
44
-
45
- // Tooltip styles
46
- // $styles .= 'li.customize-control a.button.tooltip.hint--left {color:' . $color_accent . ';}';
47
-
48
- // Image-Radio styles
49
- $styles .= '.customize-control-radio-image .image.ui-buttonset label.ui-state-active {border-color:' . $color_accent . ';}';
50
-
51
- // Buttonset-Radio styles
52
- $styles .= '.customize-control-radio-buttonset label.ui-state-active{background-color:' . $color_accent . ';color:' . $color_font . ';}';
53
-
54
- // Slider Controls
55
- $styles .= '.customize-control-slider .ui-slider .ui-slider-handle{background-color:' . $color_accent . ';border-color:' . $color_accent . ';}';
56
-
57
- // Switch Controls
58
- $styles .= '.customize-control-switch .Switch .On, .customize-control-toggle .Switch .On{color:' . $color_accent . ';}';
59
-
60
- // Toggle Controls
61
- $styles .= '.customize-control-switch .Switch.Round.On, .customize-control-toggle .Switch.Round.On{background-color:' . \Kirki_Color::adjust_brightness( $color_accent, -10 ) . ';}';
62
-
63
- // Sortable Controls
64
- $styles .= '.customize-control-sortable ul.ui-sortable li .dashicons.visibility{color:' . $color_accent . ';}';
65
-
66
- // Palette Controls
67
- $styles .= '.customize-control-palette label.ui-state-active.ui-button.ui-widget span.ui-button-text {border-color:' . $color_accent . ';}';
68
-
69
- $styles .= '</style>';
70
-
71
- echo $styles;
72
-
73
- }
74
-
75
- /**
76
- * Get the admin color theme
77
- */
78
- function get_admin_colors() {
79
-
80
- // Get the active admin theme
81
- global $_wp_admin_css_colors;
82
-
83
- // Get the user's admin colors
84
- $color = get_user_option( 'admin_color' );
85
- // If no theme is active set it to 'fresh'
86
- if ( empty( $color ) || ! isset( $_wp_admin_css_colors[$color] ) ) {
87
- $color = 'fresh';
88
- }
89
-
90
- $color = (array) $_wp_admin_css_colors[$color];
91
-
92
- return $color;
93
-
94
- }
95
-
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Styles/Frontend.php DELETED
@@ -1,239 +0,0 @@
1
- <?php
2
-
3
- namespace Kirki\Styles;
4
- use Kirki;
5
- use Kirki\Styles;
6
-
7
- class Frontend {
8
-
9
- function __construct() {
10
- $styles_priority = ( isset( $options['styles_priority'] ) ) ? $styles_priority : 10;
11
- add_action( 'wp_enqueue_scripts', array( $this, 'frontend_styles' ), $styles_priority );
12
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ), 150 );
13
- }
14
-
15
-
16
- function enqueue_styles() {
17
- wp_add_inline_style( Kirki::config()->getOrThrow( 'stylesheet_id' ), $this->styles_parse() );
18
- }
19
-
20
-
21
- /**
22
- * Add a dummy, empty stylesheet if no stylesheet_id has been defined and we need one.
23
- */
24
- function frontend_styles() {
25
- $config = Kirki::config()->get_all();
26
- $fields = Kirki::fields()->get_all();
27
-
28
- $kirki_stylesheet = Kirki::config()->getOrThrow( 'stylesheet_id' );
29
-
30
- foreach( $fields as $field ) {
31
- if ( isset( $field['output'] ) ) {
32
- $uses_output = true;
33
- }
34
- }
35
-
36
- $root = ( '' != $config['url_path'] ) ? $config['url_path'] : KIRKI_URL;
37
-
38
- if ( isset( $uses_output ) && $uses_output && $kirki_stylesheet === 'kirki-styles' ) {
39
- wp_enqueue_style( 'kirki-styles', trailingslashit( $root ) . 'assets/css/kirki-styles.css', NULL, NULL );
40
- }
41
-
42
- }
43
-
44
-
45
- function styles_parse() {
46
-
47
- $styles = $this->loop_controls();
48
- $css = '';
49
-
50
- // Early exit if styles are empty or not an array
51
- if ( empty( $styles ) || ! is_array( $styles ) ) {
52
- return;
53
- }
54
-
55
- foreach ( $styles as $style => $style_array ) {
56
- $css .= $style . '{';
57
- foreach ( $style_array as $property => $value ) {
58
- $css .= $property . ':' . $value . ';';
59
- }
60
- $css .= '}';
61
- }
62
-
63
- return $css;
64
-
65
- }
66
-
67
-
68
- function setting_styles( $field, $styles, $element, $property, $units ) {
69
-
70
- $value = kirki_get_option( $field['settings'] );
71
-
72
- // Color controls
73
- if ( 'color' == $field['type'] ) {
74
-
75
- $color = \Kirki_Color::sanitize_hex( $value );
76
- $styles[$element][$property] = $color;
77
-
78
- }
79
-
80
- // Background Controls
81
- elseif ( 'background' == $field['type'] ) {
82
-
83
- if ( isset( $field['default']['color'] ) ) {
84
- $color_mode = ( false !== strpos( $field['default']['color'], 'rgba' ) ) ? 'color-alpha' : 'color';
85
- $value = kirki_get_option( $field['settings'] . '_color' );
86
- if ( 'color-alpha' == $color_mode ) {
87
- $bg_color = esc_js( $value );
88
- } else {
89
- $bg_color = \Kirki_Color::sanitize_hex( $value );
90
- }
91
- }
92
- if ( isset( $field['default']['image'] ) ) {
93
- $bg_image = kirki_get_option( $field['settings'] . '_image' );
94
- $bg_image = esc_url_raw( $bg_image );
95
- }
96
- if ( isset( $field['default']['repeat'] ) ) {
97
- $bg_repeat = kirki_get_option( $field['settings'] . '_repeat' );
98
- $bg_repeat = kirki_sanitize_bg_repeat( $bg_repeat );
99
- }
100
- if ( isset( $field['default']['size'] ) ) {
101
- $bg_size = kirki_get_option( $field['settings'] . '_size' );
102
- $bg_size = kirki_sanitize_bg_size( $bg_size );
103
- }
104
- if ( isset( $field['default']['attach'] ) ) {
105
- $bg_attach = kirki_get_option( $field['settings'] . '_attach' );
106
- $bg_attach = kirki_sanitize_bg_attach( $bg_attach );
107
- }
108
- if ( isset( $field['default']['position'] ) ) {
109
- $bg_position = kirki_get_option( $field['settings'] . '_position' );
110
- $bg_position = kirki_sanitize_bg_position( $bg_position );
111
- }
112
- if ( isset( $field['default']['opacity'] ) && $field['default']['opacity'] ) {
113
- $bg_opacity = kirki_get_option( $field['settings'] . '_opacity' );
114
- $bg_opacity = kirki_sanitize_number( $bg_opacity );
115
- if ( isset( $bg_color ) ) {
116
- // If we're using an opacity other than 100, then convert the color to RGBA.
117
- $bg_color = ( 100 != $bg_opacity ) ? \Kirki_Color::get_rgba( $bg_color, $bg_opacity ) : $bg_color;
118
- } elseif ( isset( $bg_image ) ) {
119
- $element_opacity = ( $bg_opacity / 100 );
120
- }
121
-
122
- }
123
-
124
- if ( isset( $bg_color ) ) {
125
- $styles[$element]['background-color'] = $bg_color;
126
- }
127
- if ( isset( $bg_image ) && '' != $bg_image ) {
128
- $styles[$element]['background-image'] = 'url("' . $bg_image . '")';
129
- if ( isset( $bg_repeat ) ) {
130
- $styles[$element]['background-repeat'] = $bg_repeat;
131
- }
132
- if ( isset( $bg_size ) ) {
133
- $styles[$element]['background-size'] = $bg_size;
134
- }
135
- if ( isset( $bg_attach ) ) {
136
- $styles[$element]['background-attachment'] = $bg_attach;
137
- }
138
- if ( isset( $bg_position ) ) {
139
- $styles[$element]['background-position'] = str_replace( '-', ' ', $bg_position );
140
- }
141
- }
142
-
143
- }
144
-
145
- // Font controls
146
- elseif ( array( $field['output'] ) && isset( $field['output']['property'] ) && in_array( $field['output']['property'], array( 'font-family', 'font-size', 'font-weight' ) ) ) {
147
-
148
- $is_font_family = isset( $field['output']['property'] ) && 'font-family' == $field['output']['property'] ? true : false;
149
- $is_font_size = isset( $field['output']['property'] ) && 'font-size' == $field['output']['property'] ? true : false;
150
- $is_font_weight = isset( $field['output']['property'] ) && 'font-weight' == $field['output']['property'] ? true : false;
151
-
152
- if ( 'font-family' == $property ) {
153
-
154
- $styles[$field['output']['element']]['font-family'] = $value;
155
-
156
- } else if ( 'font-size' == $property ) {
157
-
158
- // Get the unit we're going to use for the font-size.
159
- $units = empty( $units ) ? 'px' : $units;
160
- $styles[$element]['font-size'] = $value . $units;
161
-
162
- } else if ( 'font-weight' == $property ) {
163
-
164
- $styles[$element]['font-weight'] = $value;
165
-
166
- }
167
-
168
- } else {
169
-
170
- $styles[$element][$property] = $value . $units;
171
-
172
- }
173
-
174
- return $styles;
175
-
176
- }
177
-
178
-
179
- function loop_controls() {
180
-
181
- $fields = Kirki::fields()->get_all();
182
- $styles = array();
183
-
184
- // Early exit if no fields are found.
185
- if ( ! $fields || empty( $fields ) ) {
186
- return;
187
- }
188
-
189
- foreach ( $fields as $field ) {
190
- $element = '';
191
- $property = '';
192
- $units = '';
193
-
194
- // Only continue if $field['output'] is set
195
- if ( isset( $field['output'] ) ) {
196
-
197
- // Check if this is an array of style definitions
198
- $multiple_styles = isset( $field['output'][0]['element'] ) ? true : false;
199
-
200
- if ( ! $multiple_styles ) { // single style
201
-
202
- // If $field['output'] is not an array, then use the string as the target element
203
- if ( is_string( $field['output'] ) ) {
204
- $element = $field['output'];
205
- } else {
206
- $element = isset( $field['output']['element'] ) ? $field['output']['element'] : '';
207
- $property = isset( $field['output']['property'] ) ? $field['output']['property'] : '';
208
- $units = isset( $field['output']['units'] ) ? $field['output']['units'] : '';
209
- }
210
-
211
- $styles = $this->setting_styles( $field, $styles, $element, $property, $units );
212
-
213
- } else { // Multiple styles set
214
-
215
- foreach ( $field['output'] as $style ) {
216
-
217
- if ( ! array( $style ) ) {
218
- $element = $style;
219
- } else {
220
- $element = isset( $style['element'] ) ? $style['element'] : '';
221
- $property = isset( $style['property'] ) ? $style['property'] : '';
222
- $units = isset( $style['units'] ) ? $style['units'] : '';
223
- }
224
-
225
- $styles = $this->setting_styles( $field, $styles, $element, $property, $units );
226
-
227
- }
228
-
229
- }
230
-
231
- }
232
-
233
- }
234
-
235
- return $styles;
236
-
237
- }
238
-
239
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-kirki-color.php ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Color Calculations class for Kirki
4
+ * Initially built for the Shoestrap-3 theme and then tweaked for Kirki.
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Color' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Kirki_Color {
25
+
26
+ /**
27
+ * Sanitises a HEX value.
28
+ * The way this works is by splitting the string in 6 substrings.
29
+ * Each sub-string is individually sanitized, and the result is then returned.
30
+ *
31
+ * @var string The hex value of a color
32
+ * @param boolean Whether we want to include a hash (#) at the beginning or not
33
+ * @return string The sanitized hex color.
34
+ */
35
+ public static function sanitize_hex( $color = '#FFFFFF', $hash = true ) {
36
+
37
+ // Remove any spaces and special characters before and after the string
38
+ $color = trim( $color );
39
+
40
+ // Remove any trailing '#' symbols from the color value
41
+ $color = str_replace( '#', '', $color );
42
+
43
+ // If the string is 6 characters long then use it in pairs.
44
+ if ( 3 == strlen( $color ) ) {
45
+ $color = substr( $color, 0, 1 ).substr( $color, 0, 1 ).substr( $color, 1, 1 ).substr( $color, 1, 1 ).substr( $color, 2, 1 ).substr( $color, 2, 1 );
46
+ }
47
+
48
+ $substr = array();
49
+ for ( $i = 0; $i <= 5; $i++ ) {
50
+ $default = ( 0 == $i ) ? 'F' : ( $substr[ $i - 1 ] );
51
+ $substr[ $i ] = substr( $color, $i, 1 );
52
+ $substr[ $i ] = ( false === $substr[ $i ] || ! ctype_xdigit( $substr[ $i ] ) ) ? $default : $substr[ $i ];
53
+ }
54
+ $hex = implode( '', $substr );
55
+
56
+ return ( ! $hash ) ? $hex : '#'.$hex;
57
+
58
+ }
59
+
60
+ /**
61
+ * Gets the rgb value of the $hex color.
62
+ *
63
+ * @var string The hex value of a color
64
+ * @param boolean Whether we want to implode the values or not
65
+ * @return mixed array|string
66
+ */
67
+ public static function get_rgb( $hex, $implode = false ) {
68
+
69
+ // Remove any trailing '#' symbols from the color value
70
+ $hex = self::sanitize_hex( $hex, false );
71
+
72
+ // rgb is an array
73
+ $rgb = array(
74
+ hexdec( substr( $hex, 0, 2 ) ),
75
+ hexdec( substr( $hex, 2, 2 ) ),
76
+ hexdec( substr( $hex, 4, 2 ) ),
77
+ );
78
+
79
+ return ( $implode ) ? implode( ',', $rgb ) : $rgb;
80
+
81
+ }
82
+
83
+ /**
84
+ * Converts an rgba color to hex
85
+ * This is an approximation and not completely accurate.
86
+ *
87
+ * @var string The rgba color formatted like rgba(r,g,b,a)
88
+ * @return string The hex value of the color.
89
+ */
90
+ public static function rgba2hex( $color ) {
91
+
92
+ // Remove parts of the string
93
+ $color = str_replace( array( 'rgba', '(', ')', ' ' ), '', $color );
94
+ // Convert to array
95
+ $color = explode( ',', $color );
96
+ // This is not a valid rgba definition, so return white.
97
+ if ( 4 != count( $color ) ) {
98
+ return '#ffffff';
99
+ }
100
+ // Convert dec. to hex.
101
+ $red = dechex( (int) $color[0] );
102
+ $green = dechex( (int) $color[1] );
103
+ $blue = dechex( (int) $color[2] );
104
+ $alpha = $color[3];
105
+
106
+ // Make sure all colors are 2 digits
107
+ $red = ( 1 == strlen( $red ) ) ? $red.$red : $red;
108
+ $green = ( 1 == strlen( $green ) ) ? $green.$green : $green;
109
+ $blue = ( 1 == strlen( $blue ) ) ? $blue.$blue : $blue;
110
+
111
+ // Combine hex parts
112
+ $hex = $red.$green.$blue;
113
+ // Get the opacity value on a 0-100 basis instead of 0-1.
114
+ $mix_level = intval( $alpha * 100 );
115
+ // Apply opacity - mix with white.
116
+ $hex = self::mix_colors( $hex, '#ffffff', $mix_level );
117
+
118
+ return $hex;
119
+
120
+ }
121
+
122
+ /**
123
+ * Gets the rgb value of the $hex color.
124
+ *
125
+ * @var string The hex value of a color
126
+ * @param int Opacity level (1-100)
127
+ * @return string
128
+ */
129
+ public static function get_rgba( $hex = '#fff', $opacity = 100 ) {
130
+
131
+ $hex = self::sanitize_hex( $hex, false );
132
+ /**
133
+ * Make sure that opacity is properly formatted :
134
+ * Set the opacity to 100 if a larger value has been entered by mistake.
135
+ * If a negative value is used, then set to 0.
136
+ * If an opacity value is entered in a decimal form (for example 0.25), then multiply by 100.
137
+ */
138
+ $opacity = ( 1 >= $opacity && 0 < $opacity ) ? $opacity * 100 : $opacity;
139
+ $opacity = max( 0, min( 100, $opacity ) );
140
+
141
+ // Divide the opacity by 100 to end-up with a CSS value for the opacity
142
+ $opacity = ( $opacity / 100 );
143
+
144
+ $color = 'rgba('.self::get_rgb( $hex, true ).','.$opacity.')';
145
+
146
+ return $color;
147
+
148
+ }
149
+
150
+ /**
151
+ * Gets the brightness of the $hex color.
152
+ *
153
+ * @var string The hex value of a color
154
+ * @return int value between 0 and 255
155
+ */
156
+ public static function get_brightness( $hex ) {
157
+
158
+ $hex = self::sanitize_hex( $hex, false );
159
+ // returns brightness value from 0 to 255
160
+ return intval( ( ( hexdec( substr( $hex, 0, 2 ) ) * 299 ) + ( hexdec( substr( $hex, 2, 2 ) ) * 587 ) + ( hexdec( substr( $hex, 4, 2 ) ) * 114 ) ) / 1000 );
161
+
162
+ }
163
+
164
+ /**
165
+ * Adjusts brightness of the $hex color.
166
+ *
167
+ * @var string The hex value of a color
168
+ * @var int a value between -255 (darken) and 255 (lighten)
169
+ * @return string returns hex color
170
+ */
171
+ public static function adjust_brightness( $hex, $steps ) {
172
+
173
+ $hex = self::sanitize_hex( $hex, false );
174
+ // Steps should be between -255 and 255. Negative = darker, positive = lighter
175
+ $steps = max( -255, min( 255, $steps ) );
176
+ // Adjust number of steps and keep it inside 0 to 255
177
+ $red = max( 0, min( 255, hexdec( substr( $hex, 0, 2 ) ) + $steps ) );
178
+ $green = max( 0, min( 255, hexdec( substr( $hex, 2, 2 ) ) + $steps ) );
179
+ $blue = max( 0, min( 255, hexdec( substr( $hex, 4, 2 ) ) + $steps ) );
180
+
181
+ $red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
182
+ $green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
183
+ $blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
184
+
185
+ return self::sanitize_hex( $red_hex.$green_hex.$blue_hex );
186
+
187
+ }
188
+
189
+ /**
190
+ * Mixes 2 hex colors.
191
+ * the "percentage" variable is the percent of the first color
192
+ * to be used it the mix. default is 50 (equal mix)
193
+ *
194
+ * @var string The hex value of color 1
195
+ * @var string The hex value of color 2
196
+ * @var int a value between 0 and 100
197
+ * @return string returns hex color
198
+ */
199
+ public static function mix_colors( $hex1, $hex2, $percentage ) {
200
+
201
+ $hex1 = self::sanitize_hex( $hex1, false );
202
+ $hex2 = self::sanitize_hex( $hex2, false );
203
+
204
+ $red = ( $percentage * hexdec( substr( $hex1, 0, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 0, 2 ) ) ) / 100;
205
+ $green = ( $percentage * hexdec( substr( $hex1, 2, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 2, 2 ) ) ) / 100;
206
+ $blue = ( $percentage * hexdec( substr( $hex1, 4, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 4, 2 ) ) ) / 100;
207
+
208
+ $red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
209
+ $green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
210
+ $blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
211
+
212
+ return self::sanitize_hex( $red_hex.$green_hex.$blue_hex );
213
+
214
+ }
215
+
216
+ /**
217
+ * Convert hex color to hsv
218
+ *
219
+ * @var string The hex value of color 1
220
+ * @return array returns array( 'h', 's', 'v' )
221
+ */
222
+ public static function hex_to_hsv( $hex ) {
223
+ $rgb = (array) (array) self::get_rgb( self::sanitize_hex( $hex, false ) );
224
+ return self::rgb_to_hsv( $rgb );
225
+ }
226
+
227
+ /**
228
+ * Convert hex color to hsv
229
+ *
230
+ * @var array The rgb color to conver array( 'r', 'g', 'b' )
231
+ * @return array returns array( 'h', 's', 'v' )
232
+ */
233
+ public static function rgb_to_hsv( $color = array() ) {
234
+
235
+ $var_r = ( $color[0] / 255 );
236
+ $var_g = ( $color[1] / 255 );
237
+ $var_b = ( $color[2] / 255 );
238
+
239
+ $var_min = min( $var_r, $var_g, $var_b );
240
+ $var_max = max( $var_r, $var_g, $var_b );
241
+ $del_max = $var_max - $var_min;
242
+
243
+ $h = 0;
244
+ $s = 0;
245
+ $v = $var_max;
246
+
247
+ if ( 0 != $del_max ) {
248
+ $s = $del_max / $var_max;
249
+
250
+ $del_r = ( ( ( $var_max - $var_r ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
251
+ $del_g = ( ( ( $var_max - $var_g ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
252
+ $del_b = ( ( ( $var_max - $var_b ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
253
+
254
+ if ( $var_r == $var_max ) {
255
+ $h = $del_b - $del_g;
256
+ } elseif ( $var_g == $var_max ) {
257
+ $h = ( 1 / 3 ) + $del_r - $del_b;
258
+ } elseif ( $var_b == $var_max ) {
259
+ $h = ( 2 / 3 ) + $del_g - $del_r;
260
+ }
261
+
262
+ if ( $h < 0 ) {
263
+ $h++;
264
+ }
265
+
266
+ if ( $h > 1 ) {
267
+ $h--;
268
+ }
269
+ }
270
+
271
+ return array( 'h' => round( $h, 2 ), 's' => round( $s, 2 ), 'v' => round( $v, 2 ) );
272
+
273
+ }
274
+
275
+ /*
276
+ * This is a very simple algorithm that works by summing up the differences between the three color components red, green and blue.
277
+ * A value higher than 500 is recommended for good readability.
278
+ */
279
+ public static function color_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
280
+
281
+ $color_1 = self::sanitize_hex( $color_1, false );
282
+ $color_2 = self::sanitize_hex( $color_2, false );
283
+
284
+ $color_1_rgb = self::get_rgb( $color_1 );
285
+ $color_2_rgb = self::get_rgb( $color_2 );
286
+
287
+ $r_diff = max( $color_1_rgb[0], $color_2_rgb[0] ) - min( $color_1_rgb[0], $color_2_rgb[0] );
288
+ $g_diff = max( $color_1_rgb[1], $color_2_rgb[1] ) - min( $color_1_rgb[1], $color_2_rgb[1] );
289
+ $b_diff = max( $color_1_rgb[2], $color_2_rgb[2] ) - min( $color_1_rgb[2], $color_2_rgb[2] );
290
+
291
+ $color_diff = $r_diff + $g_diff + $b_diff;
292
+
293
+ return $color_diff;
294
+
295
+ }
296
+
297
+ /*
298
+ * This function tries to compare the brightness of the colors.
299
+ * A return value of more than 125 is recommended.
300
+ * Combining it with the color_difference function above might make sense.
301
+ */
302
+ public static function brightness_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
303
+
304
+ $color_1 = self::sanitize_hex( $color_1, false );
305
+ $color_2 = self::sanitize_hex( $color_2, false );
306
+
307
+ $color_1_rgb = self::get_rgb( $color_1 );
308
+ $color_2_rgb = self::get_rgb( $color_2 );
309
+
310
+ $br_1 = ( 299 * $color_1_rgb[0] + 587 * $color_1_rgb[1] + 114 * $color_1_rgb[2] ) / 1000;
311
+ $br_2 = ( 299 * $color_2_rgb[0] + 587 * $color_2_rgb[1] + 114 * $color_2_rgb[2] ) / 1000;
312
+
313
+ return intval( abs( $br_1 - $br_2 ) );
314
+
315
+ }
316
+
317
+ /*
318
+ * Uses the luminosity to calculate the difference between the given colors.
319
+ * The returned value should be bigger than 5 for best readability.
320
+ */
321
+ public static function lumosity_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
322
+
323
+ $color_1 = self::sanitize_hex( $color_1, false );
324
+ $color_2 = self::sanitize_hex( $color_2, false );
325
+
326
+ $color_1_rgb = self::get_rgb( $color_1 );
327
+ $color_2_rgb = self::get_rgb( $color_2 );
328
+
329
+ $l1 = 0.2126 * pow( $color_1_rgb[0] / 255, 2.2 ) + 0.7152 * pow( $color_1_rgb[1] / 255, 2.2 ) + 0.0722 * pow( $color_1_rgb[2] / 255, 2.2 );
330
+ $l2 = 0.2126 * pow( $color_2_rgb[0] / 255, 2.2 ) + 0.7152 * pow( $color_2_rgb[1] / 255, 2.2 ) + 0.0722 * pow( $color_2_rgb[2] / 255, 2.2 );
331
+
332
+ $lum_diff = ( $l1 > $l2 ) ? ( $l1 + 0.05 ) / ( $l2 + 0.05 ) : ( $l2 + 0.05 ) / ( $l1 + 0.05 );
333
+
334
+ return round( $lum_diff, 2 );
335
+
336
+ }
337
+
338
+ }
includes/class-kirki-colourlovers.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Retrieve colors from the Colourlovers API.
4
+ *
5
+ * @package Kirki
6
+ * @category Addon
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Colourlovers' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Colourlovers {
24
+
25
+ /**
26
+ * Returns an array properly formatted for use by the Kirki_Palette control.
27
+ *
28
+ * @param $palettes_nr int the number of palettes we want to get
29
+ * @return array
30
+ */
31
+ public static function get_palettes( $palettes_nr = 5 ) {
32
+
33
+ $palettes = self::parse();
34
+ $palettes = array_slice( $palettes, 0, $palettes_nr );
35
+
36
+ $i = 0;
37
+ foreach ( $palettes as $palette ) {
38
+ $palettes[ $i ] = array();
39
+ foreach ( $palette as $key => $value ) {
40
+ $palettes[ $i ][ $key ] = Kirki_Color::sanitize_hex( $value );
41
+ }
42
+ $i++;
43
+ }
44
+
45
+ return $palettes;
46
+
47
+ }
48
+
49
+ /**
50
+ * Get the palettes from an XML file and parse them.
51
+ *
52
+ * @param string|null $xml
53
+ */
54
+ public static function parse( $xml = null ) {
55
+
56
+ /**
57
+ * Parse the XML file.
58
+ * XML copied from http://www.colourlovers.com/api/palettes/top?numResults=100
59
+ */
60
+ $xml_url = ( is_null( $xml ) ) ? trailingslashit( kirki_url() ).'assets/xml/colourlovers-top.xml' : $xml;
61
+ $feed_xml = simplexml_load_file( $xml_url );
62
+
63
+ $palettes = array();
64
+ foreach ( $feed_xml->palette as $result ) {
65
+ $palettes[] = (array) $result->colors->hex;
66
+ }
67
+
68
+ return $palettes;
69
+
70
+ }
71
+
72
+ }
includes/class-kirki-explode-background-field.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Kirki_Explode_Background_Field extends Kirki_Field {
4
+ /**
5
+ * Build the background fields.
6
+ * Takes a single field with type = background and explodes it to multiple controls.
7
+ *
8
+ * @param array
9
+ * @return null|array<Array>
10
+ */
11
+ public static function explode( $field ) {
12
+ $i18n = Kirki_Toolkit::i18n();
13
+ $choices = self::background_choices();
14
+
15
+ // Early exit if this is not a background field.
16
+ if ( 'background' != $field['type'] ) {
17
+ return;
18
+ }
19
+
20
+ // Sanitize field
21
+ $field = Kirki_Field::sanitize_field( $field );
22
+ // No need to proceed any further if no defaults have been set.
23
+ // We build the array of fields based on what default values have been defined.
24
+ if ( ! isset( $field['default'] ) || ! is_array( $field['default'] ) ) {
25
+ return;
26
+ }
27
+
28
+ $fields = array();
29
+ $i = 0;
30
+ foreach ( $field['default'] as $key => $value ) {
31
+
32
+ // No need to process the opacity, it is factored in the color control.
33
+ if ( 'opacity' == $key ) {
34
+ continue;
35
+ }
36
+
37
+ $key = esc_attr( $key );
38
+ $setting = $key;
39
+ $help = $field['help'];
40
+ $description = isset( $i18n[ 'background-'.$key ] ) ? $i18n[ 'background-'.$key ] : '';
41
+ $output_property = 'background-'.$key;
42
+ $label = ( 0 === $i ) ? $field['label'] : '';
43
+ $type = 'select';
44
+
45
+ switch ( $key ) {
46
+ case 'color':
47
+ /**
48
+ * Use 'color-alpha' instead of 'color' if default is an rgba value
49
+ * or if 'opacity' is set.
50
+ */
51
+ $type = ( false !== strpos( $field['default']['color'], 'rgba' ) ) ? 'color-alpha' : 'color';
52
+ $type = ( isset( $field['default']['opacity'] ) ) ? 'color-alpha' : $type;
53
+ break;
54
+ case 'image':
55
+ $type = 'image';
56
+ break;
57
+ case 'attach':
58
+ /**
59
+ * Small hack so that background attachments properly work.
60
+ */
61
+ $output_property = 'background-attachment';
62
+ $description = $i18n['background-attachment'];
63
+ break;
64
+ default:
65
+ $help = '';
66
+ break;
67
+ }
68
+
69
+ /**
70
+ * If we're using options & option_name is set, then we need to modify the setting.
71
+ */
72
+ if ( ( isset( $field['option_type'] ) && 'option' == $field['option_type'] && isset( $field['option_name'] ) ) && ! empty( $field['option_name'] ) ) {
73
+ $property_setting = str_replace( ']', '', str_replace( $field['option_name'].'[', '', $field['settings'] ) );
74
+ $property_setting = esc_attr( $field['option_name'] ).'['.esc_attr( $property_setting ).'_'.$setting.']';
75
+ } else {
76
+ $property_setting = esc_attr( $field['settings'] ).'_'.$setting;
77
+ }
78
+
79
+ /**
80
+ * Build the field.
81
+ * We're merging with the original field here, so any extra properties are inherited.
82
+ */
83
+ $fields[ $property_setting ] = array_merge( $field, array(
84
+ 'type' => $type,
85
+ 'label' => $label,
86
+ 'settings' => $property_setting,
87
+ 'help' => $help,
88
+ 'section' => $field['section'],
89
+ 'priority' => $field['priority'],
90
+ 'required' => $field['required'],
91
+ 'description' => $description,
92
+ 'default' => $value,
93
+ 'id' => Kirki_Field::sanitize_id( array( 'settings' => Kirki_Field::sanitize_settings( array( 'settings' => $field['settings'].'_'.$setting ) ) ) ),
94
+ 'choices' => isset( $choices[ $key ] ) ? $choices[ $key ] : array(),
95
+ 'output' => ( '' != $field['output'] ) ? array(
96
+ array(
97
+ 'element' => $field['output'],
98
+ 'property' => $output_property,
99
+ ),
100
+ ) : '',
101
+ 'sanitize_callback' => Kirki_Field::fallback_callback( $type ),
102
+ ) );
103
+ $i++;
104
+ }
105
+
106
+ return $fields;
107
+
108
+ }
109
+
110
+ /**
111
+ * Parse all fields and add the new background fields
112
+ *
113
+ * @param array
114
+ * @return array
115
+ */
116
+ public static function process_fields( $fields ) {
117
+
118
+ foreach ( $fields as $field ) {
119
+ /**
120
+ * Make sure background fields are exploded
121
+ */
122
+ if ( isset( $field['type'] ) && 'background' == $field['type'] ) {
123
+ $explode = self::explode( $field );
124
+ $fields = array_merge( $fields, $explode );
125
+ }
126
+ }
127
+
128
+ return $fields;
129
+
130
+ }
131
+
132
+
133
+ /**
134
+ * The background choices.
135
+ * @return array<string,array>
136
+ */
137
+ public static function background_choices() {
138
+
139
+ $i18n = Kirki_Toolkit::i18n();
140
+
141
+ return array(
142
+ 'repeat' => array(
143
+ 'no-repeat' => $i18n['no-repeat'],
144
+ 'repeat' => $i18n['repeat-all'],
145
+ 'repeat-x' => $i18n['repeat-x'],
146
+ 'repeat-y' => $i18n['repeat-y'],
147
+ 'inherit' => $i18n['inherit'],
148
+ ),
149
+ 'size' => array(
150
+ 'inherit' => $i18n['inherit'],
151
+ 'cover' => $i18n['cover'],
152
+ 'contain' => $i18n['contain'],
153
+ ),
154
+ 'attach' => array(
155
+ 'inherit' => $i18n['inherit'],
156
+ 'fixed' => $i18n['fixed'],
157
+ 'scroll' => $i18n['scroll'],
158
+ ),
159
+ 'position' => array(
160
+ 'left-top' => $i18n['left-top'],
161
+ 'left-center' => $i18n['left-center'],
162
+ 'left-bottom' => $i18n['left-bottom'],
163
+ 'right-top' => $i18n['right-top'],
164
+ 'right-center' => $i18n['right-center'],
165
+ 'right-bottom' => $i18n['right-bottom'],
166
+ 'center-top' => $i18n['center-top'],
167
+ 'center-center' => $i18n['center-center'],
168
+ 'center-bottom' => $i18n['center-bottom'],
169
+ ),
170
+ );
171
+
172
+ }
173
+
174
+ }
includes/class-kirki-field.php ADDED
@@ -0,0 +1,714 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sanitizes all variables from our fields and separates complex fields to their sub-fields.
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Field' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Field {
24
+
25
+ /**
26
+ * Sanitizes the field
27
+ *
28
+ * @param array the field definition
29
+ * @return array
30
+ */
31
+ public static function sanitize_field( $field ) {
32
+
33
+ /**
34
+ * Sanitize each property of the field separately.
35
+ */
36
+ $sanitized = array(
37
+ 'settings_raw' => self::sanitize_settings_raw( $field ),
38
+ 'default' => self::sanitize_default( $field ),
39
+ 'label' => self::sanitize_label( $field ),
40
+ 'help' => self::sanitize_help( $field ),
41
+ 'description' => self::sanitize_description( $field ),
42
+ 'required' => self::sanitize_required( $field ),
43
+ 'transport' => self::sanitize_transport( $field ),
44
+ 'type' => self::sanitize_control_type( $field ),
45
+ 'option_type' => self::sanitize_type( $field ),
46
+ 'section' => self::sanitize_section( $field ),
47
+ 'settings' => self::sanitize_settings( $field ),
48
+ 'priority' => self::sanitize_priority( $field ),
49
+ 'choices' => self::sanitize_choices( $field ),
50
+ 'output' => self::sanitize_output( $field ),
51
+ 'sanitize_callback' => self::sanitize_callback( $field ),
52
+ 'js_vars' => self::sanitize_js_vars( $field ),
53
+ 'id' => self::sanitize_id( $field ),
54
+ 'capability' => self::sanitize_capability( $field ),
55
+ 'variables' => self::sanitize_variables( $field ),
56
+ 'active_callback' => self::sanitize_active_callback( $field )
57
+ );
58
+
59
+ /**
60
+ * Return a merged array so any extra custom properties are parse as well (but not sanitized)
61
+ */
62
+ return array_merge( $field, $sanitized );
63
+
64
+ }
65
+
66
+ /**
67
+ * Sanitizes the control type.
68
+ *
69
+ * @param array the field definition
70
+ * @return string If not set, then defaults to text.
71
+ */
72
+ public static function sanitize_control_type( $field ) {
73
+
74
+ // If no field type has been defined then fallback to text
75
+ if ( ! isset( $field['type'] ) ) {
76
+ return 'text';
77
+ }
78
+
79
+ switch ( $field['type'] ) {
80
+
81
+ case 'checkbox' :
82
+ /**
83
+ * Tweaks for backwards-compatibility:
84
+ * Prior to version 0.8 switch & toggle were part of the checkbox control.
85
+ */
86
+ if ( isset( $field['mode'] ) && 'switch' == $field['mode'] ) {
87
+ $field['type'] = 'switch';
88
+ } elseif ( isset( $field['mode'] ) && 'toggle' == $field['mode'] ) {
89
+ $field['type'] = 'toggle';
90
+ }
91
+ break;
92
+ case 'radio' :
93
+ /**
94
+ * Tweaks for backwards-compatibility:
95
+ * Prior to version 0.8 radio-buttonset & radio-image were part of the checkbox control.
96
+ */
97
+ if ( isset( $field['mode'] ) && 'buttonset' == $field['mode'] ) {
98
+ $field['type'] = 'radio-buttonset';
99
+ } elseif ( isset( $field['mode'] ) && 'image' == $field['mode'] ) {
100
+ $field['type'] = 'radio-image';
101
+ }
102
+ break;
103
+ case 'group-title' :
104
+ case 'group_title' :
105
+ /**
106
+ * Tweaks for backwards-compatibility:
107
+ * Prior to version 0.8 there was a group-title control.
108
+ */
109
+ $field['type'] = 'custom';
110
+ break;
111
+ case 'color_alpha' :
112
+ // Just making sure that common mistakes will still work.
113
+ $field['type'] = 'color-alpha';
114
+ break;
115
+ case 'color' :
116
+ // If a default value of rgba() is defined for a color control then use color-alpha instead.
117
+ if ( isset( $field['default'] ) && false !== strpos( $field['default'], 'rgba' ) ) {
118
+ $field['type'] = 'color-alpha';
119
+ }
120
+ break;
121
+ }
122
+
123
+ /**
124
+ * sanitize using esc_attr and return the value.
125
+ */
126
+ return esc_attr( $field['type'] );
127
+
128
+ }
129
+
130
+ /**
131
+ * Sanitizes the setting type.
132
+ *
133
+ * @param array the field definition
134
+ * @return string (theme_mod|option)
135
+ */
136
+ public static function sanitize_type( $field ) {
137
+
138
+ /**
139
+ * If we've set an 'option_type' in the field properties
140
+ * then sanitize the value using esc_attr and return it.
141
+ */
142
+ if ( isset( $field['option_type'] ) ) {
143
+ return esc_attr( $field['option_type'] );
144
+ }
145
+
146
+ /**
147
+ * If no 'option_type' has been defined
148
+ * then try to get the option from the kirki/config filter.
149
+ */
150
+ $config = apply_filters( 'kirki/config', array() );
151
+ if ( isset( $config['option_type'] ) ) {
152
+ return esc_attr( $config['option_type'] );
153
+ }
154
+
155
+ /**
156
+ * If all else fails, fallback to theme_mod
157
+ */
158
+ return 'theme_mod';
159
+
160
+ }
161
+
162
+ /**
163
+ * Sanitizes the setting variables.
164
+ *
165
+ * @param array the field definition
166
+ * @return mixed
167
+ */
168
+ public static function sanitize_variables( $field ) {
169
+
170
+ /**
171
+ * Return null if no value has been defined
172
+ * or if not properly formatted as an array.
173
+ */
174
+ if ( ! isset( $field['variables'] ) || ! is_array( $field['variables'] ) ) {
175
+ return null;
176
+ }
177
+ return $field['variables'];
178
+
179
+ }
180
+
181
+ /**
182
+ * Sanitizes the setting active callback.
183
+ *
184
+ * @param array the field definition
185
+ * @return string callable function name.
186
+ */
187
+ public static function sanitize_active_callback( $field ) {
188
+
189
+ /**
190
+ * If a custom 'active_callback' has been defined then return that.
191
+ */
192
+ if ( isset( $field['active_callback'] ) ) {
193
+ return $field['active_callback'];
194
+ }
195
+
196
+ /**
197
+ * If the 'required' argument is set then we'll need to auto-calculate things.
198
+ * Set 'active_callback' to 'kirki_active_callback'. ALl extra calculations will be handled there.
199
+ */
200
+ if ( isset( $field['required'] ) ) {
201
+ return 'kirki_active_callback';
202
+ }
203
+
204
+ /**
205
+ * If all else fails, then fallback to __return_true
206
+ * This way the control is always shown.
207
+ */
208
+ return '__return_true';
209
+
210
+ }
211
+
212
+ /**
213
+ * Sanitizes the setting permissions.
214
+ *
215
+ * @param array the field definition
216
+ * @return string (theme_mod|option)
217
+ */
218
+ public static function sanitize_capability( $field ) {
219
+
220
+ /**
221
+ * If we have not set a custom 'capability' then we'll need to figure it out.
222
+ */
223
+ if ( ! isset( $field['capability'] ) ) {
224
+
225
+ /**
226
+ * If there's a global configuration then perhaps we're defining a capability there.
227
+ * Use the 'kirki/config' filter to figure it out.
228
+ */
229
+ $config = apply_filters( 'kirki/config', array() );
230
+ if ( isset( $config['capability'] ) ) {
231
+ return esc_attr( $config['capability'] );
232
+ }
233
+
234
+ /**
235
+ * No capability has been found, fallback to edit_theme_options
236
+ */
237
+ return 'edit_theme_options';
238
+
239
+ }
240
+
241
+ /**
242
+ * All good, a capability has been defined so return that escaped.
243
+ */
244
+ return esc_attr( $field['capability'] );
245
+
246
+ }
247
+
248
+ /**
249
+ * Sanitizes the raw setting name.
250
+ *
251
+ * @param array the field definition
252
+ * @return string
253
+ */
254
+ public static function sanitize_settings_raw( $field ) {
255
+
256
+ /**
257
+ * Compatibility tweak
258
+ * Previous versions of the Kirki customizer used 'setting' istead of 'settings'.
259
+ */
260
+ if ( ! isset( $field['settings'] ) && isset( $field['setting'] ) ) {
261
+ return sanitize_key( $field['setting'] );
262
+ }
263
+
264
+ /**
265
+ * Sanitize the field's settings attribute.
266
+ */
267
+ return sanitize_key( $field['settings'] );
268
+
269
+ }
270
+
271
+ /**
272
+ * Sanitizes the setting name
273
+ *
274
+ * @param array the field definition
275
+ * @return string
276
+ */
277
+ public static function sanitize_settings( $field ) {
278
+
279
+ /**
280
+ * If we're using options & option_name is set, then we need to modify the setting.
281
+ */
282
+ if ( ( isset( $field['option_type'] ) && 'option' == $field['option_type'] && isset( $field['option_name'] ) ) && ! empty( $field['option_name'] ) ) {
283
+ $field['settings'] = esc_attr( $field['option_name'] ).'['.esc_attr( $field['settings'] ).']';
284
+ }
285
+
286
+ return $field['settings'];
287
+
288
+ }
289
+
290
+ /**
291
+ * Sanitizes the control label.
292
+ *
293
+ * @param array the field definition
294
+ * @return string
295
+ */
296
+ public static function sanitize_label( $field ) {
297
+
298
+ /**
299
+ * If a label has been defined then we need to sanitize it and then return it.
300
+ * Sanitization here will be done using the 'wp_strip_all_tags' function.
301
+ */
302
+ if ( isset( $field['label'] ) ) {
303
+ return wp_strip_all_tags( $field['label'] );
304
+ }
305
+
306
+ /**
307
+ * If no label has been defined then we're returning an empty value.
308
+ * This is simply done to prevent any 'undefined index' PHP notices.
309
+ */
310
+ return '';
311
+
312
+ }
313
+
314
+ /**
315
+ * Sanitizes the control section
316
+ *
317
+ * @param array the field definition
318
+ * @return string
319
+ */
320
+ public static function sanitize_section( $field ) {
321
+
322
+ /**
323
+ * If no section is defined then make sure we add the one section that is ALWAYS present: 'title_tagline'
324
+ * Though it's wrong to use a section arbitrarily, at least this way we're making sure that the control will be rendered,
325
+ * even if you forget to add a section argument.
326
+ */
327
+ if ( ! isset( $field['section'] ) ) {
328
+ return 'title_tagline';
329
+ }
330
+
331
+ /**
332
+ * Sanitize the section name and return it.
333
+ */
334
+ return sanitize_key( $field['section'] );
335
+
336
+ }
337
+
338
+ /**
339
+ * Sanitizes the control id.
340
+ * Sanitizing the ID should happen after the 'settings' sanitization.
341
+ * This way we can also properly handle cases where the option_type is set to 'option'
342
+ * and we're using an array instead of individual options.
343
+ *
344
+ * @param array the field definition
345
+ * @return string
346
+ */
347
+ public static function sanitize_id( $field ) {
348
+ return sanitize_key( str_replace( '[', '-', str_replace( ']', '', $field['settings'] ) ) );
349
+ }
350
+
351
+ /**
352
+ * Sanitizes the setting default value
353
+ *
354
+ * @param array the field definition
355
+ * @return mixed
356
+ */
357
+ public static function sanitize_default( $field ) {
358
+
359
+ /**
360
+ * make sure a default value is defined.
361
+ */
362
+ if ( ! isset( $field['default'] ) ) {
363
+ return '';
364
+ }
365
+
366
+ /**
367
+ * If an array then sanitize the array items separately
368
+ * TODO: the array_walk_recursive that we used was over-sanitizing things causing malfunctions.
369
+ * We've commented this out and will revisit this in a future release.
370
+ */
371
+ if ( is_array( $field['default'] ) ) {
372
+ // array_walk_recursive( $field['default'], array( 'Kirki_Field', 'sanitize_defaults_array' ) );
373
+ return $field['default'];
374
+ }
375
+
376
+ /**
377
+ * Return raw & unfiltered for custom controls
378
+ */
379
+ if ( isset( $field['type'] ) && 'custom' == $field['type'] ) {
380
+ return $field['default'];
381
+ }
382
+
383
+ /**
384
+ * fallback to escaping the default value.
385
+ */
386
+ return esc_textarea( $field['default'] );
387
+
388
+ }
389
+
390
+ /**
391
+ * Sanitizes the control description
392
+ *
393
+ * @param array the field definition
394
+ * @return string
395
+ */
396
+ public static function sanitize_description( $field ) {
397
+
398
+ if ( ! isset( $field['description'] ) && ! isset( $field['subtitle'] ) ) {
399
+ return '';
400
+ }
401
+
402
+ /**
403
+ * Compatibility tweak
404
+ *
405
+ * Previous verions of the Kirki Customizer had the 'description' field mapped to the new 'help'
406
+ * and instead of 'description' we were using 'subtitle'.
407
+ * This has been deprecated in favor of WordPress core's 'description' field that was recently introduced.
408
+ *
409
+ */
410
+ if ( isset( $field['subtitle'] ) ) {
411
+ return wp_strip_all_tags( $field['subtitle'] );
412
+ }
413
+ return wp_strip_all_tags( $field['description'] );
414
+
415
+ }
416
+
417
+ /**
418
+ * Sanitizes the control help
419
+ *
420
+ * @param array the field definition
421
+ * @return string
422
+ */
423
+ public static function sanitize_help( $field ) {
424
+
425
+ /**
426
+ * Compatibility tweak
427
+ *
428
+ * Previous verions of the Kirki Customizer had the 'description' field mapped to the new 'help'
429
+ * and instead of 'description' we were using 'subtitle'.
430
+ * This has been deprecated in favor of WordPress core's 'description' field that was recently introduced.
431
+ *
432
+ */
433
+ if ( isset( $field['subtitle'] ) ) {
434
+ // Use old arguments form.
435
+ if ( isset( $field['description'] ) ) {
436
+ return wp_strip_all_tags( $field['description'] );
437
+ }
438
+ return '';
439
+ }
440
+
441
+ /**
442
+ * Return empty string if not set.
443
+ */
444
+ if ( ! isset( $field['help'] ) ) {
445
+ return '';
446
+ }
447
+
448
+ /**
449
+ * Fallback to stripping all tags and returning.
450
+ */
451
+ return wp_strip_all_tags( $field['help'] );
452
+
453
+ }
454
+
455
+ /**
456
+ * Sanitizes the control choices.
457
+ *
458
+ * @param array the field definition
459
+ * @return array|string
460
+ */
461
+ public static function sanitize_choices( $field ) {
462
+
463
+ /**
464
+ * If not set then return an empty array.
465
+ * This will prevent PHP 'undefined index' notices.
466
+ */
467
+ if ( ! isset( $field['choices'] ) ) {
468
+ return array();
469
+ }
470
+
471
+ /**
472
+ * If an array then sanitize the array items separately
473
+ * TODO: the array_walk_recursive that we used was over-sanitizing things causing malfunctions.
474
+ * We've commented this out and will revisit this in a future release.
475
+ */
476
+ if ( is_array( $field['choices'] ) ) {
477
+ // array_walk_recursive( $field['choices'], array( 'Kirki_Field', 'sanitize_defaults_array' ) );
478
+ return $field['choices'];
479
+ }
480
+
481
+ /**
482
+ * This is a string so fallback to escaping the value and return.
483
+ */
484
+ return esc_attr( $field['choices'] );
485
+
486
+ }
487
+
488
+ /**
489
+ * Sanitizes the control output
490
+ *
491
+ * @param array the field definition
492
+ * @return array
493
+ */
494
+ public static function sanitize_output( $field ) {
495
+
496
+ /**
497
+ * Early exit and return a NULL value if output is not set
498
+ */
499
+ if ( ! isset( $field['output'] ) ) {
500
+ return null;
501
+ }
502
+
503
+ /**
504
+ * sanitize using esc_attr if output is string.
505
+ */
506
+ if ( ! is_array( $field['output'] ) ) {
507
+ return esc_attr( $field['output'] );
508
+ }
509
+ $output_sanitized = array();
510
+
511
+ /**
512
+ * convert to multidimentional array if necessary
513
+ */
514
+ if ( isset( $field['output']['element'] ) ) {
515
+ $field['output'] = array( $field['output'] );
516
+ }
517
+
518
+ /**
519
+ * sanitize array items individually
520
+ */
521
+ foreach ( $field['output'] as $output ) {
522
+ if ( ! isset( $output['media_query'] ) ) {
523
+ if ( isset( $output['prefix'] ) && ( false !== strpos( $output['prefix'], '@media' ) ) ) {
524
+ $output['media_query'] = $output['prefix'];
525
+ $output['prefix'] = '';
526
+ $output['suffix'] = '';
527
+ } else {
528
+ $output['media_query'] = 'global';
529
+ }
530
+ }
531
+ $output_sanitized[] = array(
532
+ 'element' => ( isset( $output['element'] ) ) ? sanitize_text_field( $output['element'] ) : '',
533
+ 'property' => ( isset( $output['property'] ) ) ? sanitize_text_field( $output['property'] ) : '',
534
+ 'units' => ( isset( $output['units'] ) ) ? sanitize_text_field( $output['units'] ) : '',
535
+ 'media_query' => trim( sanitize_text_field( str_replace( '{', '', $output['media_query'] ) ) ),
536
+ );
537
+ }
538
+
539
+ return $output_sanitized;
540
+
541
+ }
542
+
543
+ /**
544
+ * Sanitizes the control transport.
545
+ *
546
+ * @param array the field definition
547
+ * @return string postMessage|refresh (defaults to refresh)
548
+ */
549
+ public static function sanitize_transport( $field ) {
550
+
551
+ if ( isset( $field['transport'] ) && 'postMessage' == $field['transport'] ) {
552
+ return 'postMessage';
553
+ }
554
+
555
+ /**
556
+ * fallback to 'refresh'
557
+ */
558
+ return 'refresh';
559
+
560
+ }
561
+
562
+ /**
563
+ * Sanitizes the setting sanitize_callback
564
+ *
565
+ * @param array the field definition
566
+ * @return mixed the sanitization callback for this setting
567
+ */
568
+ public static function sanitize_callback( $field ) {
569
+
570
+ if ( isset( $field['sanitize_callback'] ) && ! empty( $field['sanitize_callback'] ) ) {
571
+ return $field['sanitize_callback'];
572
+ }
573
+ // Fallback callback
574
+ return self::fallback_callback( $field['type'] );
575
+
576
+ }
577
+
578
+ /**
579
+ * Sanitizes the control js_vars.
580
+ *
581
+ * @param array the field definition
582
+ * @return array|null
583
+ */
584
+ public static function sanitize_js_vars( $field ) {
585
+
586
+ $js_vars_sanitized = null;
587
+ if ( isset( $field['js_vars'] ) && is_array( $field['js_vars'] ) ) {
588
+ $js_vars_sanitized = array();
589
+ if ( isset( $field['js_vars']['element'] ) ) {
590
+ $field['js_vars'] = array( $field['js_vars'] );
591
+ }
592
+ foreach ( $field['js_vars'] as $js_vars ) {
593
+ $js_vars_sanitized[] = array(
594
+ 'element' => ( isset( $js_vars['element'] ) ) ? sanitize_text_field( $js_vars['element'] ) : '',
595
+ 'function' => ( isset( $js_vars['function'] ) ) ? esc_js( $js_vars['function'] ) : '',
596
+ 'property' => ( isset( $js_vars['property'] ) ) ? esc_js( $js_vars['property'] ) : '',
597
+ 'units' => ( isset( $js_vars['units'] ) ) ? esc_js( $js_vars['units'] ) : '',
598
+ );
599
+ }
600
+ }
601
+ return $js_vars_sanitized;
602
+
603
+ }
604
+
605
+ /**
606
+ * Sanitizes the control required argument.
607
+ *
608
+ * @param array the field definition
609
+ * @return array|null
610
+ */
611
+ public static function sanitize_required( $field ) {
612
+
613
+ $required_sanitized = null;
614
+ if ( isset( $field['required'] ) && is_array( $field['required'] ) ) {
615
+ $required_sanitized = array();
616
+ if ( isset( $field['required']['setting'] ) ) {
617
+ $field['required'] = array( $field['required'] );
618
+ }
619
+ foreach ( $field['required'] as $required ) {
620
+ $required_sanitized[] = array(
621
+ 'setting' => ( isset( $required['setting'] ) ) ? sanitize_text_field( $required['setting'] ) : '',
622
+ 'operator' => ( isset( $required['operator'] ) && in_array( $required['operator'], array( '==', '===', '!=', '!==', '>=', '<=', '>', '<' ) ) ) ? $required['operator'] : '==',
623
+ 'value' => ( isset( $required['value'] ) ) ? sanitize_text_field( $required['value'] ) : true,
624
+ );
625
+ }
626
+ }
627
+ return $required_sanitized;
628
+
629
+ }
630
+
631
+ /**
632
+ * Sanitizes the control priority
633
+ *
634
+ * @param array the field definition
635
+ * @return int
636
+ */
637
+ public static function sanitize_priority( $field ) {
638
+
639
+ if ( ! isset( $field['priority'] ) || '0' == absint( intval( $field['priority'] ) ) ) {
640
+ return 10;
641
+ }
642
+ return absint( intval( $field['priority'] ) );
643
+
644
+ }
645
+
646
+ /**
647
+ * Sanitizes the control transport.
648
+ *
649
+ * @param string the control type
650
+ * @return string|string[] the function name of a sanitization callback
651
+ */
652
+ public static function fallback_callback( $field_type ) {
653
+
654
+ switch ( $field_type ) {
655
+ case 'checkbox' :
656
+ case 'toggle' :
657
+ case 'switch' :
658
+ $sanitize_callback = array( 'Kirki_Sanitize', 'checkbox' );
659
+ break;
660
+ case 'color' :
661
+ case 'color-alpha' :
662
+ $sanitize_callback = array( 'Kirki_Sanitize', 'color' );
663
+ break;
664
+ case 'image' :
665
+ case 'upload' :
666
+ $sanitize_callback = 'esc_url_raw';
667
+ break;
668
+ case 'radio' :
669
+ case 'radio-image' :
670
+ case 'radio-buttonset' :
671
+ case 'select' :
672
+ case 'select2' :
673
+ case 'palette' :
674
+ $sanitize_callback = 'esc_attr';
675
+ break;
676
+ case 'dropdown-pages' :
677
+ $sanitize_callback = array( 'Kirki_Sanitize', 'dropdown_pages' );
678
+ break;
679
+ case 'slider' :
680
+ case 'number' :
681
+ $sanitize_callback = array( 'Kirki_Sanitize', 'number' );
682
+ break;
683
+ case 'text' :
684
+ case 'textarea' :
685
+ case 'editor' :
686
+ $sanitize_callback = 'esc_textarea';
687
+ break;
688
+ case 'multicheck' :
689
+ $sanitize_callback = array( 'Kirki_Sanitize', 'multicheck' );
690
+ break;
691
+ case 'sortable' :
692
+ $sanitize_callback = array( 'Kirki_Sanitize', 'sortable' );
693
+ break;
694
+ default :
695
+ $sanitize_callback = array( 'Kirki_Sanitize', 'unfiltered' );
696
+ break;
697
+ }
698
+
699
+ return $sanitize_callback;
700
+
701
+ }
702
+
703
+ /**
704
+ * Sanitizes the defaults array.
705
+ * This is used as a callback function in the sanitize_default method.
706
+ */
707
+ public static function sanitize_defaults_array( $value = '', $key = '' ) {
708
+
709
+ $value = esc_textarea( $value );
710
+ $key = esc_attr( $key );
711
+
712
+ }
713
+
714
+ }
includes/{Fonts/FontRegistry.php → class-kirki-fonts-font-registry.php} RENAMED
@@ -1,16 +1,26 @@
1
  <?php
2
-
3
- namespace Kirki\Fonts;
4
-
5
- Use Kirki;
6
-
7
  /**
8
- * Class FontManager
9
- * @package Kirki\Fonts
10
  *
11
- * Provides access to fonts available for selection in the controls
 
 
 
 
 
12
  */
13
- class FontRegistry {
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  /** @var array */
16
  private $standard_fonts = null;
@@ -33,7 +43,7 @@ class FontRegistry {
33
  $standard_fonts = $this->get_standard_fonts();
34
  $google_fonts = $this->get_google_fonts();
35
 
36
- return apply_filters('kirki/fonts/all', array_merge($standard_fonts, $google_fonts));
37
  }
38
 
39
  /**
@@ -58,9 +68,8 @@ class FontRegistry {
58
  *
59
  * @return boolean
60
  */
61
- public function is_google_font($font) {
62
- $allowed_fonts = $this->get_google_fonts();
63
- return ( array_key_exists( $font, $allowed_fonts ) ) ? true : false;
64
  }
65
 
66
 
@@ -77,12 +86,10 @@ class FontRegistry {
77
 
78
  // Validate each font and convert to URL format
79
  foreach ( $fonts as $font ) {
80
- $font = trim( $font );
81
-
82
  // Verify that the font exists
83
  if ( $this->is_google_font( $font ) ) {
84
  // Build the family name and variant string (e.g., "Open+Sans:regular,italic,700")
85
- $family[] = urlencode( $font . ':' . join( ',', $this->choose_google_font_variants( $font, $allowed_fonts[ $font ]['variants'] ) ) );
86
  }
87
  }
88
 
@@ -90,30 +97,32 @@ class FontRegistry {
90
  if ( empty( $family ) ) {
91
  return '';
92
  } else {
93
- $request = '//fonts.googleapis.com/css?family=' . implode( '|', $family );
94
  }
95
 
96
  // load the font weight
97
- $weight = ( is_array( $weight ) ) ? implode( ',', $weight ) : $weight;
98
- $request .= $weight;
99
 
100
  // Load the font subset
101
- if ( 'all' === $subset ) {
102
- $subsets_available = $this->get_google_font_subsets();
103
 
 
104
  // Remove the all set
105
  unset( $subsets_available['all'] );
106
-
107
  // Build the array
108
  $subsets = array_keys( $subsets_available );
 
109
  } else {
110
- $subsets = (array)$subset;
 
 
111
  }
112
 
113
  // Append the subset string
114
- $request .= ( ! empty( $subsets ) ) ? '&subset=' . join( ',', $subsets ) : '';
115
 
116
- return esc_url( $request );
117
  }
118
 
119
  /**
@@ -122,7 +131,8 @@ class FontRegistry {
122
  * @return array The available subsets.
123
  */
124
  public function get_google_font_subsets() {
125
- $i18n = Kirki::i18n();
 
126
  return array(
127
  'all' => $i18n['all'],
128
  'cyrillic' => $i18n['cyrillic'],
@@ -135,6 +145,7 @@ class FontRegistry {
135
  'latin-ext' => $i18n['latin-ext'],
136
  'vietnamese' => $i18n['vietnamese'],
137
  );
 
138
  }
139
 
140
  /**
@@ -147,7 +158,8 @@ class FontRegistry {
147
  * @param array $variants The variants for the font.
148
  * @return array The chosen variants.
149
  */
150
- public function choose_google_font_variants($font, $variants = array()) {
 
151
  $chosen_variants = array();
152
 
153
  if ( empty( $variants ) ) {
@@ -158,12 +170,7 @@ class FontRegistry {
158
  }
159
 
160
  // If a "regular" variant is not found, get the first variant
161
- if ( ! in_array( 'regular', $variants ) ) {
162
- $chosen_variants[] = $variants[0];
163
- } else {
164
- $chosen_variants[] = 'regular';
165
- }
166
-
167
  // Only add "italic" if it exists
168
  if ( in_array( 'italic', $variants ) ) {
169
  $chosen_variants[] = 'italic';
@@ -174,7 +181,8 @@ class FontRegistry {
174
  $chosen_variants[] = '700';
175
  }
176
 
177
- return apply_filters( 'kirki/font/variants', array_unique($chosen_variants), $font, $variants );
 
178
  }
179
 
180
  /**
@@ -183,25 +191,28 @@ class FontRegistry {
183
  * @return array Standard websafe fonts.
184
  */
185
  public function get_standard_fonts() {
186
- $i18n = Kirki::i18n();
187
- if ($this->standard_fonts==null) {
188
- $this->standard_fonts = apply_filters('kirki/fonts/standard_fonts', array(
189
- 'serif' => array(
 
 
190
  'label' => $i18n['serif'],
191
- 'stack' => 'Georgia,Times,"Times New Roman",serif'
192
  ),
193
  'sans-serif' => array(
194
- 'label' => $i18n['sans-serif'],
195
- 'stack' => '"Helvetica Neue",Helvetica,Arial,sans-serif'
196
  ),
197
- 'monospace' => array(
198
  'label' => $i18n['monospace'],
199
- 'stack' => 'Monaco,"Lucida Sans Typewriter","Lucida Typewriter","Courier New",Courier,monospace'
200
- )
201
- ));
202
  }
203
 
204
  return $this->standard_fonts;
 
205
  }
206
 
207
 
@@ -212,6 +223,7 @@ class FontRegistry {
212
  * @return string The full font stack.
213
  */
214
  public function get_font_stack( $font ) {
 
215
  $all_fonts = $this->get_all_fonts();
216
 
217
  // Sanitize font choice
@@ -220,12 +232,10 @@ class FontRegistry {
220
 
221
  // Use stack if one is identified
222
  if ( isset( $all_fonts[ $font ]['stack'] ) && ! empty( $all_fonts[ $font ]['stack'] ) ) {
223
- $stack = $all_fonts[ $font ]['stack'];
224
- } else {
225
- $stack = '"' . $font . '",' . $sans;
226
  }
 
227
 
228
- return $stack;
229
  }
230
 
231
  /**
@@ -235,14 +245,16 @@ class FontRegistry {
235
  * @return string The sanitized font choice.
236
  */
237
  public function sanitize_font_choice( $value ) {
 
 
238
  if ( is_int( $value ) ) {
239
- // The array key is an integer, so the chosen option is a heading, not a real choice
240
  return '';
241
- } else if ( array_key_exists( $value, $this->get_font_choices() ) ) {
 
242
  return $value;
243
  }
244
-
245
  return '';
 
246
  }
247
 
248
  /**
@@ -251,23 +263,35 @@ class FontRegistry {
251
  * @return array All Google Fonts.
252
  */
253
  public function get_google_fonts() {
254
- if ($this->google_fonts==null) {
 
 
 
 
 
 
 
 
 
 
255
  // Get the list of fonts from our json file and convert to an array
256
- $fonts = json_decode(file_get_contents(KIRKI_PATH . '/assets/json/webfonts.json'), true);
257
 
258
  $google_fonts = array();
259
- foreach ($fonts['items'] as $font) {
260
- $google_fonts[$font['family']] = array(
261
  'label' => $font['family'],
262
  'variants' => $font['variants'],
263
  'subsets' => $font['subsets'],
264
  );
265
  }
266
 
267
- $this->google_fonts = apply_filters('kirki/fonts/google_fonts', $google_fonts);
 
268
  }
269
 
270
  return $this->google_fonts;
 
271
  }
272
 
273
  }
1
  <?php
 
 
 
 
 
2
  /**
3
+ * Provides access to fonts available for selection in the controls
 
4
  *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
  */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Fonts_Font_Registry' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Fonts_Font_Registry {
24
 
25
  /** @var array */
26
  private $standard_fonts = null;
43
  $standard_fonts = $this->get_standard_fonts();
44
  $google_fonts = $this->get_google_fonts();
45
 
46
+ return apply_filters( 'kirki/fonts/all', array_merge( $standard_fonts, $google_fonts ) );
47
  }
48
 
49
  /**
68
  *
69
  * @return boolean
70
  */
71
+ public function is_google_font( $font ) {
72
+ return ( array_key_exists( $font, $this->get_google_fonts() ) );
 
73
  }
74
 
75
 
86
 
87
  // Validate each font and convert to URL format
88
  foreach ( $fonts as $font ) {
 
 
89
  // Verify that the font exists
90
  if ( $this->is_google_font( $font ) ) {
91
  // Build the family name and variant string (e.g., "Open+Sans:regular,italic,700")
92
+ $family[] = $font.':'.join( ',', $this->choose_google_font_variants( $font, $allowed_fonts[ $font ]['variants'] ) ).',';
93
  }
94
  }
95
 
97
  if ( empty( $family ) ) {
98
  return '';
99
  } else {
100
+ $request = str_replace( ' ', '+', '//fonts.googleapis.com/css?family='.implode( '|', $family ) );
101
  }
102
 
103
  // load the font weight
104
+ $weight = ( is_array( $weight ) ) ? implode( ',', $weight ) : $weight;
105
+ $request .= trim( $weight );
106
 
107
  // Load the font subset
108
+ if ( 'all' == $subset ) {
 
109
 
110
+ $subsets_available = $this->get_google_font_subsets();
111
  // Remove the all set
112
  unset( $subsets_available['all'] );
 
113
  // Build the array
114
  $subsets = array_keys( $subsets_available );
115
+
116
  } else {
117
+
118
+ $subsets = (array) $subset;
119
+
120
  }
121
 
122
  // Append the subset string
123
+ $request .= ( ! empty( $subsets ) ) ? '&subset='.join( ',', $subsets ) : '';
124
 
125
+ return $request;
126
  }
127
 
128
  /**
131
  * @return array The available subsets.
132
  */
133
  public function get_google_font_subsets() {
134
+
135
+ $i18n = Kirki_Toolkit::i18n();
136
  return array(
137
  'all' => $i18n['all'],
138
  'cyrillic' => $i18n['cyrillic'],
145
  'latin-ext' => $i18n['latin-ext'],
146
  'vietnamese' => $i18n['vietnamese'],
147
  );
148
+
149
  }
150
 
151
  /**
158
  * @param array $variants The variants for the font.
159
  * @return array The chosen variants.
160
  */
161
+ public function choose_google_font_variants( $font, $variants = array() ) {
162
+
163
  $chosen_variants = array();
164
 
165
  if ( empty( $variants ) ) {
170
  }
171
 
172
  // If a "regular" variant is not found, get the first variant
173
+ $chosen_variants[] = ( ! in_array( 'regular', $variants ) ) ? $variants[0] : 'regular';
 
 
 
 
 
174
  // Only add "italic" if it exists
175
  if ( in_array( 'italic', $variants ) ) {
176
  $chosen_variants[] = 'italic';
181
  $chosen_variants[] = '700';
182
  }
183
 
184
+ return apply_filters( 'kirki/font/variants', array_unique( $chosen_variants ), $font, $variants );
185
+
186
  }
187
 
188
  /**
191
  * @return array Standard websafe fonts.
192
  */
193
  public function get_standard_fonts() {
194
+
195
+ $i18n = Kirki_Toolkit::i18n();
196
+
197
+ if ( null == $this->standard_fonts ) {
198
+ $this->standard_fonts = apply_filters( 'kirki/fonts/standard_fonts', array(
199
+ 'serif' => array(
200
  'label' => $i18n['serif'],
201
+ 'stack' => 'Georgia,Times,"Times New Roman",serif',
202
  ),
203
  'sans-serif' => array(
204
+ 'label' => $i18n['sans-serif'],
205
+ 'stack' => '"Helvetica Neue",Helvetica,Arial,sans-serif',
206
  ),
207
+ 'monospace' => array(
208
  'label' => $i18n['monospace'],
209
+ 'stack' => 'Monaco,"Lucida Sans Typewriter","Lucida Typewriter","Courier New",Courier,monospace',
210
+ ),
211
+ ) );
212
  }
213
 
214
  return $this->standard_fonts;
215
+
216
  }
217
 
218
 
223
  * @return string The full font stack.
224
  */
225
  public function get_font_stack( $font ) {
226
+
227
  $all_fonts = $this->get_all_fonts();
228
 
229
  // Sanitize font choice
232
 
233
  // Use stack if one is identified
234
  if ( isset( $all_fonts[ $font ]['stack'] ) && ! empty( $all_fonts[ $font ]['stack'] ) ) {
235
+ return $all_fonts[ $font ]['stack'];
 
 
236
  }
237
+ return '"'.$font.'",'.$sans;
238
 
 
239
  }
240
 
241
  /**
245
  * @return string The sanitized font choice.
246
  */
247
  public function sanitize_font_choice( $value ) {
248
+
249
+ // The array key is an integer, so the chosen option is a heading, not a real choice
250
  if ( is_int( $value ) ) {
 
251
  return '';
252
+ }
253
+ if ( array_key_exists( $value, $this->get_font_choices() ) ) {
254
  return $value;
255
  }
 
256
  return '';
257
+
258
  }
259
 
260
  /**
263
  * @return array All Google Fonts.
264
  */
265
  public function get_google_fonts() {
266
+
267
+ global $wp_filesystem;
268
+ // Initialize the WP filesystem, no more using 'file-put-contents' function
269
+ if ( empty( $wp_filesystem ) ) {
270
+ require_once ( ABSPATH.'/wp-admin/includes/file.php' );
271
+ WP_Filesystem();
272
+ }
273
+
274
+ if ( null == $this->google_fonts ) {
275
+
276
+ $json = $wp_filesystem->get_contents( KIRKI_PATH.'/assets/json/webfonts.json' );
277
  // Get the list of fonts from our json file and convert to an array
278
+ $fonts = json_decode( $json, true );
279
 
280
  $google_fonts = array();
281
+ foreach ( $fonts['items'] as $font ) {
282
+ $google_fonts[ $font['family'] ] = array(
283
  'label' => $font['family'],
284
  'variants' => $font['variants'],
285
  'subsets' => $font['subsets'],
286
  );
287
  }
288
 
289
+ $this->google_fonts = apply_filters( 'kirki/fonts/google_fonts', $google_fonts );
290
+
291
  }
292
 
293
  return $this->google_fonts;
294
+
295
  }
296
 
297
  }
includes/class-kirki-helper.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper methods
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Helper' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Helper {
24
+
25
+ /**
26
+ * Helper function
27
+ *
28
+ * removes an item from an array
29
+ */
30
+ public function array_delete( $idx, $array ) {
31
+
32
+ // Early exit and return null if $array is not an array.
33
+ if ( ! is_array( $array ) ) {
34
+ return null;
35
+ }
36
+
37
+ unset( $array[ $idx ] );
38
+ return array_values( $array );
39
+
40
+ }
41
+
42
+ /**
43
+ * Returns the attachment object
44
+ *
45
+ * @var string URL to the image
46
+ * @return string numeric ID of the attachement.
47
+ */
48
+ public static function get_image_id( $url ) {
49
+
50
+ global $wpdb;
51
+ $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $url ) );
52
+ return $attachment[0];
53
+
54
+ }
55
+
56
+ /**
57
+ * Returns an array of the attachment's properties.
58
+ *
59
+ * @var string URL to the image
60
+ * @return array array()
61
+ */
62
+ public static function get_image_from_url( $url ) {
63
+
64
+ $image_id = self::get_image_id( $url );
65
+ $image = wp_get_attachment_image_src( $image_id, 'full' );
66
+
67
+ return array(
68
+ 'url' => $image[0],
69
+ 'width' => $image[1],
70
+ 'height' => $image[2],
71
+ 'thumbnail' => $image[3],
72
+ );
73
+
74
+ }
75
+
76
+ /**
77
+ * Helper function that gets posts and fomats them in a way so they can be used in select fields etc.
78
+ */
79
+ public static function get_posts( $args ) {
80
+
81
+ // Get the posts
82
+ $posts = get_posts( $args );
83
+
84
+ // properly format the array.
85
+ $items = array();
86
+ foreach ( $posts as $post ) {
87
+ $items[ $post->ID ] = $post->post_title;
88
+ }
89
+
90
+ return $items;
91
+
92
+ }
93
+
94
+ }
includes/class-kirki-output.php ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generates the styles for the frontend.
4
+ * Handles the 'output' argument of fields
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Output' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Kirki_Output {
25
+
26
+ public static $settings = null;
27
+ public static $type = 'theme_mod';
28
+ public static $output = array();
29
+ public static $callback = null;
30
+
31
+ public static $css;
32
+
33
+ public static $value = null;
34
+
35
+ /**
36
+ * The class constructor.
37
+ *
38
+ * @var string the setting ID.
39
+ * @var string theme_mod / option
40
+ * @var array an array of arrays of the output arguments.
41
+ * @var mixed a callable function.
42
+ */
43
+ public static function css( $setting = '', $type = 'theme_mod', $output = array(), $callback = '', $return_array = false ) {
44
+
45
+ // No need to proceed any further if we don't have the required arguments.
46
+ if ( '' == $setting || empty( $output ) ) {
47
+ return;
48
+ }
49
+
50
+ self::$settings = $setting;
51
+ self::$type = $type;
52
+ self::$output = Kirki_Field::sanitize_output( array( 'output' => $output ) );
53
+ self::$value = self::get_value();
54
+ self::$callback = $callback;
55
+
56
+ return ( true === $return_array ) ? self::styles() : self::styles_parse( self::add_prefixes( self::styles() ) );
57
+
58
+ }
59
+
60
+ /**
61
+ * Gets the value
62
+ *
63
+ * @return mixed
64
+ */
65
+ public static function get_value() {
66
+
67
+ /**
68
+ * Get the default value
69
+ */
70
+ $default = '';
71
+ if ( isset( Kirki::$fields[ self::$settings ] ) && isset( Kirki::$fields[ self::$settings ]['default'] ) ) {
72
+ if ( ! is_array( Kirki::$fields[ self::$settings ]['default'] ) ) {
73
+ $default = Kirki::$fields[ self::$settings ]['default'];
74
+ }
75
+ }
76
+
77
+ if ( 'theme_mod' == self::$type ) {
78
+ /**
79
+ * This is a theme_mod.
80
+ * All we have to do is use the get_theme_mod function to get the value
81
+ */
82
+ $value = get_theme_mod( self::$settings, $default );
83
+ } else {
84
+ /**
85
+ * This is an option.
86
+ */
87
+ if ( false !== strpos( self::$settings, '[' ) ) {
88
+ $setting_parts = explode( '[', self::$settings );
89
+ $option_name = str_replace( array( '[', ']' ), '', $setting_parts[0] );
90
+ /**
91
+ * We're using serialized options.
92
+ * First we'll need to get the option defined by the $option_name
93
+ * and then get the value of the specific setting from the array of options.
94
+ */
95
+ $option_value = get_option( $option_name );
96
+ $setting_stripped = str_replace( $option_name.'[', '', str_replace( ']', '', self::$settings ) );
97
+ if ( isset( $option_value[ $setting_stripped ] ) ) {
98
+ /**
99
+ * An option is set, so use that value.
100
+ */
101
+ $value = $option_value[ $setting_stripped ];
102
+ } else {
103
+ /**
104
+ * Option is not set, fallback to the default value.
105
+ */
106
+ $value = $default;
107
+ }
108
+ } else {
109
+ /**
110
+ * Options are not serialized, all we need to do is get the option value here.
111
+ */
112
+ $value = get_option( self::$settings, $default );
113
+ }
114
+ }
115
+
116
+ return $value;
117
+
118
+ }
119
+
120
+ /**
121
+ * Gets the array of generated styles and creates the minimized, inline CSS
122
+ *
123
+ * @param array
124
+ * @return string|null the generated CSS.
125
+ */
126
+ public static function styles_parse( $css = array() ) {
127
+
128
+ /**
129
+ * Process the array of CSS properties and produce the final CSS
130
+ */
131
+ $final_css = '';
132
+ if ( ! is_array( $css ) || empty( $css ) ) {
133
+ return;
134
+ }
135
+ foreach ( $css as $media_query => $styles ) {
136
+
137
+ $final_css .= ( 'global' != $media_query ) ? $media_query . '{' : '';
138
+
139
+ foreach ( $styles as $style => $style_array ) {
140
+ $final_css .= $style . '{';
141
+ foreach ( $style_array as $property => $value ) {
142
+ // Take care of formatting the URL for background-image statements.
143
+ if ( 'background-image' == $property || 'background' == $property && false !== filter_var( $value, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED ) ) {
144
+ $value = 'url("'.$value.'")';
145
+ }
146
+ // Make sure the background-position property is properly formatted
147
+ if ( 'background-position' == $property ) {
148
+ $value = str_replace( array( '_', '-' ), ' ', $value );
149
+ }
150
+ $final_css .= $property . ':' . $value . ';';
151
+ }
152
+ $final_css .= '}';
153
+ }
154
+
155
+ $final_css .= ( 'global' != $media_query ) ? '}' : '';
156
+
157
+ }
158
+
159
+
160
+ return $final_css;
161
+
162
+ }
163
+
164
+ /**
165
+ * Get the styles as an array.
166
+ */
167
+ public static function styles() {
168
+
169
+ $styles = array();
170
+
171
+ foreach ( self::$output as $output ) {
172
+ // Do we have units?
173
+ $units = ( isset( $output['units'] ) ) ? $output['units'] : '';
174
+ // Do we need to run this through a callback action?
175
+ $value = ( '' != self::$callback ) ? call_user_func( self::$callback, self::$value ) : self::$value;
176
+
177
+ $styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $value.$units;
178
+ }
179
+
180
+ return $styles;
181
+
182
+ }
183
+
184
+ /**
185
+ * Add prefixes if necessary
186
+ */
187
+ public static function add_prefixes( $css ) {
188
+
189
+ if ( ! is_array( $css ) ) {
190
+ return;
191
+ }
192
+
193
+ foreach ( $css as $media_query => $elements ) {
194
+
195
+ foreach ( $elements as $element => $style_array ) {
196
+
197
+ foreach ( $style_array as $property => $value ) {
198
+
199
+ // border-radius
200
+ if ( 'border-radius' == $property ) {
201
+ $css[$media_query][$element]['-webkit-border-radius'] = $value;
202
+ $css[$media_query][$element]['-moz-border-radius'] = $value;
203
+ }
204
+ // box-shadow
205
+ if ( 'box-shadow' == $property ) {
206
+ $css[$media_query][$element]['-webkit-box-shadow'] = $value;
207
+ $css[$media_query][$element]['-moz-box-shadow'] = $value;
208
+ }
209
+ // box-sizing
210
+ elseif ( 'box-sizing' == $property ) {
211
+ $css[$media_query][$element]['-webkit-box-sizing'] = $value;
212
+ $css[$media_query][$element]['-moz-box-sizing'] = $value;
213
+ }
214
+ // text-shadow
215
+ elseif ( 'text-shadow' == $property ) {
216
+ $css[$media_query][$element]['-webkit-text-shadow'] = $value;
217
+ $css[$media_query][$element]['-moz-text-shadow'] = $value;
218
+ }
219
+ // transform
220
+ elseif ( 'transform' == $property ) {
221
+ $css[$media_query][$element]['-webkit-transform'] = $value;
222
+ $css[$media_query][$element]['-moz-transform'] = $value;
223
+ $css[$media_query][$element]['-ms-transform'] = $value;
224
+ $css[$media_query][$element]['-o-transform'] = $value;
225
+ }
226
+ // background-size
227
+ elseif ( 'background-size' == $property ) {
228
+ $css[$media_query][$element]['-webkit-background-size'] = $value;
229
+ $css[$media_query][$element]['-moz-background-size'] = $value;
230
+ $css[$media_query][$element]['-ms-background-size'] = $value;
231
+ $css[$media_query][$element]['-o-background-size'] = $value;
232
+ }
233
+ // transition
234
+ elseif ( 'transition' == $property ) {
235
+ $css[$media_query][$element]['-webkit-transition'] = $value;
236
+ $css[$media_query][$element]['-moz-transition'] = $value;
237
+ $css[$media_query][$element]['-ms-transition'] = $value;
238
+ $css[$media_query][$element]['-o-transition'] = $value;
239
+ }
240
+ // transition-property
241
+ elseif ( 'transition-property' == $property ) {
242
+ $css[$media_query][$element]['-webkit-transition-property'] = $value;
243
+ $css[$media_query][$element]['-moz-transition-property'] = $value;
244
+ $css[$media_query][$element]['-ms-transition-property'] = $value;
245
+ $css[$media_query][$element]['-o-transition-property'] = $value;
246
+ }
247
+
248
+ }
249
+
250
+ }
251
+
252
+ }
253
+
254
+ return $css;
255
+
256
+ }
257
+
258
+ }
includes/class-kirki-sanitize.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Additional sanitization methods for controls.
4
+ * These are used in the field's 'sanitize_callback' argument.
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Sanitize' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Kirki_Sanitize {
25
+
26
+ /**
27
+ * Checkbox sanitization callback.
28
+ *
29
+ * Sanitization callback for 'checkbox' type controls. This callback sanitizes `$checked`
30
+ * as a boolean value, either TRUE or FALSE.
31
+ *
32
+ * @param bool|string $checked Whether the checkbox is checked.
33
+ * @return bool Whether the checkbox is checked.
34
+ */
35
+ public static function checkbox( $checked ) {
36
+ return ( ( isset( $checked ) && ( true == $checked || 'on' == $checked ) ) ? true : false );
37
+ }
38
+
39
+ /**
40
+ * Sanitize number options
41
+ *
42
+ * @since 0.5
43
+ */
44
+ public static function number( $value ) {
45
+ return ( is_numeric( $value ) ) ? $value : intval( $value );
46
+ }
47
+
48
+ /**
49
+ * Drop-down Pages sanitization callback.
50
+ *
51
+ * - Sanitization: dropdown-pages
52
+ * - Control: dropdown-pages
53
+ *
54
+ * Sanitization callback for 'dropdown-pages' type controls. This callback sanitizes `$page_id`
55
+ * as an absolute integer, and then validates that $input is the ID of a published page.
56
+ *
57
+ * @see absint() https://developer.wordpress.org/reference/functions/absint/
58
+ * @see get_post_status() https://developer.wordpress.org/reference/functions/get_post_status/
59
+ *
60
+ * @param int $page_id Page ID.
61
+ * @param WP_Customize_Setting $setting Setting instance.
62
+ * @return int|string Page ID if the page is published; otherwise, the setting default.
63
+ */
64
+ public static function dropdown_pages( $page_id, $setting ) {
65
+ // Ensure $input is an absolute integer.
66
+ $page_id = absint( $page_id );
67
+
68
+ // If $page_id is an ID of a published page, return it; otherwise, return the default.
69
+ return ( 'publish' == get_post_status( $page_id ) ? $page_id : $setting->default );
70
+ }
71
+
72
+ /**
73
+ * Sanitize sortable controls
74
+ *
75
+ * @since 0.8.3
76
+ */
77
+
78
+ public static function sortable( $value ) {
79
+ if ( is_serialized( $value ) ) {
80
+ return $value;
81
+ } else {
82
+ return serialize( $value );
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Sanitize RGBA colors
88
+ *
89
+ * @since 0.8.5
90
+ */
91
+ public static function rgba( $value ) {
92
+
93
+ // If empty or an array return transparent
94
+ if ( empty( $value ) || is_array( $value ) ) {
95
+ return 'rgba(0,0,0,0)';
96
+ }
97
+
98
+ // If string does not start with 'rgba', then treat as hex
99
+ // sanitize the hex color and finally convert hex to rgba
100
+ if ( false === strpos( $value, 'rgba' ) ) {
101
+ return Kirki_Color::get_rgba( Kirki_Color::sanitize_hex( $value ) );
102
+ }
103
+
104
+ // By now we know the string is formatted as an rgba color so we need to further sanitize it.
105
+ $value = str_replace( ' ', '', $value );
106
+ sscanf( $value, 'rgba(%d,%d,%d,%f)', $red, $green, $blue, $alpha );
107
+ return 'rgba('.$red.','.$green.','.$blue.','.$alpha.')';
108
+
109
+ }
110
+
111
+ /**
112
+ * Sanitize colors.
113
+ * Determine if the current value is a hex or an rgba color and call the appropriate method.
114
+ *
115
+ * @since 0.8.5
116
+ * @return string
117
+ */
118
+ public static function color( $value ) {
119
+
120
+ // Is this an rgba color or a hex?
121
+ $mode = ( false === strpos( $value, 'rgba' ) ) ? 'rgba' : 'hex';
122
+
123
+ if ( 'rgba' == $mode ) {
124
+ return Kirki_Color::sanitize_hex( $value );
125
+ } else {
126
+ return self::rgba( $value );
127
+ }
128
+
129
+ }
130
+
131
+ /**
132
+ * multicheck callback
133
+ */
134
+ public static function multicheck( $values ) {
135
+
136
+ $multi_values = ( ! is_array( $values ) ) ? explode( ',', $values ) : $values;
137
+ return ( ! empty( $multi_values ) ) ? array_map( 'sanitize_text_field', $multi_values ) : array();
138
+
139
+ }
140
+
141
+ /**
142
+ * DOES NOT SANITIZE ANYTHING.
143
+ *
144
+ * @since 0.5
145
+ */
146
+ public static function unfiltered( $value ) {
147
+ return $value;
148
+ }
149
+
150
+ }
includes/class-kirki-scripts-customizer-branding.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add the logo and description to the customizer.
4
+ * Logo and customizer are defined using the kirki/config filter.
5
+ * See https://github.com/reduxframework/kirki/wiki/Styling-the-Customizer for documentation
6
+ *
7
+ * @package Kirki
8
+ * @category Core
9
+ * @author Aristeides Stathopoulos
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Scripts_Customizer_Branding' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Scripts_Customizer_Branding extends Kirki_Scripts_Enqueue_Script {
26
+
27
+ /**
28
+ * If we've specified an image to be used as logo,
29
+ * replace the default theme description with a div that will include our logo.
30
+ */
31
+ public function generate_script() {
32
+
33
+ $config = apply_filters( 'kirki/config', array() );
34
+ $script = '';
35
+ if ( ( isset( $config['logo_image'] ) && '' != $config['logo_image'] ) || ( isset( $config['description'] ) && '' != $config['description'] ) ) {
36
+ if ( isset( $config['logo_image'] ) && '' != $config['logo_image'] ) {
37
+ $config['logo_image'] = esc_url_raw( $config['logo_image'] );
38
+ $script .= '$( \'div#customize-info .preview-notice\' ).replaceWith( \'<img src="'.$config['logo_image'].'">\' );';
39
+ }
40
+ if ( isset( $config['description'] ) && '' != $config['description'] ) {
41
+ $config['description'] = esc_textarea( $config['description'] );
42
+ $script .= '$( \'div#customize-info .accordion-section-content\' ).replaceWith( \'<div class="accordion-section-content"><div class="theme-description">'.$config['description'].'</div></div>\' );';
43
+ }
44
+ }
45
+
46
+ return $script;
47
+
48
+ }
49
+
50
+ public function customize_controls_print_scripts() {
51
+ $script = $this->generate_script();
52
+ if ( '' != $script ) {
53
+ echo Kirki_Scripts_Registry::prepare( $script );
54
+ }
55
+ }
56
+
57
+ public function customize_controls_enqueue_scripts() {}
58
+
59
+ public function customize_controls_print_footer_scripts() {}
60
+
61
+ public function wp_footer() {}
62
+
63
+ }
includes/class-kirki-scripts-customizer-default-scripts.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enqueue the scripts that are required by the customizer.
4
+ * Any additional scripts that are required by individual controls
5
+ * are enqueued in the control classes themselves.
6
+ *
7
+ * @package Kirki
8
+ * @category Core
9
+ * @author Aristeides Stathopoulos
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Scripts_Customizer_Default_Scripts' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Scripts_Customizer_Default_Scripts extends Kirki_Scripts_Enqueue_Script {
26
+
27
+ public function generate_script() {}
28
+
29
+ /**
30
+ * Enqueue the scripts required.
31
+ */
32
+ public function customize_controls_enqueue_scripts() {
33
+
34
+ wp_enqueue_script( 'kirki-tooltip', trailingslashit( kirki_url() ).'assets/js/kirki-tooltip.js', array( 'jquery', 'customize-controls' ) );
35
+ wp_enqueue_script( 'serialize-js', trailingslashit( kirki_url() ).'assets/js/serialize.js' );
36
+ wp_enqueue_script( 'jquery-select2', trailingslashit( kirki_url() ).'assets/js/select2.full.min.js', array( 'jquery' ) );
37
+ wp_enqueue_script( 'jquery-ui-core' );
38
+ wp_enqueue_script( 'jquery-ui-tooltip' );
39
+ wp_enqueue_script( 'jquery-stepper-min-js' );
40
+
41
+ wp_enqueue_style( 'css-select2', trailingslashit( kirki_url() ).'assets/css/select2.min.css' );
42
+ }
43
+
44
+ public function customize_controls_print_scripts() {}
45
+
46
+ public function customize_controls_print_footer_scripts() {}
47
+
48
+ public function wp_footer() {}
49
+
50
+ }
includes/class-kirki-scripts-customizer-postmessage.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Try to automatically generate the script necessary for postMessage to work.
4
+ * for documentation see https://github.com/reduxframework/kirki/wiki/required
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Scripts_Customizer_PostMessage' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Kirki_Scripts_Customizer_PostMessage extends Kirki_Scripts_Enqueue_Script {
25
+
26
+ public function generate_script() {
27
+
28
+ global $wp_customize;
29
+ // Early exit if we're not in the customizer
30
+ if ( ! isset( $wp_customize ) ) {
31
+ return;
32
+ }
33
+
34
+ // Get an array of all the fields
35
+ $fields = Kirki::$fields;
36
+
37
+ $script = '';
38
+ // Parse the fields and create the script.
39
+ foreach ( $fields as $field ) {
40
+ $field['transport'] = Kirki_Field::sanitize_transport( $field );
41
+ $field['js_vars'] = Kirki_Field::sanitize_js_vars( $field );
42
+ if ( ! is_null( $field['js_vars'] ) && 'postMessage' == $field['transport'] ) {
43
+ foreach ( $field['js_vars'] as $js_vars ) {
44
+ $script .= 'wp.customize( \''.Kirki_Field::sanitize_settings( $field ).'\', function( value ) {';
45
+ $script .= 'value.bind( function( newval ) {';
46
+ if ( 'html' == $js_vars['function'] ) {
47
+ $script .= '$(\''.esc_js( $js_vars['element'] ).'\').html( newval );';
48
+ } elseif ( 'css' == $js_vars['function'] ) {
49
+ $script .= '$(\''.esc_js( $js_vars['element'] ).'\').css(\''.esc_js( $js_vars['property'] ).'\', newval'.( ! empty( $js_vars['units'] ) ? ' + \''.$js_vars['units']."'" : '' ).' );';
50
+ }
51
+ $script .= '}); });';
52
+ }
53
+ }
54
+ }
55
+
56
+ return $script;
57
+
58
+ }
59
+
60
+ public function wp_footer() {
61
+ $script = $this->generate_script();
62
+ if ( '' != $script ) {
63
+ echo Kirki_Scripts_Registry::prepare( $script );
64
+ }
65
+ }
66
+
67
+ public function customize_controls_print_scripts() {}
68
+
69
+ public function customize_controls_enqueue_scripts() {}
70
+
71
+ public function customize_controls_print_footer_scripts() {}
72
+
73
+ }
includes/class-kirki-scripts-customizer-tooltips.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Injects tooltips to controls when the 'help' argument is used.
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Scripts_Customizer_Tooltips' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Scripts_Customizer_Tooltips extends Kirki_Scripts_Enqueue_Script {
24
+
25
+ /**
26
+ * Add the help bubble
27
+ */
28
+ public function generate_script() {
29
+
30
+ $fields = Kirki::$fields;
31
+
32
+ $scripts = array();
33
+
34
+ foreach ( $fields as $field ) {
35
+
36
+ $field['help'] = Kirki_Field::sanitize_help( $field );
37
+ $field['settings'] = Kirki_Field::sanitize_settings( $field );
38
+
39
+ if ( ! empty( $field['help'] ) ) {
40
+ $content = "<a href='#' class='tooltip hint--left' data-hint='".strip_tags( esc_html( $field['help'] ) )."'><span class='dashicons dashicons-info'></span></a>";
41
+ $scripts[] = '$( "'.$content.'" ).prependTo( "#customize-control-'.$field['settings'].'" );';
42
+ }
43
+
44
+ }
45
+
46
+ // No need to echo anything if the script is empty
47
+ if ( empty( $scripts ) ) {
48
+ return;
49
+ }
50
+
51
+ // Make sure we don't add any duplicates
52
+ $scripts = array_unique( $scripts );
53
+ // Convert array to string
54
+ $script = implode( '', $scripts );
55
+
56
+ return $script;
57
+
58
+ }
59
+
60
+ public function customize_controls_print_footer_scripts() {
61
+ $script = $this->generate_script();
62
+ if ( '' != $script ) {
63
+ echo Kirki_Scripts_Registry::prepare( $script );
64
+ }
65
+ }
66
+
67
+ public function customize_controls_print_scripts() {}
68
+
69
+ public function customize_controls_enqueue_scripts() {}
70
+
71
+ public function wp_footer() {}
72
+
73
+ }
includes/class-kirki-scripts-enqueue-script.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is just an abstract class that enqueues scripts.
4
+ * Other classes can extend this and skip the __construct since it's all handled here.
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Scripts_Enqueue_Script' ) ) {
21
+ return;
22
+ }
23
+
24
+ abstract class Kirki_Scripts_Enqueue_Script extends Kirki_Scripts_Registry {
25
+
26
+ public function __construct() {
27
+
28
+ add_action( 'customize_controls_print_scripts', array( $this, 'customize_controls_print_scripts' ), 999 );
29
+ add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) );
30
+ add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_controls_print_footer_scripts' ) );
31
+ add_action( 'wp_footer', array( $this, 'wp_footer' ), 21 );
32
+
33
+ }
34
+
35
+ /**
36
+ * @return void
37
+ */
38
+ abstract public function generate_script();
39
+
40
+ /**
41
+ * @return void
42
+ */
43
+ abstract public function customize_controls_print_scripts();
44
+
45
+ /**
46
+ * @return void
47
+ */
48
+ abstract public function customize_controls_enqueue_scripts();
49
+
50
+ /**
51
+ * @return void
52
+ */
53
+ abstract public function customize_controls_print_footer_scripts();
54
+
55
+ /**
56
+ * @return void
57
+ */
58
+ abstract public function wp_footer();
59
+
60
+ }
includes/class-kirki-scripts-frontend-google-fonts.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Creates the google-fonts link.
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Scripts_Frontend_Google_Fonts' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Scripts_Frontend_Google_Fonts {
24
+
25
+ public function __construct() {
26
+ add_action( 'wp_enqueue_scripts', array( $this, 'google_font' ), 105 );
27
+ }
28
+
29
+ public function google_link() {
30
+
31
+ // Get the array of fields
32
+ $fields = Kirki::$fields;
33
+
34
+ // Early exit if no fields are found.
35
+ if ( empty( $fields ) ) {
36
+ return;
37
+ }
38
+
39
+ $fonts = array();
40
+ foreach ( $fields as $field ) {
41
+
42
+ // Sanitize the field's output & settings_raw items.
43
+ $field['output'] = Kirki_Field::sanitize_output( $field );
44
+ $field['settings_raw'] = Kirki_Field::sanitize_settings_raw( $field );
45
+
46
+ // Make sure output is properly formatted
47
+ if ( isset( $field['output'] ) && is_array( $field['output'] ) ) {
48
+
49
+ foreach ( $field['output'] as $output ) {
50
+
51
+ if ( in_array( $output['property'], array( 'font-family', 'font-weight', 'font-subset' ) ) ) {
52
+ // The value of this control
53
+ $value = Kirki::get_option( $field['settings_raw'] );
54
+
55
+ if ( 'font-family' == $output['property'] ) {
56
+ // Add the font-family to the array
57
+ $fonts[]['font-family'] = $value;
58
+ } else if ( 'font-weight' == $output['property'] ) {
59
+ // Add font-weight to the array
60
+ $fonts[]['font-weight'] = $value;
61
+ } else if ( 'font-subset' == $output['property'] ) {
62
+ // add font subsets to the array
63
+ $fonts[]['subsets'] = $value;
64
+ }
65
+
66
+ }
67
+
68
+ }
69
+
70
+ }
71
+
72
+ }
73
+
74
+ foreach ( $fonts as $font ) {
75
+
76
+ // Do we have font-families?
77
+ if ( isset( $font['font-family'] ) ) {
78
+
79
+ $font_families = ( ! isset( $font_families ) ) ? array() : $font_families;
80
+ $font_families[] = $font['font-family'];
81
+
82
+ if ( Kirki_Toolkit::fonts()->is_google_font( $font['font-family'] ) ) {
83
+ $has_google_font = true;
84
+ }
85
+
86
+ }
87
+
88
+ // Do we have font-weights?
89
+ if ( isset( $font['font-weight'] ) ) {
90
+
91
+ $font_weights = ( ! isset( $font_weights ) ) ? array() : $font_weights;
92
+ $font_weights[] = $font['font-weight'];
93
+
94
+ }
95
+
96
+ // Do we have font-subsets?
97
+ if ( isset( $font['subsets'] ) ) {
98
+
99
+ $font_subsets = ( ! isset( $font_subsets ) ) ? array() : $font_subsets;
100
+ $font_subsets[] = $font['subsets'];
101
+
102
+ }
103
+
104
+ }
105
+
106
+ // Make sure there are no empty values and define defaults.
107
+ $font_families = ( ! isset( $font_families ) || empty( $font_families ) ) ? false : $font_families;
108
+ $font_weights = ( ! isset( $font_weights ) || empty( $font_weights ) ) ? '400' : $font_weights;
109
+ $font_subsets = ( ! isset( $font_subsets ) || empty( $font_subsets ) ) ? 'all' : $font_subsets;
110
+
111
+ if ( ! isset( $has_google_font ) || ! $has_google_font ) {
112
+ $font_families = false;
113
+ }
114
+
115
+ // Return the font URL.
116
+ return ( $font_families ) ? Kirki_Toolkit::fonts()->get_google_font_uri( $font_families, $font_weights, $font_subsets ) : false;
117
+
118
+ }
119
+
120
+ /**
121
+ * Enqueue Google fonts if necessary
122
+ */
123
+ public function google_font() {
124
+ if ( $this->google_link() ) {
125
+ $google_link = str_replace( '%3A', ':', $this->google_link() );
126
+ wp_enqueue_style( 'kirki_google_fonts', $google_link, array(), null );
127
+ }
128
+ }
129
+
130
+ }
includes/class-kirki-scripts-registry.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Instantiates all other needed scripts.
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Scripts_Registry' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Scripts_Registry {
24
+
25
+ public $dependencies;
26
+ public $branding;
27
+ public $postmessage;
28
+ public $tooltips;
29
+ public $googlefonts;
30
+
31
+ public function __construct() {
32
+
33
+ $this->dependencies = new Kirki_Scripts_Customizer_Default_Scripts();
34
+ $this->branding = new Kirki_Scripts_Customizer_Branding();
35
+ $this->postmessage = new Kirki_Scripts_Customizer_PostMessage();
36
+ $this->tooltips = new Kirki_Scripts_Customizer_Tooltips();
37
+ $this->googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
38
+
39
+ }
40
+
41
+ /**
42
+ * @param string $script
43
+ */
44
+ public static function prepare( $script ) {
45
+ return '<script>jQuery(document).ready(function($) { "use strict"; '.$script.'});</script>';
46
+ }
47
+
48
+ }
includes/class-kirki-styles-customizer.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Changes the styling of the customizer
4
+ * based on the settings set using the kirki/config filter.
5
+ * For documentation please see
6
+ * https://github.com/reduxframework/kirki/wiki/Styling-the-Customizer
7
+ *
8
+ * @package Kirki
9
+ * @category Core
10
+ * @author Aristeides Stathopoulos
11
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
12
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
13
+ * @since 1.0
14
+ */
15
+
16
+ // Exit if accessed directly
17
+ if ( ! defined( 'ABSPATH' ) ) {
18
+ exit;
19
+ }
20
+
21
+ // Early exit if the class already exists
22
+ if ( class_exists( 'Kirki_Styles_Customizer' ) ) {
23
+ return;
24
+ }
25
+
26
+ class Kirki_Styles_Customizer {
27
+
28
+ public function __construct() {
29
+ add_action( 'customize_controls_print_styles', array( $this, 'customizer_styles' ), 99 );
30
+ }
31
+
32
+ /**
33
+ * Enqueue the stylesheets required.
34
+ */
35
+ public function customizer_styles() {
36
+ wp_enqueue_style( 'kirki-customizer-css', trailingslashit( kirki_url() ).'assets/css/customizer.css', null, '0.5' );
37
+ wp_add_inline_style( 'kirki-customizer-css', $this->custom_css() );
38
+ }
39
+
40
+ /**
41
+ * Add custom CSS rules to the head, applying our custom styles
42
+ */
43
+ public function custom_css() {
44
+
45
+ $color = $this->get_admin_colors();
46
+ $config = apply_filters( 'kirki/config', array() );
47
+
48
+ // Calculate the accent color
49
+ $color_accent = ( isset( $color['icon_colors'] ) && isset( $color['icon_colos']['focus'] ) ) ? $color['icon_colors']['focus'] : '#3498DB';
50
+ if ( isset( $config['color_accent'] ) ) {
51
+ $color_accent = Kirki_Color::sanitize_hex( $config['color_accent'] );
52
+ }
53
+
54
+ // Calculate the background & font colors
55
+ $color_back = false;
56
+ $color_font = false;
57
+ if ( isset( $config['color_back'] ) ) {
58
+ $color_back = Kirki_Color::sanitize_hex( $config['color_back'] );
59
+ $color_font = ( 170 > Kirki_Color::get_brightness( $color_back ) ) ? '#f2f2f2' : '#222';
60
+ }
61
+
62
+ $styles = '';
63
+
64
+ // Width
65
+ if ( isset( $config['width'] ) ) {
66
+ $styles .= '.wp-full-overlay-sidebar{width:'.esc_attr( $config['width'] ).';}';
67
+ $styles .= '.wp-full-overlay.expanded{margin-left:'.esc_attr( $config['width'] ).';}';
68
+ }
69
+
70
+ if ( false !== $color_back && false !== $color_font ) {
71
+
72
+ // Generic background color
73
+ $styles .= '.wp-full-overlay-sidebar{background:'.$color_back.';}';
74
+
75
+ // Title background color
76
+ $styles .= '#customize-controls .customize-info .accordion-section-title, #customize-controls .panel-meta.customize-info .accordion-section-title:hover{background:'.$color_back.';}';
77
+
78
+ // Borders
79
+ $border_color = ( 170 > Kirki_Color::get_brightness( $color_back ) ) ? 'rgba(255,255,255,.2)' : 'rgba(0,0,0,.2)';
80
+ $styles .= '#customize-controls .customize-info{border-top-color:'.$border_color.';border-bottom-color:'.$border_color.';}';
81
+ $styles .= '.customize-section-title{border-bottom-color:'.$border_color.';}';
82
+ $styles .= '.customize-panel-back, .customize-section-back{border-right-color:'.$border_color.';}';
83
+ $styles .= '#customize-header-actions{border-bottom-color:'.$border_color.';}';
84
+ $styles .= '.customize-controls-close, .customize-overlay-close{border-right-color:'.$border_color.'!important;}';
85
+
86
+ // back & close buttons color
87
+ if ( 170 > Kirki_Color::get_brightness( $color_back ) ) {
88
+ $color = Kirki_Color::adjust_brightness( $color_back, 80 );
89
+ } else {
90
+ $color = Kirki_Color::adjust_brightness( $color_back, -80 );
91
+ }
92
+ $styles .= '.customize-panel-back:focus, .customize-panel-back:hover, .customize-section-back:focus, .customize-section-back:hover, .customize-panel-back, .customize-section-back, .customize-controls-close, .customize-overlay-close{background:'.$color.';}';
93
+ $styles .= '.control-panel-back:focus, .control-panel-back:hover, .customize-controls-close:focus, .customize-controls-close:hover, .customize-controls-preview-toggle:focus, .customize-controls-preview-toggle:hover, .customize-overlay-close:focus, .customize-overlay-close:hover{background:'.$color.'}';
94
+
95
+ // Sections list titles
96
+ $styles .= '#customize-theme-controls .accordion-section-title{background:'.$color_back.';color:'.$color_font.';}';
97
+ $color = ( ( 170 > Kirki_Color::get_brightness( $color_accent ) ) ) ? 'color:#ffffff;' : '';
98
+ $styles .= '#customize-controls .control-section .accordion-section-title:focus, #customize-controls .control-section .accordion-section-title:hover, #customize-controls .control-section.open .accordion-section-title, #customize-controls .control-section:hover>.accordion-section-title{background:'.$color_accent.';'.$color.'}';
99
+
100
+ // Arrows
101
+ if ( 170 > Kirki_Color::get_brightness( $color_back ) ) {
102
+ $color = Kirki_Color::adjust_brightness( $color_back, 120 );
103
+ } else {
104
+ $color = Kirki_Color::adjust_brightness( $color_back, -120 );
105
+ }
106
+ $styles .= '.accordion-section-title:after, .handlediv, .item-edit, .sidebar-name-arrow, .widget-action{color:'.$color.'}';
107
+ if ( 170 > Kirki_Color::get_brightness( $color_accent ) ) {
108
+ $color = Kirki_Color::adjust_brightness( $color_accent, 120 );
109
+ } else {
110
+ $color = Kirki_Color::adjust_brightness( $color_accent, -120 );
111
+ }
112
+ $styles .= '#customize-theme-controls .control-section .accordion-section-title:focus:after, #customize-theme-controls .control-section .accordion-section-title:hover:after, #customize-theme-controls .control-section.open .accordion-section-title:after, #customize-theme-controls .control-section:hover>.accordion-section-title:after{color:'.$color.'}';
113
+
114
+ // Title for active section
115
+ $styles .= '.customize-section-title{background:'.$color_back.';}';
116
+ $styles .= '.customize-section-title h3, h3.customize-section-title{color:'.$color_font.';}';
117
+
118
+ // Active section background
119
+ $styles .= '#customize-theme-controls .accordion-section-content{background:'.Kirki_Color::mix_colors( $color_back, '#ffffff', 10 ).';}';
120
+
121
+ // Title color for active panels etc.
122
+ $styles .= '#customize-controls .customize-info .preview-notice{color:'.$color_font.';}';
123
+
124
+ }
125
+
126
+ // Button styles
127
+ $color = ( ( 170 > Kirki_Color::get_brightness( $color_accent ) ) ) ? '#fff' : '#222';
128
+ $styles .= '.wp-core-ui .button-primary-disabled, .wp-core-ui .button-primary.disabled, .wp-core-ui .button-primary:disabled, .wp-core-ui .button-primary[disabled]{background:'.$color_accent.' !important;color:'.$color.' !important;border-color:rgba(0,0,0,.1) !important;opacity:.7;}';
129
+ $styles .= '.wp-core-ui .button-primary{background-color:'.$color_accent.';color:'.$color.';opacity:1;}';
130
+
131
+ // Tooltip styles
132
+ $styles .= '#customize-controls .customize-info .customize-help-toggle{color:'.$color_accent.';}';
133
+
134
+ // Image-Radio styles
135
+ $styles .= '.customize-control-radio-image .image.ui-buttonset label.ui-state-active{border:2px solid '.$color_accent.';}';
136
+
137
+ // Buttonset-Radio styles
138
+ $color = ( ( 170 > Kirki_Color::get_brightness( $color_accent ) ) ) ? '#fff;' : '#222';
139
+ $styles .= '.customize-control-radio-buttonset label.ui-state-active{background-color:'.$color_accent.';color:'.$color.';}';
140
+
141
+ // Slider Controls
142
+ $styles .= '.customize-control-slider .ui-slider .ui-slider-handle{background-color:'.$color_accent.';}';
143
+
144
+ // Switch Controls
145
+ $styles .= '.customize-control-switch .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag{background:'.$color_accent.';}';
146
+
147
+ // Toggle Controls
148
+ $styles .= '.customize-control-toggle .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag{background:'.$color_accent.';}';
149
+
150
+ // Sortable Controls
151
+ $styles .= '.customize-control-sortable ul.ui-sortable li .dashicons.visibility{color:'.$color_accent.';}';
152
+
153
+ // Palette Controls
154
+ $styles .= '.customize-control-palette label.ui-state-active.ui-button.ui-widget span.ui-button-text{border-color:'.$color_accent.';}';
155
+
156
+ return $styles;
157
+
158
+ }
159
+
160
+
161
+ /**
162
+ * Get the admin color theme
163
+ */
164
+ public function get_admin_colors() {
165
+
166
+ // Get the active admin theme
167
+ global $_wp_admin_css_colors;
168
+
169
+ // Get the user's admin colors
170
+ $color = get_user_option( 'admin_color' );
171
+ // If no theme is active set it to 'fresh'
172
+ if ( empty( $color ) || ! isset( $_wp_admin_css_colors[ $color ] ) ) {
173
+ $color = 'fresh';
174
+ }
175
+
176
+ $color = (array) $_wp_admin_css_colors[ $color ];
177
+
178
+ return $color;
179
+
180
+ }
181
+
182
+ }
includes/class-kirki-styles-frontend.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generates the styles for the frontend.
4
+ * Handles the 'output' argument of fields.
5
+ * Usage instructions on https://github.com/reduxframework/kirki/wiki/output
6
+ *
7
+ * @package Kirki
8
+ * @category Core
9
+ * @author Aristeides Stathopoulos
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Styles_Frontend' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Styles_Frontend {
26
+
27
+ public function __construct() {
28
+
29
+ $config = apply_filters( 'kirki/config', array() );
30
+ $priority = ( isset( $config['styles_priority'] ) ) ? intval( $config['styles_priority'] ) : 150;
31
+
32
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_styles' ), $priority );
33
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ), $priority );
34
+
35
+ }
36
+
37
+ /**
38
+ * Add the inline styles
39
+ */
40
+ public function enqueue_styles() {
41
+ wp_add_inline_style( 'kirki-styles', $this->loop_controls() );
42
+ }
43
+
44
+ /**
45
+ * Add a dummy, empty stylesheet.
46
+ */
47
+ public function frontend_styles() {
48
+ wp_enqueue_style( 'kirki-styles', trailingslashit( kirki_url() ).'assets/css/kirki-styles.css', null, null );
49
+
50
+ }
51
+
52
+ /**
53
+ * loop through all fields and create an array of style definitions
54
+ */
55
+ public function loop_controls() {
56
+
57
+ $fields = Kirki::$fields;
58
+ $css = array();
59
+
60
+ // Early exit if no fields are found.
61
+ if ( empty( $fields ) ) {
62
+ return;
63
+ }
64
+
65
+ foreach ( $fields as $field ) {
66
+
67
+ // Only continue if $field['output'] is set
68
+ if ( isset( $field['output'] ) && 'background' != $field['type'] ) {
69
+
70
+ $css = array_merge_recursive( $css, Kirki_Output::css(
71
+ Kirki_Field::sanitize_settings_raw( $field ),
72
+ Kirki_Field::sanitize_type( $field ),
73
+ Kirki_Field::sanitize_output( $field ),
74
+ isset( $field['output']['callback'] ) ? $field['output']['callback'] : '',
75
+ true
76
+ ) );
77
+
78
+ }
79
+
80
+ }
81
+
82
+ return Kirki_Output::styles_parse( Kirki_Output::add_prefixes( $css ) );
83
+
84
+ }
85
+
86
+ }
includes/class-kirki-toolkit.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The main Kirki object
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ // Early exit if the class already exists
19
+ if ( class_exists( 'Kirki_Toolkit' ) ) {
20
+ return;
21
+ }
22
+
23
+ class Kirki_Toolkit {
24
+
25
+ /** @var Kirki The only instance of this class */
26
+ public static $instance = null;
27
+
28
+ public static $version = '1.0.0';
29
+
30
+ public $font_registry = null;
31
+ public $scripts = null;
32
+ public $api = null;
33
+ public $styles = array();
34
+
35
+ /**
36
+ * Access the single instance of this class
37
+ * @return Kirki
38
+ */
39
+ public static function get_instance() {
40
+ if ( null == self::$instance ) {
41
+ self::$instance = new Kirki_Toolkit();
42
+ }
43
+ return self::$instance;
44
+ }
45
+
46
+ /**
47
+ * Shortcut method to get the translation strings
48
+ */
49
+ public static function i18n() {
50
+
51
+ $i18n = array(
52
+ 'background-color' => __( 'Background Color', 'kirki' ),
53
+ 'background-image' => __( 'Background Image', 'kirki' ),
54
+ 'no-repeat' => __( 'No Repeat', 'kirki' ),
55
+ 'repeat-all' => __( 'Repeat All', 'kirki' ),
56
+ 'repeat-x' => __( 'Repeat Horizontally', 'kirki' ),
57
+ 'repeat-y' => __( 'Repeat Vertically', 'kirki' ),
58
+ 'inherit' => __( 'Inherit', 'kirki' ),
59
+ 'background-repeat' => __( 'Background Repeat', 'kirki' ),
60
+ 'cover' => __( 'Cover', 'kirki' ),
61
+ 'contain' => __( 'Contain', 'kirki' ),
62
+ 'background-size' => __( 'Background Size', 'kirki' ),
63
+ 'fixed' => __( 'Fixed', 'kirki' ),
64
+ 'scroll' => __( 'Scroll', 'kirki' ),
65
+ 'background-attachment' => __( 'Background Attachment', 'kirki' ),
66
+ 'left-top' => __( 'Left Top', 'kirki' ),
67
+ 'left-center' => __( 'Left Center', 'kirki' ),
68
+ 'left-bottom' => __( 'Left Bottom', 'kirki' ),
69
+ 'right-top' => __( 'Right Top', 'kirki' ),
70
+ 'right-center' => __( 'Right Center', 'kirki' ),
71
+ 'right-bottom' => __( 'Right Bottom', 'kirki' ),
72
+ 'center-top' => __( 'Center Top', 'kirki' ),
73
+ 'center-center' => __( 'Center Center', 'kirki' ),
74
+ 'center-bottom' => __( 'Center Bottom', 'kirki' ),
75
+ 'background-position' => __( 'Background Position', 'kirki' ),
76
+ 'background-opacity' => __( 'Background Opacity', 'kirki' ),
77
+ 'ON' => __( 'ON', 'kirki' ),
78
+ 'OFF' => __( 'OFF', 'kirki' ),
79
+ 'all' => __( 'All', 'kirki' ),
80
+ 'cyrillic' => __( 'Cyrillic', 'kirki' ),
81
+ 'cyrillic-ext' => __( 'Cyrillic Extended', 'kirki' ),
82
+ 'devanagari' => __( 'Devanagari', 'kirki' ),
83
+ 'greek' => __( 'Greek', 'kirki' ),
84
+ 'greek-ext' => __( 'Greek Extended', 'kirki' ),
85
+ 'khmer' => __( 'Khmer', 'kirki' ),
86
+ 'latin' => __( 'Latin', 'kirki' ),
87
+ 'latin-ext' => __( 'Latin Extended', 'kirki' ),
88
+ 'vietnamese' => __( 'Vietnamese', 'kirki' ),
89
+ 'serif' => _x( 'Serif', 'font style', 'kirki' ),
90
+ 'sans-serif' => _x( 'Sans Serif', 'font style', 'kirki' ),
91
+ 'monospace' => _x( 'Monospace', 'font style', 'kirki' ),
92
+ );
93
+
94
+ $config = apply_filters( 'kirki/config', array() );
95
+
96
+ if ( isset( $config['i18n'] ) ) {
97
+ $i18n = wp_parse_args( $config['i18n'], $i18n );
98
+ }
99
+
100
+ return $i18n;
101
+
102
+ }
103
+
104
+ /**
105
+ * Shortcut method to get the font registry.
106
+ */
107
+ public static function fonts() {
108
+ return self::get_instance()->font_registry;
109
+ }
110
+
111
+ /**
112
+ * Constructor is private, should only be called by get_instance()
113
+ */
114
+ private function __construct() {
115
+ }
116
+
117
+ }
includes/class-kirki.php ADDED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Kirki API class.
4
+ * Takes care of adding panels, sections & fields to the customizer.
5
+ * For documentation please see https://github.com/reduxframework/kirki/wiki
6
+ *
7
+ * @package Kirki
8
+ * @category Core
9
+ * @author Aristeides Stathopoulos
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki {
26
+
27
+ public static $config = array();
28
+ public static $fields = array();
29
+ public static $panels = array();
30
+ public static $sections = array();
31
+
32
+ /**
33
+ * the class constructor
34
+ */
35
+ public function __construct() {
36
+ add_action( 'wp_loaded', array( $this, 'add_to_customizer' ), 1 );
37
+ }
38
+
39
+ /**
40
+ * Helper function that adds the fields, sections and panels to the customizer.
41
+ * @return void
42
+ */
43
+ public function add_to_customizer() {
44
+ $this->fields_from_filters();
45
+ add_action( 'customize_register', array( $this, 'add_panels' ), 97 );
46
+ add_action( 'customize_register', array( $this, 'add_sections' ), 98 );
47
+ add_action( 'customize_register', array( $this, 'add_fields' ), 99 );
48
+ }
49
+
50
+ /**
51
+ * Process fields added using the 'kirki/fields' and 'kirki/controls' filter.
52
+ * These filters are no longer used, this is simply for backwards-compatibility
53
+ */
54
+ public function fields_from_filters() {
55
+
56
+ $fields = apply_filters( 'kirki/controls', array() );
57
+ $fields = apply_filters( 'kirki/fields', $fields );
58
+
59
+ if ( ! empty( $fields ) ) {
60
+ foreach ( $fields as $field ) {
61
+ self::add_field( 'global', $field );
62
+ }
63
+ }
64
+
65
+ }
66
+
67
+ /**
68
+ * Get the value of an option from the db.
69
+ *
70
+ * @var string the ID of the configuration corresponding to this field
71
+ * @var string the field_id (defined as 'settings' in the field arguments)
72
+ *
73
+ * @return mixed the saved value of the field.
74
+ *
75
+ */
76
+ public static function get_option( $config_id = '', $field_id = '' ) {
77
+
78
+ /**
79
+ * Make sure value is defined
80
+ */
81
+ $value = '';
82
+
83
+ /**
84
+ * This allows us to skip the $config_id argument.
85
+ * If we skip adding a $config_id, use the 'global' configuration.
86
+ */
87
+ if ( ( '' == $field_id ) && '' != $config_id ) {
88
+ $field_id = $config_id;
89
+ $config_id = 'global';
90
+ }
91
+
92
+ /**
93
+ * If $config_id is empty, set it to 'global'.
94
+ */
95
+ $config_id = ( '' == $config_id ) ? 'global' : $config_id;
96
+
97
+ /**
98
+ * Are we using options or theme_mods?
99
+ */
100
+ $mode = self::$config[ $config_id ]['option_type'];
101
+
102
+ /**
103
+ * Is there an option name set?
104
+ */
105
+ $option_name = self::$config[ $config_id ]['option_name'];
106
+
107
+ if ( 'theme_mod' == $mode ) {
108
+ /**
109
+ * We're using theme_mods.
110
+ * so just get the value using get_theme_mod
111
+ */
112
+ $value = get_theme_mod( $field_id, self::$fields[ $field_id ]['default'] );
113
+
114
+ /**
115
+ * If the field is a background field, then get the sub-fields
116
+ * and return an array of the values.
117
+ */
118
+ if ( 'background' == self::$fields[ $field_id ]['type'] ) {
119
+ $value = array();
120
+ foreach ( self::$fields[ $field_id ]['default'] as $property_key => $property_default ) {
121
+ $value[ $property_key ] = get_theme_mod( $field_id.'_'.$property_key, $property_default );
122
+ }
123
+ }
124
+
125
+ } elseif ( 'option' == $mode ) {
126
+ /**
127
+ * We're using options.
128
+ */
129
+ if ( '' != $option_name ) {
130
+ /**
131
+ * Options are serialized as a single option in the db.
132
+ * We'll have to get the option and then get the item from the array.
133
+ */
134
+ $options = get_option( $option_name );
135
+
136
+ /**
137
+ * If this is a background field, get the individual sub-fields and return an array.
138
+ */
139
+ if ( 'background' == self::$fields[ $field_id ]['type'] ) {
140
+ $value = array();
141
+ $setting_modified = str_replace( ']', '', str_replace( $option_name.'[', '', $field_id ) );
142
+
143
+ foreach ( self::$fields[ $field_id ]['default'] as $property => $property_default ) {
144
+
145
+ if ( isset( $options[ $setting_modified.'_'.$property ] ) ) {
146
+ $value[ $property ] = $options[ $setting_modified.'_'.$property ];
147
+ } else {
148
+ $value[ $property ] = $property_default;
149
+ }
150
+ }
151
+ } else {
152
+ /**
153
+ * This is not a background field so continue and get the value.
154
+ */
155
+ $value = ( isset( $options[ $field_id ] ) ) ? $options[ $field_id ] : self::$fields[ $field_id ]['default'];
156
+ $value = maybe_unserialize( $value );
157
+ }
158
+
159
+
160
+ } else {
161
+ /**
162
+ * Each option separately saved in the db
163
+ */
164
+ $value = get_option( $field_id, self::$fields[ $field_id ]['default'] );
165
+
166
+ /**
167
+ * If the field is a background field, then get the sub-fields
168
+ * and return an array of the values.
169
+ */
170
+ if ( 'background' == self::$fields[ $field_id ]['type'] ) {
171
+ $value = array();
172
+ foreach ( self::$fields[ $field_id ]['default'] as $property_key => $property_default ) {
173
+ $value[ $property_key ] = get_option( $field_id.'_'.$property_key, $property_default );
174
+ }
175
+ }
176
+
177
+ }
178
+
179
+ }
180
+
181
+ /**
182
+ * reduxframework compatibility tweaks.
183
+ * If KIRKI_REDUX_COMPATIBILITY is defined as true then modify the output of the values
184
+ * and make them compatible with Redux.
185
+ */
186
+ if ( defined( 'KIRKI_REDUX_COMPATIBILITY' ) && KIRKI_REDUX_COMPATIBILITY ) {
187
+
188
+ switch ( self::$fields[ $field_id ]['type'] ) {
189
+
190
+ case 'image' :
191
+ $value = Kirki_Helper::get_image_from_url( $value );
192
+ break;
193
+
194
+ }
195
+
196
+ }
197
+
198
+ return $value;
199
+
200
+ }
201
+
202
+ /**
203
+ * Sets the configuration options.
204
+ *
205
+ * @var string the configuration ID.
206
+ * @var array the configuration options.
207
+ */
208
+ public static function add_config( $config_id, $args = array() ) {
209
+
210
+ $default_args = array(
211
+ 'capability' => 'edit_theme_options',
212
+ 'option_type' => 'theme_mod',
213
+ 'option_name' => '',
214
+ 'compiler' => array(),
215
+ );
216
+ $args = array_merge( $default_args, $args );
217
+
218
+ /**
219
+ * Allow empty value as the config ID by setting the id to global.
220
+ */
221
+ $config_id = ( '' == $config_id ) ? 'global' : $config_id;
222
+ /**
223
+ * Set the config
224
+ */
225
+ self::$config[ $config_id ] = $args;
226
+
227
+ }
228
+
229
+ /**
230
+ * register our panels to the WordPress Customizer
231
+ * @var object The WordPress Customizer object
232
+ */
233
+ public function add_panels( $wp_customize ) {
234
+
235
+ if ( ! empty( self::$panels ) ) {
236
+
237
+ foreach ( self::$panels as $panel ) {
238
+ $wp_customize->add_panel( sanitize_key( $panel['id'] ), array(
239
+ 'title' => esc_textarea( $panel['title'] ),
240
+ 'priority' => esc_attr( $panel['priority'] ),
241
+ 'description' => esc_textarea( $panel['description'] ),
242
+ 'active_callback' => $panel['active_callback'],
243
+ ) );
244
+ }
245
+
246
+ }
247
+ }
248
+
249
+ /**
250
+ * register our sections to the WordPress Customizer
251
+ * @var object The WordPress Customizer object
252
+ */
253
+ public function add_sections( $wp_customize ) {
254
+
255
+ if ( ! empty( self::$sections ) ) {
256
+
257
+ foreach ( self::$sections as $section ) {
258
+ $wp_customize->add_section( sanitize_key( $section['id'] ), array(
259
+ 'title' => esc_textarea( $section['title'] ),
260
+ 'priority' => esc_attr( $section['priority'] ),
261
+ 'panel' => esc_attr( $section['panel'] ),
262
+ 'description' => esc_textarea( $section['description'] ),
263
+ 'active_callback' => $section['active_callback'],
264
+ ) );
265
+ }
266
+
267
+ }
268
+
269
+ }
270
+
271
+ /**
272
+ * Create the settings and controls from the $fields array and register them.
273
+ * @var object The WordPress Customizer object
274
+ */
275
+ public function add_fields( $wp_customize ) {
276
+
277
+ $control_types = apply_filters( 'kirki/control_types', array(
278
+ 'color' => 'WP_Customize_Color_Control',
279
+ 'color-alpha' => 'Kirki_Controls_Color_Alpha_Control',
280
+ 'image' => 'WP_Customize_Image_Control',
281
+ 'upload' => 'WP_Customize_Upload_Control',
282
+ 'switch' => 'Kirki_Controls_Switch_Control',
283
+ 'toggle' => 'Kirki_Controls_Toggle_Control',
284
+ 'radio-buttonset' => 'Kirki_Controls_Radio_ButtonSet_Control',
285
+ 'radio-image' => 'Kirki_Controls_Radio_Image_Control',
286
+ 'sortable' => 'Kirki_Controls_Sortable_Control',
287
+ 'slider' => 'Kirki_Controls_Slider_Control',
288
+ 'number' => 'Kirki_Controls_Number_Control',
289
+ 'multicheck' => 'Kirki_Controls_MultiCheck_Control',
290
+ 'palette' => 'Kirki_Controls_Palette_Control',
291
+ 'custom' => 'Kirki_Controls_Custom_Control',
292
+ 'editor' => 'Kirki_Controls_Editor_Control',
293
+ 'select2' => 'Kirki_Controls_Select2_Control',
294
+ 'select2-multiple' => 'Kirki_Controls_Select2_Multiple_Control'
295
+ ) );
296
+
297
+ foreach ( self::$fields as $field ) {
298
+
299
+ if ( 'background' == $field['type'] ) {
300
+ continue;
301
+ }
302
+
303
+ $wp_customize->add_setting( Kirki_Field::sanitize_settings( $field ), array(
304
+ 'default' => Kirki_Field::sanitize_default( $field ),
305
+ 'type' => Kirki_Field::sanitize_type( $field ),
306
+ 'capability' => Kirki_Field::sanitize_capability( $field ),
307
+ 'transport' => Kirki_Field::sanitize_transport( $field ),
308
+ 'sanitize_callback' => Kirki_Field::sanitize_callback( $field ),
309
+ ) );
310
+
311
+ if ( array_key_exists( $field['type'], $control_types ) ) {
312
+
313
+ $class_name = $control_types[ $field['type'] ];
314
+ $wp_customize->add_control( new $class_name(
315
+ $wp_customize,
316
+ Kirki_Field::sanitize_id( $field ),
317
+ Kirki_Field::sanitize_field( $field )
318
+ ) );
319
+
320
+ } else {
321
+
322
+ $wp_customize->add_control( new WP_Customize_Control(
323
+ $wp_customize,
324
+ Kirki_Field::sanitize_id( $field ),
325
+ Kirki_Field::sanitize_field( $field )
326
+ ) );
327
+
328
+ }
329
+
330
+ }
331
+
332
+ }
333
+
334
+ /**
335
+ * Create a new panel
336
+ *
337
+ * @var string the ID for this panel
338
+ * @var array the panel arguments
339
+ */
340
+ public static function add_panel( $id = '', $args = array() ) {
341
+
342
+ $args['id'] = esc_attr( $id );
343
+ $args['description'] = ( isset( $args['description'] ) ) ? esc_textarea( $args['description'] ) : '';
344
+ $args['priority'] = ( isset( $args['priority'] ) ) ? esc_attr( $args['priority'] ) : 10;
345
+ if ( ! isset( $args['active_callback'] ) ) {
346
+ $args['active_callback'] = ( isset( $args['required'] ) ) ? 'kirki_active_callback' : '__return_true';
347
+ }
348
+
349
+ self::$panels[ $args['id'] ] = $args;
350
+
351
+ }
352
+
353
+ /**
354
+ * Create a new section
355
+ *
356
+ * @var string the ID for this section
357
+ * @var array the section arguments
358
+ */
359
+ public static function add_section( $id, $args ) {
360
+
361
+ $args['id'] = esc_attr( $id );
362
+ $args['panel'] = ( isset( $args['panel'] ) ) ? esc_attr( $args['panel'] ) : '';
363
+ $args['description'] = ( isset( $args['description'] ) ) ? esc_textarea( $args['description'] ) : '';
364
+ $args['priority'] = ( isset( $args['priority'] ) ) ? esc_attr( $args['priority'] ) : 10;
365
+ if ( ! isset( $args['active_callback'] ) ) {
366
+ $args['active_callback'] = ( isset( $args['required'] ) ) ? 'kirki_active_callback' : '__return_true';
367
+ }
368
+
369
+ self::$sections[ $args['id'] ] = $args;
370
+
371
+ }
372
+
373
+ /**
374
+ * Create a new field
375
+ *
376
+ * @var string the configuration ID for this field
377
+ * @var array the field arguments
378
+ */
379
+ public static function add_field( $config_id, $args ) {
380
+
381
+ if ( is_array( $config_id ) && empty( $args ) ) {
382
+ $args = $config_id;
383
+ $config_id = 'global';
384
+ }
385
+
386
+ $config_id = ( '' == $config_id ) ? 'global' : $config_id;
387
+
388
+ /**
389
+ * Get the configuration options
390
+ */
391
+ $config = self::$config[ $config_id ];
392
+
393
+ /**
394
+ * If we've set an option in the configuration
395
+ * then make sure we're using options and not theme_mods
396
+ */
397
+ if ( '' != $config['option_name'] ) {
398
+ $config['option_type'] = 'option';
399
+ }
400
+
401
+ /**
402
+ * If no option name has been set for the field,
403
+ * use the one from the configuration
404
+ */
405
+ if ( ! isset( $args['option_name'] ) ) {
406
+ $args['option_name'] = $config['option_name'];
407
+ }
408
+
409
+ /**
410
+ * If no capability has been set for the field,
411
+ * use the one from the configuration
412
+ */
413
+ if ( ! isset( $args['capability'] ) ) {
414
+ $args['capability'] = $config['capability'];
415
+ }
416
+
417
+ /**
418
+ * Check if [settings] is set.
419
+ * If not set, check for [setting]
420
+ */
421
+ if ( ! isset( $args['settings'] ) && isset( $args['setting'] ) ) {
422
+ $args['settings'] = $args['setting'];
423
+ }
424
+
425
+ /**
426
+ * If no option-type has been set for the field,
427
+ * use the one from the configuration
428
+ */
429
+ if ( ! isset( $args['option_type'] ) ) {
430
+ $args['option_type'] = $config['option_type'];
431
+ }
432
+
433
+ /**
434
+ * Add the field to the static $fields variable properly indexed
435
+ */
436
+ self::$fields[ Kirki_Field::sanitize_settings( $args ) ] = $args;
437
+
438
+ if ( 'background' == $args['type'] ) {
439
+ /**
440
+ * Build the background fields
441
+ */
442
+ self::$fields = Kirki_Explode_Background_Field::process_fields( self::$fields );
443
+ }
444
+
445
+ }
446
+
447
+ /**
448
+ * Build the variables.
449
+ *
450
+ * @return array ('variable-name' => value)
451
+ */
452
+ public function get_variables() {
453
+
454
+ $variables = array();
455
+
456
+ /**
457
+ * Loop through all fields
458
+ */
459
+ foreach ( self::$fields as $field ) {
460
+ /**
461
+ * Check if we have variables for this field
462
+ */
463
+ if ( isset( $field['variables'] ) && false != $field['variables'] && ! empty( $field['variables'] ) ) {
464
+ /**
465
+ * Loop through the array of variables
466
+ */
467
+ foreach ( $field['variables'] as $field_variable ) {
468
+ /**
469
+ * Is the variable ['name'] defined?
470
+ * If yes, then we can proceed.
471
+ */
472
+ if ( isset( $field_variable['name'] ) ) {
473
+ /**
474
+ * Sanitize the variable name
475
+ */
476
+ $variable_name = esc_attr( $field_variable['name'] );
477
+ /**
478
+ * Do we have a callback function defined?
479
+ * If not then set $variable_callback to false.
480
+ */
481
+ $variable_callback = ( isset( $field_variable['callback'] ) && is_callable( $field_variable['callback'] ) ) ? $field_variable['callback'] : false;
482
+ /**
483
+ * If we have a variable_callback defined then get the value of the option
484
+ * and run it through the callback function.
485
+ * If no callback is defined (false) then just get the value.
486
+ */
487
+ if ( $variable_callback ) {
488
+ $variables[ $variable_name ] = call_user_func( $field_variable['callback'], self::get_option( Kirki_Field::sanitize_settings( $field ) ) );
489
+ } else {
490
+ $variables[ $variable_name ] = self::get_option( $field['settings'] );
491
+ }
492
+
493
+ }
494
+
495
+ }
496
+
497
+ }
498
+
499
+ }
500
+ /**
501
+ * Pass the variables through a filter ('kirki/variable')
502
+ * and return the array of variables
503
+ */
504
+ return apply_filters( 'kirki/variable', $variables );
505
+
506
+ }
507
+
508
+ }
includes/controls/color-alpha/class-kirki-controls-color-alpha-control.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * color-alpha Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Color_Alpha_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Color_Alpha_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'color-alpha';
25
+ public $palette = true;
26
+ public $default = '#FFFFFF';
27
+
28
+ public function enqueue() {
29
+
30
+ wp_enqueue_script( 'kirki-color-alpha', trailingslashit( kirki_url() ).'includes/controls/color-alpha/script.js', array( 'jquery' ) );
31
+ wp_enqueue_style( 'kirki-color-alpha', trailingslashit( kirki_url() ).'includes/controls/color-alpha/style.css' );
32
+
33
+ }
34
+
35
+ protected function render() {
36
+ $id = 'customize-control-'.str_replace( '[', '-', str_replace( ']', '', $this->id ) );
37
+ $class = 'customize-control customize-control-'.$this->type; ?>
38
+ <li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
39
+ <?php $this->render_content(); ?>
40
+ </li>
41
+ <?php }
42
+
43
+ public function render_content() { ?>
44
+ <label>
45
+ <span class="customize-control-title">
46
+ <?php echo esc_attr( $this->label ); ?>
47
+ <?php if ( ! empty( $this->description ) ) : ?>
48
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
49
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
50
+ <?php endif; ?>
51
+ </span>
52
+ <input type="text" data-palette="<?php echo esc_textarea( $this->palette ); ?>" data-default-color="<?php echo $this->default; ?>" value="<?php echo intval( $this->value() ); ?>" class="kirki-color-control" <?php $this->link(); ?> />
53
+ </label>
54
+ <?php }
55
+ }
includes/controls/color-alpha/script.js ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+
3
+ if ( typeof Color !== "undefined" ) {
4
+
5
+ Color.prototype.toString = function(remove_alpha) {
6
+ if (remove_alpha == 'no-alpha') {
7
+ return this.toCSS('rgba', '1').replace(/\s+/g, '');
8
+ }
9
+ if (this._alpha < 1) {
10
+ return this.toCSS('rgba', this._alpha).replace(/\s+/g, '');
11
+ }
12
+ var hex = parseInt(this._color, 10).toString(16);
13
+ if (this.error) return '';
14
+ if (hex.length < 6) {
15
+ for (var i = 6 - hex.length - 1; i >= 0; i--) {
16
+ hex = '0' + hex;
17
+ }
18
+ }
19
+ return '#' + hex;
20
+ };
21
+
22
+ $('.kirki-color-control').each(function() {
23
+ var $control = $(this),
24
+ value = $control.val().replace(/\s+/g, '');
25
+ // Manage Palettes
26
+ var palette_input = $control.attr('data-palette');
27
+ if (palette_input == 'false' || palette_input == false) {
28
+ var palette = false;
29
+ } else if (palette_input == 'true' || palette_input == true) {
30
+ var palette = true;
31
+ } else {
32
+ var palette = $control.attr('data-palette').split(",");
33
+ }
34
+ $control.wpColorPicker({ // change some things with the color picker
35
+ clear: function(event, ui) {
36
+ // TODO reset Alpha Slider to 100
37
+ },
38
+ change: function(event, ui) {
39
+ // send ajax request to wp.customizer to enable Save & Publish button
40
+ var _new_value = $control.val();
41
+ var key = $control.attr('data-customize-setting-link');
42
+ wp.customize(key, function(obj) {
43
+ obj.set(_new_value);
44
+ });
45
+ // change the background color of our transparency container whenever a color is updated
46
+ var $transparency = $control.parents('.wp-picker-container:first').find('.transparency');
47
+ // we only want to show the color at 100% alpha
48
+ $transparency.css('backgroundColor', ui.color.toString('no-alpha'));
49
+ },
50
+ palettes: palette // remove the color palettes
51
+ });
52
+ $('<div class="kirki-alpha-container"><div class="slider-alpha"></div><div class="transparency"></div></div>').appendTo($control.parents('.wp-picker-container'));
53
+ var $alpha_slider = $control.parents('.wp-picker-container:first').find('.slider-alpha');
54
+ // if in format RGBA - grab A channel value
55
+ if (value.match(/rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/)) {
56
+ var alpha_val = parseFloat(value.match(/rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/)[1]) * 100;
57
+ var alpha_val = parseInt(alpha_val);
58
+ } else {
59
+ var alpha_val = 100;
60
+ }
61
+ $alpha_slider.slider({
62
+ slide: function(event, ui) {
63
+ $(this).find('.ui-slider-handle').text(ui.value); // show value on slider handle
64
+ // send ajax request to wp.customizer to enable Save & Publish button
65
+ var _new_value = $control.val();
66
+ var key = $control.attr('data-customize-setting-link');
67
+ wp.customize(key, function(obj) {
68
+ obj.set(_new_value);
69
+ });
70
+ },
71
+ create: function(event, ui) {
72
+ var v = $(this).slider('value');
73
+ $(this).find('.ui-slider-handle').text(v);
74
+ },
75
+ value: alpha_val,
76
+ range: "max",
77
+ step: 1,
78
+ min: 1,
79
+ max: 100
80
+ }); // slider
81
+ $alpha_slider.slider().on('slidechange', function(event, ui) {
82
+ var new_alpha_val = parseFloat(ui.value),
83
+ iris = $control.data('a8cIris'),
84
+ color_picker = $control.data('wpWpColorPicker');
85
+ iris._color._alpha = new_alpha_val / 100.0;
86
+ $control.val(iris._color.toString());
87
+ color_picker.toggler.css({
88
+ backgroundColor: $control.val()
89
+ });
90
+ // fix relationship between alpha slider and the 'side slider not updating.
91
+ var get_val = $control.val();
92
+ $($control).wpColorPicker('color', get_val);
93
+ });
94
+ }); // each
95
+ }
96
+ });
includes/controls/color-alpha/style.css ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-color-alpha .kirki-alpha-container {
2
+ box-sizing: padding-box;
3
+ display: none;
4
+ border: 1px solid #dfdfdf;
5
+ border-top: none;
6
+ background: #fff;
7
+ padding: 0 11px 6px; }
8
+ .customize-control-color-alpha .kirki-alpha-container .transparency {
9
+ height: 24px;
10
+ width: 100%;
11
+ background-color: #fff;
12
+ background-image: url("transparency-grid.png");
13
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.4) inset;
14
+ -webkit-border-radius: 3px;
15
+ -moz-border-radius: 3px;
16
+ border-radius: 3px;
17
+ padding: 0; }
18
+ .customize-control-color-alpha .kirki-alpha-container .ui-slider-handle {
19
+ color: #777;
20
+ background-color: #fff;
21
+ text-shadow: 0 1px 0 #fff;
22
+ text-decoration: none;
23
+ position: absolute;
24
+ z-index: 2;
25
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
26
+ border: 1px solid #aaa;
27
+ -webkit-border-radius: 4px;
28
+ -moz-border-radius: 4px;
29
+ border-radius: 4px;
30
+ opacity: 0.9;
31
+ margin-top: -2px;
32
+ height: 20px;
33
+ cursor: ew-resize;
34
+ font-size: 12px;
35
+ padding: 3px; }
36
+ .customize-control-color-alpha .kirki-alpha-container .ui-slider {
37
+ position: relative;
38
+ text-align: center;
39
+ width: 88%; }
40
+ .customize-control-color-alpha .wp-picker-container a.wp-picker-open ~ div.kirki-alpha-container {
41
+ display: block; }
42
+ .customize-control-color-alpha .customize-control-alphacolor .wp-picker-container .iris-picker {
43
+ border-bottom: none; }
44
+
45
+ /*# sourceMappingURL=style.css.map */
includes/controls/color-alpha/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAEI,qDAAuB;EACnB,UAAU,EAAE,WAAW;EACvB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,iBAAiB;EACzB,UAAU,EAAE,IAAI;EAChB,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,UAAU;EACnB,mEAAc;IACV,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,4BAA4B;IAC9C,UAAU,EAAE,gCAA6B;IACzC,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,aAAa,EAAE,GAAG;IAClB,OAAO,EAAE,CAAC;EAEd,uEAAkB;IACd,KAAK,EAAE,IAAI;IACX,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,YAAY;IACzB,eAAe,EAAE,IAAI;IACrB,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,4BAAyB;IACrC,MAAM,EAAE,cAAc;IACtB,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,aAAa,EAAE,GAAG;IAClB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,SAAS;IACjB,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,GAAG;EAEhB,gEAAW;IACP,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,MAAM;IAClB,KAAK,EAAE,GAAG;AAGlB,gGAAkE;EAC9D,OAAO,EAAE,KAAK;AAElB,8FAAgE;EAC5D,aAAa,EAAE,IAAI",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/color-alpha/style.scss ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Color-Alpha Controls
2
+ .customize-control-color-alpha {
3
+ .kirki-alpha-container {
4
+ box-sizing: padding-box;
5
+ display: none;
6
+ border: 1px solid #dfdfdf;
7
+ border-top: none;
8
+ background: #fff;
9
+ padding: 0 11px 6px;
10
+ .transparency {
11
+ height: 24px;
12
+ width: 100%;
13
+ background-color: #fff;
14
+ background-image: url("transparency-grid.png");
15
+ box-shadow: 0 0 5px rgba(0,0,0,0.4) inset;
16
+ -webkit-border-radius: 3px;
17
+ -moz-border-radius: 3px;
18
+ border-radius: 3px;
19
+ padding: 0;
20
+ }
21
+ .ui-slider-handle {
22
+ color: #777;
23
+ background-color: #fff;
24
+ text-shadow: 0 1px 0 #fff;
25
+ text-decoration: none;
26
+ position: absolute;
27
+ z-index: 2;
28
+ box-shadow: 0 1px 2px rgba(0,0,0,0.2);
29
+ border: 1px solid #aaa;
30
+ -webkit-border-radius: 4px;
31
+ -moz-border-radius: 4px;
32
+ border-radius: 4px;
33
+ opacity: 0.9;
34
+ margin-top: -2px;
35
+ height: 20px;
36
+ cursor: ew-resize;
37
+ font-size: 12px;
38
+ padding: 3px;
39
+ }
40
+ .ui-slider {
41
+ position: relative;
42
+ text-align: center;
43
+ width: 88%;
44
+ }
45
+ }
46
+ .wp-picker-container a.wp-picker-open ~ div.kirki-alpha-container {
47
+ display: block;
48
+ }
49
+ .customize-control-alphacolor .wp-picker-container .iris-picker {
50
+ border-bottom: none;
51
+ }
52
+ }
{assets/images → includes/controls/color-alpha}/transparency-grid.png RENAMED
File without changes
includes/controls/custom/class-kirki-controls-custom-control.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * custom Customizer Control.
4
+ *
5
+ * Creates a new custom control.
6
+ * Custom controls accept raw HTML/JS.
7
+ *
8
+ * @package Kirki
9
+ * @subpackage Controls
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Controls_Custom_Control' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Controls_Custom_Control extends WP_Customize_Control {
26
+
27
+ public $type = 'custom';
28
+
29
+ public function render_content() { ?>
30
+ <label>
31
+ <span class="customize-control-title">
32
+ <?php echo esc_attr( $this->label ); ?>
33
+ <?php if ( ! empty( $this->description ) ) : ?>
34
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
35
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
36
+ <?php endif; ?>
37
+ </span>
38
+ <?php
39
+ /**
40
+ * The value is defined by the developer in the field configuration as 'default'.
41
+ * There is no user input on this field, it's a raw HTML/JS field and we do not sanitize it.
42
+ * Do not be alarmed, this is not a security issue.
43
+ * In order for someone to be able to change this they would have to have access to your filesystem.
44
+ * If that happens, they can change whatever they want anyways. This field is not a concern.
45
+ */
46
+ ?>
47
+ <?php echo $this->value(); ?>
48
+ </label>
49
+ <?php
50
+
51
+ }
52
+
53
+ }
includes/controls/editor/class-kirki-controls-editor-control.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * editor Customizer Control.
4
+ *
5
+ * Creates a TinyMCE textarea.
6
+ *
7
+ * @package Kirki
8
+ * @subpackage Controls
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // Early exit if the class already exists
20
+ if ( class_exists( 'Kirki_Controls_Editor_Control' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Kirki_Controls_Editor_Control extends WP_Customize_Control {
25
+
26
+ public $type = 'editor';
27
+
28
+ public function enqueue() {
29
+ wp_enqueue_script( 'kirki-editor', trailingslashit( kirki_url() ).'includes/controls/editor/kirki-editor.js', array( 'jquery' ) );
30
+ }
31
+
32
+ public function render_content() { ?>
33
+
34
+ <label>
35
+ <span class="customize-control-title">
36
+ <?php echo esc_attr( $this->label ); ?>
37
+ <?php if ( ! empty( $this->description ) ) : ?>
38
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
39
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
40
+ <?php endif; ?>
41
+ </span>
42
+ <input type="hidden" <?php $this->link(); ?> value="<?php echo esc_textarea( $this->value() ); ?>">
43
+ <?php
44
+ $settings = array(
45
+ 'textarea_name' => $this->id,
46
+ 'teeny' => true,
47
+ );
48
+ wp_editor( esc_textarea( $this->value() ), $this->id, $settings );
49
+
50
+ do_action( 'admin_footer' );
51
+ do_action( 'admin_print_footer_scripts' );
52
+ ?>
53
+ </label>
54
+ <?php
55
+ }
56
+
57
+ }
includes/controls/editor/kirki-editor.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ wp.customizerCtrlEditor = {
3
+
4
+ init: function() {
5
+
6
+ $(window).load(function() {
7
+
8
+ $('textarea.wp-editor-area').each(function() {
9
+ var tArea = $(this),
10
+ id = tArea.attr('id'),
11
+ input = $('input[data-customize-setting-link="' + id + '"]'),
12
+ editor = tinyMCE.get(id),
13
+ setChange,
14
+ content;
15
+
16
+ if (editor) {
17
+ editor.onChange.add(function(ed, e) {
18
+ ed.save();
19
+ content = editor.getContent();
20
+ clearTimeout(setChange);
21
+ setChange = setTimeout(function() {
22
+ input.val(content).trigger('change');
23
+ }, 500);
24
+ });
25
+ }
26
+
27
+ if (editor) {
28
+ editor.onChange.add(function(ed, e) {
29
+ ed.save();
30
+ content = editor.getContent();
31
+ clearTimeout(setChange);
32
+ setChange = setTimeout(function() {
33
+ input.val(content).trigger('change');
34
+ }, 500);
35
+ });
36
+ }
37
+
38
+ tArea.css({
39
+ visibility: 'visible'
40
+ }).on('keyup', function() {
41
+ content = tArea.val();
42
+ clearTimeout(setChange);
43
+ setChange = setTimeout(function() {
44
+ input.val(content).trigger('change');
45
+ }, 500);
46
+ });
47
+ });
48
+ });
49
+ }
50
+
51
+ };
52
+
53
+ wp.customizerCtrlEditor.init();
54
+
55
+ })(jQuery);
includes/controls/multicheck/class-kirki-controls-multicheck-control.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * editor Customizer Control.
4
+ *
5
+ * Multiple checkbox customize control class.
6
+ * Props @ Justin Tadlock: http://justintadlock.com/archives/2015/05/26/multiple-checkbox-customizer-control
7
+ *
8
+ * @package Kirki
9
+ * @subpackage Controls
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Controls_MultiCheck_Control' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Controls_MultiCheck_Control extends WP_Customize_Control {
26
+
27
+ public $type = 'multicheck';
28
+
29
+ public function enqueue() {
30
+
31
+ wp_enqueue_script( 'kirki-multicheck', trailingslashit( kirki_url() ).'includes/controls/multicheck/kirki-multicheck.js', array( 'jquery' ) );
32
+ wp_enqueue_style( 'kirki-multicheck', trailingslashit( kirki_url() ).'includes/controls/multicheck/style.css' );
33
+
34
+ }
35
+
36
+ public function render_content() {
37
+
38
+ if ( empty( $this->choices ) ) {
39
+ return;
40
+ }
41
+ ?>
42
+
43
+ <?php if ( ! empty( $this->label ) ) : ?>
44
+ <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
45
+ <?php endif; ?>
46
+
47
+ <?php if ( ! empty( $this->description ) ) : ?>
48
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
49
+ <?php endif; ?>
50
+
51
+ <?php $multi_values = ( ! is_array( $this->value() ) ) ? explode( ',', $this->value() ) : $this->value(); ?>
52
+
53
+ <ul>
54
+ <?php foreach ( $this->choices as $value => $label ) : ?>
55
+ <li>
56
+ <label>
57
+ <input type="checkbox" value="<?php echo esc_attr( $value ); ?>" <?php checked( in_array( $value, $multi_values ) ); ?> />
58
+ <?php echo esc_html( $label ); ?>
59
+ </label>
60
+ </li>
61
+ <?php endforeach; ?>
62
+ </ul>
63
+
64
+ <input type="hidden" <?php $this->link(); ?> value="<?php echo esc_attr( implode( ',', $multi_values ) ); ?>" />
65
+ <?php }
66
+ }
includes/controls/multicheck/kirki-multicheck.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function() {
2
+ jQuery( '.customize-control-multicheck input[type="checkbox"]' ).on( 'change', function() {
3
+ checkbox_values = jQuery( this ).parents( '.customize-control' ).find( 'input[type="checkbox"]:checked' ).map(
4
+ function() { return this.value; }
5
+ ).get().join( ',' );
6
+ jQuery( this ).parents( '.customize-control' ).find( 'input[type="hidden"]' ).val( checkbox_values ).trigger( 'change' );
7
+ }
8
+ ); } );
includes/controls/multicheck/style.css ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-checkbox input[type="checkbox"],
2
+ .customize-control-multicheck input[type="checkbox"] {
3
+ position: relative;
4
+ margin: 0 1rem 0 0;
5
+ cursor: pointer;
6
+ margin-bottom: 5px;
7
+ width: 22px;
8
+ height: 22px; }
9
+ .customize-control-checkbox input[type="checkbox"]:before,
10
+ .customize-control-multicheck input[type="checkbox"]:before {
11
+ content: "";
12
+ position: absolute;
13
+ left: 0;
14
+ z-index: 1;
15
+ width: 100%;
16
+ height: 100%;
17
+ border: none; }
18
+ .customize-control-checkbox input[type="checkbox"]:after,
19
+ .customize-control-multicheck input[type="checkbox"]:after {
20
+ content: "";
21
+ position: absolute;
22
+ left: 0;
23
+ top: 0;
24
+ width: 100%;
25
+ height: 100%;
26
+ background: #fff;
27
+ cursor: pointer; }
28
+ .customize-control-checkbox input[type="checkbox"]:checked:before,
29
+ .customize-control-multicheck input[type="checkbox"]:checked:before {
30
+ border: 4px solid #4caf50;
31
+ -webkit-transform: rotate(-45deg);
32
+ -moz-transform: rotate(-45deg);
33
+ -ms-transform: rotate(-45deg);
34
+ -o-transform: rotate(-45deg);
35
+ transform: rotate(-45deg);
36
+ width: 14px;
37
+ height: 6px;
38
+ top: 6px;
39
+ left: 5px;
40
+ border-top-style: none;
41
+ border-right-style: none; }
42
+ .customize-control-checkbox input[type="checkbox"]:checked:after,
43
+ .customize-control-multicheck input[type="checkbox"]:checked:after {
44
+ background: #f2f2f2; }
45
+
46
+ /*# sourceMappingURL=style.css.map */
includes/controls/multicheck/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAkDI;oDAAuB;EAjDvB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,UAAU;EAClB,MAAM,EAAE,OAAO;EACf,aAAa,EAAE,GAAG;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ;6DAAS;IACL,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;EAEhB;4DAAQ;IACJ,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,OAAO;EAGf;qEAAS;IACL,MAAM,EAAE,iBAAiB;IACzB,iBAAiB,EAAE,cAAc;IACjC,cAAc,EAAE,cAAc;IAC9B,aAAa,EAAE,cAAc;IAC7B,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,cAAc;IACzB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,GAAG;IACT,gBAAgB,EAAE,IAAI;IACtB,kBAAkB,EAAE,IAAI;EAE5B;oEAAQ;IACJ,UAAU,EAAE,OAAO",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/multicheck/style.scss ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @mixin custom-checkbox() {
2
+ position: relative;
3
+ margin: 0 1rem 0 0;
4
+ cursor: pointer;
5
+ margin-bottom: 5px;
6
+ width: 22px;
7
+ height: 22px;
8
+ &:before {
9
+ content: "";
10
+ position: absolute;
11
+ left: 0;
12
+ z-index: 1;
13
+ width: 100%;
14
+ height: 100%;
15
+ border: none;
16
+ }
17
+ &:after {
18
+ content: "";
19
+ position: absolute;
20
+ left: 0;
21
+ top: 0;
22
+ width: 100%;
23
+ height: 100%;
24
+ background: #fff;
25
+ cursor: pointer;
26
+ }
27
+ &:checked {
28
+ &:before {
29
+ border: 4px solid #4caf50;
30
+ -webkit-transform: rotate(-45deg);
31
+ -moz-transform: rotate(-45deg);
32
+ -ms-transform: rotate(-45deg);
33
+ -o-transform: rotate(-45deg);
34
+ transform: rotate(-45deg);
35
+ width: 14px;
36
+ height: 6px;
37
+ top: 6px;
38
+ left: 5px;
39
+ border-top-style: none;
40
+ border-right-style: none;
41
+ }
42
+ &:after {
43
+ background: #f2f2f2;
44
+ }
45
+ }
46
+ }
47
+
48
+ // Checkbox & Multicheck Controls
49
+ .customize-control-checkbox,
50
+ .customize-control-multicheck {
51
+ input[type="checkbox"] {
52
+ @include custom-checkbox();
53
+ }
54
+ }
includes/controls/number/class-kirki-controls-number-control.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * number Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Number_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ /**
23
+ * Create a simple number control
24
+ */
25
+ class Kirki_Controls_Number_Control extends WP_Customize_Control {
26
+
27
+ public $type = 'number';
28
+
29
+ public function enqueue() {
30
+
31
+ wp_enqueue_script( 'formstone', trailingslashit( kirki_url() ).'includes/controls/number/formstone-core.js', array( 'jquery' ) );
32
+ wp_enqueue_script( 'formstone-number', trailingslashit( kirki_url() ).'includes/controls/number/formstone-number.js', array( 'jquery', 'formstone' ) );
33
+ wp_enqueue_style( 'kirki-number', trailingslashit( kirki_url() ).'includes/controls/number/style.css' );
34
+
35
+ }
36
+
37
+ public function render_content() {
38
+
39
+ if ( ! empty( $this->choices ) ) {
40
+ $min = ( isset( $this->choices['min'] ) ) ? ' min="'.esc_attr( $this->choices['min'] ).'"' : '';
41
+ $max = ( isset( $this->choices['max'] ) ) ? ' max="'.esc_attr( $this->choices['max'] ).'"' : '';
42
+ $step = ( isset( $this->choices['step'] ) ) ? ' step="'.esc_attr( $this->choices['step'] ).'"' : '';
43
+ } else {
44
+ $min = '';
45
+ $max = '';
46
+ $step = '';
47
+ }
48
+ ?>
49
+
50
+ <label class="customizer-text">
51
+ <span class="customize-control-title">
52
+ <?php echo esc_attr( $this->label ); ?>
53
+ <?php if ( ! empty( $this->description ) ) : ?>
54
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
55
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
56
+ <?php endif; ?>
57
+ </span>
58
+ <input type="number"<?php echo $min.$max.$step; ?> <?php $this->link(); ?> value="<?php echo intval( $this->value() ); ?>"/>
59
+ </label>
60
+ <script>
61
+ jQuery(document).ready(function($) {
62
+ "use strict";
63
+ $( "#customize-control-<?php echo $this->id; ?> input[type='number']").number();
64
+ });
65
+ </script>
66
+
67
+ <?php
68
+ }
69
+ }
includes/controls/number/formstone-core.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.1 [core.js] 2015-05-22 | MIT License | formstone.it */
2
+
3
+ var Formstone=this.Formstone=function(a,b,c,d){"use strict";function e(a){m.Plugins[a].initialized||(m.Plugins[a].methods._setup.call(c),m.Plugins[a].initialized=!0)}function f(a,b,c,d){var e,f={raw:{}};d=d||{};for(e in d)d.hasOwnProperty(e)&&("classes"===a?(f.raw[d[e]]=b+"-"+d[e],f[d[e]]="."+b+"-"+d[e]):(f.raw[e]=d[e],f[e]=d[e]+"."+b));for(e in c)c.hasOwnProperty(e)&&("classes"===a?(f.raw[e]=c[e].replace(/{ns}/g,b),f[e]=c[e].replace(/{ns}/g,"."+b)):(f.raw[e]=c[e].replace(/.{ns}/g,""),f[e]=c[e].replace(/{ns}/g,b)));return f}function g(){var a,b={transition:"transitionend",MozTransition:"transitionend",OTransition:"otransitionend",WebkitTransition:"webkitTransitionEnd"},d=["transition","-webkit-transition"],e={transform:"transform",MozTransform:"-moz-transform",OTransform:"-o-transform",msTransform:"-ms-transform",webkitTransform:"-webkit-transform"},f="transitionend",g="",h="",i=c.createElement("div");for(a in b)if(b.hasOwnProperty(a)&&a in i.style){f=b[a],m.support.transition=!0;break}o.transitionEnd=f+".{ns}";for(a in d)if(d.hasOwnProperty(a)&&d[a]in i.style){g=d[a];break}m.transition=g;for(a in e)if(e.hasOwnProperty(a)&&e[a]in i.style){m.support.transform=!0,h=e[a];break}m.transform=h}function h(){m.windowWidth=m.$window.width(),m.windowHeight=m.$window.height(),p=l.startTimer(p,q,i)}function i(){for(var a in m.ResizeHandlers)m.ResizeHandlers.hasOwnProperty(a)&&m.ResizeHandlers[a].callback.call(b,m.windowWidth,m.windowHeight)}function j(a,b){return parseInt(a.priority)-parseInt(b.priority)}var k=function(){this.Version="0.6.1",this.Plugins={},this.ResizeHandlers=[],this.window=b,this.$window=a(b),this.document=c,this.$document=a(c),this.$body=null,this.windowWidth=0,this.windowHeight=0,this.userAgent=b.navigator.userAgent||b.navigator.vendor||b.opera,this.isFirefox=/Firefox/i.test(this.userAgent),this.isChrome=/Chrome/i.test(this.userAgent),this.isSafari=/Safari/i.test(this.userAgent)&&!this.isChrome,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(this.userAgent),this.isFirefoxMobile=this.isFirefox&&this.isMobile,this.transform=null,this.transition=null,this.support={file:!!(b.File&&b.FileList&&b.FileReader),history:!!(b.history&&b.history.pushState&&b.history.replaceState),matchMedia:!(!b.matchMedia&&!b.msMatchMedia),raf:!(!b.requestAnimationFrame||!b.cancelAnimationFrame),touch:!!("ontouchstart"in b||b.DocumentTouch&&c instanceof b.DocumentTouch),transition:!1,transform:!1}},l={killEvent:function(a,b){try{a.preventDefault(),a.stopPropagation(),b&&a.stopImmediatePropagation()}catch(c){}},startTimer:function(a,b,c,d){return l.clearTimer(a),d?setInterval(c,b):setTimeout(c,b)},clearTimer:function(a,b){a&&(b?clearInterval(a):clearTimeout(a),a=null)},sortAsc:function(a,b){return parseInt(b)-parseInt(a)},sortDesc:function(a,b){return parseInt(b)-parseInt(a)}},m=new k,n={base:"{ns}",element:"{ns}-element"},o={namespace:".{ns}",blur:"blur.{ns}",change:"change.{ns}",click:"click.{ns}",dblClick:"dblclick.{ns}",drag:"drag.{ns}",dragEnd:"dragend.{ns}",dragEnter:"dragenter.{ns}",dragLeave:"dragleave.{ns}",dragOver:"dragover.{ns}",dragStart:"dragstart.{ns}",drop:"drop.{ns}",error:"error.{ns}",focus:"focus.{ns}",focusIn:"focusin.{ns}",focusOut:"focusout.{ns}",input:"input.{ns}",keyDown:"keydown.{ns}",keyPress:"keypress.{ns}",keyUp:"keyup.{ns}",load:"load.{ns}",mouseDown:"mousedown.{ns}",mouseEnter:"mouseenter.{ns}",mouseLeave:"mouseleave.{ns}",mouseMove:"mousemove.{ns}",mouseOut:"mouseout.{ns}",mouseOver:"mouseover.{ns}",mouseUp:"mouseup.{ns}",resize:"resize.{ns}",scroll:"scroll.{ns}",select:"select.{ns}",touchCancel:"touchcancel.{ns}",touchEnd:"touchend.{ns}",touchLeave:"touchleave.{ns}",touchMove:"touchmove.{ns}",touchStart:"touchstart.{ns}"};k.prototype.Plugin=function(c,d){return m.Plugins[c]=function(c,d){function g(b){var f="object"===a.type(b);b=a.extend(!0,{},d.defaults||{},f?b:{});for(var g=this,h=0,j=g.length;j>h;h++){var k=g.eq(h);if(!i(k)){var l=k.data(c+"-options"),m=a.extend(!0,{$el:k},b,"object"===a.type(l)?l:{});k.addClass(d.classes.raw.element).data(s,m),e(c),d.methods._construct.apply(k,[m].concat(Array.prototype.slice.call(arguments,f?1:0)))}}return g}function h(a){d.functions.iterate.apply(this,[d.methods._destruct].concat(Array.prototype.slice.call(arguments,1))),this.removeClass(d.classes.raw.element).removeData(s)}function i(a){return a.data(s)}function k(b){if(this instanceof a){var c=d.methods[b];return"object"!==a.type(b)&&b?c&&0!==b.indexOf("_")?d.functions.iterate.apply(this,[c].concat(Array.prototype.slice.call(arguments,1))):this:g.apply(this,arguments)}}function p(c){var e=d.utilities[c]||d.utilities._initialize||!1;return e?e.apply(b,Array.prototype.slice.call(arguments,"object"===a.type(c)?0:1)):void 0}function q(b){d.defaults=a.extend(!0,d.defaults,b||{})}function r(b){for(var c=this,d=0,e=c.length;e>d;d++){var f=c.eq(d),g=i(f)||{};"undefined"!==a.type(g.$el)&&b.apply(f,[g].concat(Array.prototype.slice.call(arguments,1)))}return c}var s="fs-"+c;return d.initialized=!1,d.priority=d.priority||10,d.classes=f("classes",s,n,d.classes),d.events=f("events",c,o,d.events),d.functions=a.extend({getData:i,iterate:r},l,d.functions),d.methods=a.extend(!0,{_setup:a.noop,_construct:a.noop,_destruct:a.noop,_resize:!1,destroy:h},d.methods),d.utilities=a.extend(!0,{_initialize:!1,_delegate:!1,defaults:q},d.utilities),d.widget&&(a.fn[c]=k),a[c]=d.utilities._delegate||p,d.namespace=c,d.methods._resize&&(m.ResizeHandlers.push({namespace:c,priority:d.priority,callback:d.methods._resize}),m.ResizeHandlers.sort(j)),d}(c,d),m.Plugins[c]};var p=null,q=20;return m.$window.on("resize.fs",h),h(),a(function(){m.$body=a("body");for(var b in m.Plugins)m.Plugins.hasOwnProperty(b)&&e(b)}),o.clickTouchStart=o.click+" "+o.touchStart,g(),m}(jQuery,this,document);
includes/controls/number/formstone-number.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.1 [number.js] 2015-05-22 | MIT License | formstone.it */
2
+
3
+ !function(a,b,c){"use strict";function d(){t=b.$body}function e(a){var b=parseFloat(this.attr("min")),c=parseFloat(this.attr("max"));a.min=b||0===b?b:!1,a.max=c||0===c?c:!1,a.step=parseFloat(this.attr("step"))||1,a.timer=null,a.digits=m(a.step),a.disabled=this.prop("disabled");var d="";d+='<button type="button" class="'+[q.arrow,q.up].join(" ")+'">'+a.labels.up+"</button>",d+='<button type="button" class="'+[q.arrow,q.down].join(" ")+'">'+a.labels.down+"</button>",this.wrap('<div class="'+[q.base,a.customClass,a.disabled?q.disabled:""].join(" ")+'"></div>').after(d),a.$container=this.parent(p.base),a.$arrows=a.$container.find(p.arrow),this.on(r.keyPress,p.element,a,i),a.$container.on([r.touchStart,r.mouseDown].join(" "),p.arrow,a,j)}function f(a){a.$arrows.remove(),this.unwrap().off(r.namespace)}function g(a){a.disabled&&(this.prop("disabled",!1),a.$container.removeClass(q.disabled),a.disabled=!1)}function h(a){a.disabled||(this.prop("disabled",!0),a.$container.addClass(q.disabled),a.disabled=!0)}function i(a){var b=a.data;(38===a.keyCode||40===a.keyCode)&&(a.preventDefault(),l(b,38===a.keyCode?b.step:-b.step))}function j(b){s.killEvent(b),k(b);var c=b.data;if(!c.disabled){var d=a(b.target).hasClass(q.up)?c.step:-c.step;c.timer=s.startTimer(c.timer,110,function(){l(c,d,!1)},!0),l(c,d),t.on([r.touchEnd,r.mouseUp].join(" "),c,k)}}function k(a){s.killEvent(a);var b=a.data;s.clearTimer(b.timer,!0),t.off(r.namespace)}function l(b,c){var d=parseFloat(b.$el.val()),e=c;"undefined"===a.type(d)||isNaN(d)?e=b.min!==!1?b.min:0:b.min!==!1&&d<b.min?e=b.min:e+=d;var f=(e-b.min)%b.step;0!==f&&(e-=f),b.min!==!1&&e<b.min&&(e=b.min),b.max!==!1&&e>b.max&&(e-=b.step),e!==d&&(e=n(e,b.digits),b.$el.val(e).trigger(r.raw.change))}function m(a){var b=String(a);return b.indexOf(".")>-1?b.length-b.indexOf(".")-1:0}function n(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c}var o=b.Plugin("number",{widget:!0,defaults:{customClass:"",labels:{up:"Up",down:"Down"}},classes:["arrow","up","down","disabled"],methods:{_setup:d,_construct:e,_destruct:f,enable:g,disable:h},events:{tap:"tap"}}),p=o.classes,q=p.raw,r=o.events,s=o.functions,t=null}(jQuery,Formstone);
includes/controls/number/style.css ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-number .fs-number {
2
+ position: relative;
3
+ border-radius: 3px;
4
+ margin: 0 0 10px 0;
5
+ overflow: hidden; }
6
+ .customize-control-number .fs-number,
7
+ .customize-control-number .fs-number:after,
8
+ .customize-control-number .fs-number:before,
9
+ .customize-control-number .fs-number *,
10
+ .customize-control-number .fs-number *:after,
11
+ .customize-control-number .fs-number *:before {
12
+ box-sizing: border-box;
13
+ -webkit-transition: none;
14
+ transition: none;
15
+ -webkit-user-select: none !important;
16
+ -moz-user-select: none !important;
17
+ -ms-user-select: none !important;
18
+ user-select: none !important; }
19
+ .customize-control-number .fs-number-element {
20
+ width: 100%;
21
+ height: 2.5em;
22
+ background: #ffffff;
23
+ border: 1px solid #cccccc;
24
+ border-bottom-width: 2px;
25
+ border-radius: 3px;
26
+ color: #222222;
27
+ font-size: 15px;
28
+ line-height: 1;
29
+ overflow: hidden;
30
+ padding: 0 10px;
31
+ -moz-appearance: textfield; }
32
+ .customize-control-number .fs-number-element::-webkit-inner-spin-button, .customize-control-number .fs-number-element::-webkit-outer-spin-button {
33
+ margin: 0;
34
+ -webkit-appearance: none; }
35
+ .customize-control-number .fs-number-element::-ms-clear {
36
+ display: none; }
37
+ .customize-control-number .fs-number-element:focus {
38
+ background-color: #ffffff; }
39
+ .customize-control-number .fs-number-disabled .fs-number-element {
40
+ background: #ffffff;
41
+ border-color: #cccccc;
42
+ color: #cccccc; }
43
+ .customize-control-number .fs-number-arrow {
44
+ width: 25px;
45
+ height: 50%;
46
+ position: absolute;
47
+ right: 0;
48
+ z-index: 1;
49
+ background: #ffffff;
50
+ border: 1px solid #cccccc;
51
+ cursor: pointer;
52
+ display: block;
53
+ overflow: hidden;
54
+ text-indent: 200%;
55
+ white-space: nowrap; }
56
+ .customize-control-number .fs-number-arrow:focus {
57
+ outline: none; }
58
+ .customize-control-number .fs-number-arrow:after {
59
+ width: 0;
60
+ height: 0;
61
+ position: absolute;
62
+ top: 0;
63
+ right: 0;
64
+ bottom: 0;
65
+ left: 0;
66
+ border-left: 5px solid transparent;
67
+ border-right: 5px solid transparent;
68
+ content: '';
69
+ display: block;
70
+ margin: auto; }
71
+ .customize-control-number .fs-number-arrow.fs-number-up {
72
+ top: 0; }
73
+ .customize-control-number .fs-number-arrow.fs-number-up:after {
74
+ border-bottom: 5px solid #666666; }
75
+ .customize-control-number .fs-number-arrow.fs-number-down {
76
+ bottom: 0;
77
+ border-top: none; }
78
+ .customize-control-number .fs-number-arrow.fs-number-down:after {
79
+ border-top: 5px solid #666666; }
80
+ .customize-control-number .no-opacity .fs-number-arrow {
81
+ text-indent: -999999px; }
82
+ .customize-control-number .fs-number-disabled .fs-number-arrow {
83
+ cursor: default; }
84
+ .customize-control-number .fs-number-disabled .fs-number-arrow:after {
85
+ border-top-color: #cccccc;
86
+ border-bottom-color: #cccccc; }
87
+
88
+ /*# sourceMappingURL=style.css.map */
includes/controls/number/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAEI,oCAAW;EACP,QAAQ,EAAE,QAAQ;EAClB,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,UAAU;EAClB,QAAQ,EAAE,MAAM;AAEpB;;;;;6CAKoB;EAChB,UAAU,EAAE,UAAU;EACtB,kBAAkB,EAAE,IAAI;EACxB,UAAU,EAAE,IAAI;EAChB,mBAAmB,EAAE,eAAe;EACpC,gBAAgB,EAAE,eAAe;EACjC,eAAe,EAAE,eAAe;EAChC,WAAW,EAAE,eAAe;AAEhC,4CAAmB;EACf,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EACzB,mBAAmB,EAAE,GAAG;EACxB,aAAa,EAAE,GAAG;EAClB,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,CAAC;EACd,QAAQ,EAAE,MAAM;EAChB,OAAO,EAAE,MAAM;EACf,eAAe,EAAE,SAAS;EAC1B,gJAC6B;IACzB,MAAM,EAAE,CAAC;IACT,kBAAkB,EAAE,IAAI;EAE5B,uDAAa;IACT,OAAO,EAAE,IAAI;EAEjB,kDAAQ;IACJ,gBAAgB,EAAE,OAAO;AAGjC,gEAAuC;EACnC,UAAU,EAAE,OAAO;EACnB,YAAY,EAAE,OAAO;EACrB,KAAK,EAAE,OAAO;AAElB,0CAAiB;EACb,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,CAAC;EACR,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EACzB,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,KAAK;EACd,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,MAAM;EACnB,gDAAQ;IACJ,OAAO,EAAE,IAAI;EAEjB,gDAAQ;IACJ,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,WAAW,EAAE,qBAAqB;IAClC,YAAY,EAAE,qBAAqB;IACnC,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,IAAI;EAEhB,uDAAe;IACX,GAAG,EAAE,CAAC;EAEV,6DAAqB;IACjB,aAAa,EAAE,iBAAiB;EAEpC,yDAAiB;IACb,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,IAAI;IAChB,+DAAQ;MACJ,UAAU,EAAE,iBAAiB;AAIzC,sDAA6B;EACzB,WAAW,EAAE,SAAS;AAGtB,8DAAiB;EACb,MAAM,EAAE,OAAO;EACf,oEAAQ;IACJ,gBAAgB,EAAE,OAAO;IACzB,mBAAmB,EAAE,OAAO",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/number/style.scss ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Number Controls
2
+ .customize-control-number {
3
+ .fs-number {
4
+ position: relative;
5
+ border-radius: 3px;
6
+ margin: 0 0 10px 0;
7
+ overflow: hidden;
8
+ }
9
+ .fs-number,
10
+ .fs-number:after,
11
+ .fs-number:before,
12
+ .fs-number *,
13
+ .fs-number *:after,
14
+ .fs-number *:before {
15
+ box-sizing: border-box;
16
+ -webkit-transition: none;
17
+ transition: none;
18
+ -webkit-user-select: none !important;
19
+ -moz-user-select: none !important;
20
+ -ms-user-select: none !important;
21
+ user-select: none !important;
22
+ }
23
+ .fs-number-element {
24
+ width: 100%;
25
+ height: 2.5em;
26
+ background: #ffffff;
27
+ border: 1px solid #cccccc;
28
+ border-bottom-width: 2px;
29
+ border-radius: 3px;
30
+ color: #222222;
31
+ font-size: 15px;
32
+ line-height: 1;
33
+ overflow: hidden;
34
+ padding: 0 10px;
35
+ -moz-appearance: textfield;
36
+ &::-webkit-inner-spin-button,
37
+ &::-webkit-outer-spin-button {
38
+ margin: 0;
39
+ -webkit-appearance: none;
40
+ }
41
+ &::-ms-clear {
42
+ display: none;
43
+ }
44
+ &:focus {
45
+ background-color: #ffffff;
46
+ }
47
+ }
48
+ .fs-number-disabled .fs-number-element {
49
+ background: #ffffff;
50
+ border-color: #cccccc;
51
+ color: #cccccc;
52
+ }
53
+ .fs-number-arrow {
54
+ width: 25px;
55
+ height: 50%;
56
+ position: absolute;
57
+ right: 0;
58
+ z-index: 1;
59
+ background: #ffffff;
60
+ border: 1px solid #cccccc;
61
+ cursor: pointer;
62
+ display: block;
63
+ overflow: hidden;
64
+ text-indent: 200%;
65
+ white-space: nowrap;
66
+ &:focus {
67
+ outline: none;
68
+ }
69
+ &:after {
70
+ width: 0;
71
+ height: 0;
72
+ position: absolute;
73
+ top: 0;
74
+ right: 0;
75
+ bottom: 0;
76
+ left: 0;
77
+ border-left: 5px solid transparent;
78
+ border-right: 5px solid transparent;
79
+ content: '';
80
+ display: block;
81
+ margin: auto;
82
+ }
83
+ &.fs-number-up {
84
+ top: 0;
85
+ }
86
+ &.fs-number-up:after {
87
+ border-bottom: 5px solid #666666;
88
+ }
89
+ &.fs-number-down {
90
+ bottom: 0;
91
+ border-top: none;
92
+ &:after {
93
+ border-top: 5px solid #666666;
94
+ }
95
+ }
96
+ }
97
+ .no-opacity .fs-number-arrow {
98
+ text-indent: -999999px;
99
+ }
100
+ .fs-number-disabled {
101
+ .fs-number-arrow {
102
+ cursor: default;
103
+ &:after {
104
+ border-top-color: #cccccc;
105
+ border-bottom-color: #cccccc;
106
+ }
107
+ }
108
+ }
109
+ }
includes/{Controls/PaletteControl.php → controls/palette/class-kirki-controls-palette-control.php} RENAMED
@@ -1,13 +1,33 @@
1
  <?php
 
 
 
 
 
 
 
 
 
2
 
3
- namespace Kirki\Controls;
 
 
 
 
 
 
 
 
4
 
5
- class PaletteControl extends \WP_Customize_Control {
6
 
7
  public $type = 'palette';
8
 
9
  public function enqueue() {
 
10
  wp_enqueue_script( 'jquery-ui-button' );
 
 
11
  }
12
 
13
  public function render_content() {
@@ -16,26 +36,21 @@ class PaletteControl extends \WP_Customize_Control {
16
  return;
17
  }
18
 
19
- $name = '_customize-palette-' . $this->id;
20
 
21
  ?>
22
  <span class="customize-control-title">
23
- <?php
24
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
25
- ?>
26
- <?php echo $this->label; ?>
27
  <?php if ( ! empty( $this->description ) ) : ?>
28
- <?php
29
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
30
- ?>
31
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
32
  <?php endif; ?>
33
  </span>
34
 
35
  <div id="input_<?php echo $this->id; ?>" class="buttonset">
36
  <?php foreach ( $this->choices as $value => $colorSet ) : ?>
37
- <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id . $value; ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
38
- <label for="<?php echo $this->id . $value; ?>">
39
  <?php
40
  foreach ( $colorSet as $color ) {
41
  printf( "<span style='background: {$color}'>{$color}</span>" );
1
  <?php
2
+ /**
3
+ * palette Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
 
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Palette_Control' ) ) {
19
+ return;
20
+ }
21
 
22
+ class Kirki_Controls_Palette_Control extends WP_Customize_Control {
23
 
24
  public $type = 'palette';
25
 
26
  public function enqueue() {
27
+
28
  wp_enqueue_script( 'jquery-ui-button' );
29
+ wp_enqueue_style( 'kirki-palette', trailingslashit( kirki_url() ).'includes/controls/palette/style.css' );
30
+
31
  }
32
 
33
  public function render_content() {
36
  return;
37
  }
38
 
39
+ $name = '_customize-palette-'.$this->id;
40
 
41
  ?>
42
  <span class="customize-control-title">
43
+ <?php echo esc_attr( $this->label ); ?>
 
 
 
44
  <?php if ( ! empty( $this->description ) ) : ?>
45
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
 
 
46
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
47
  <?php endif; ?>
48
  </span>
49
 
50
  <div id="input_<?php echo $this->id; ?>" class="buttonset">
51
  <?php foreach ( $this->choices as $value => $colorSet ) : ?>
52
+ <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id.esc_attr( $value ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
53
+ <label for="<?php echo $this->id.esc_attr( $value ); ?>">
54
  <?php
55
  foreach ( $colorSet as $color ) {
56
  printf( "<span style='background: {$color}'>{$color}</span>" );
includes/controls/palette/style.css ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-palette label.ui-button.ui-widget {
2
+ width: 95%;
3
+ background: none;
4
+ padding: 0; }
5
+ .customize-control-palette label.ui-button.ui-widget .ui-button-text {
6
+ border-top: 3px solid transparent;
7
+ border-bottom: 3px solid transparent;
8
+ margin-bottom: 5px;
9
+ display: flex; }
10
+ .customize-control-palette label.ui-button.ui-widget .ui-button-text span {
11
+ padding: 10px 0;
12
+ flex-grow: 1;
13
+ font-size: 0;
14
+ line-height: 10px;
15
+ color: transparent;
16
+ -webkit-transition: all 200ms ease-in-out;
17
+ -moz-transition: all 200ms ease-in-out;
18
+ -ms-transition: all 200ms ease-in-out;
19
+ -o-transition: all 200ms ease-in-out;
20
+ transition: all 200ms ease-in-out; }
21
+ .customize-control-palette label.ui-button.ui-widget .ui-button-text span:hover {
22
+ padding: 10px;
23
+ flex-grow: 3;
24
+ min-width: 60px;
25
+ font-size: 10px;
26
+ line-height: 10px;
27
+ color: #000; }
28
+ .customize-control-palette label.ui-state-active.ui-button.ui-widget span.ui-button-text {
29
+ border: 3px solid #333; }
30
+
31
+ /*# sourceMappingURL=style.css.map */
includes/controls/palette/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAGQ,oDAAsB;EAClB,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,CAAC;EACV,oEAAgB;IACZ,UAAU,EAAE,qBAAqB;IACjC,aAAa,EAAE,qBAAqB;IACpC,aAAa,EAAE,GAAG;IAClB,OAAO,EAAE,IAAI;IACb,yEAAK;MACD,OAAO,EAAE,MAAM;MACf,SAAS,EAAE,CAAC;MACZ,SAAS,EAAE,CAAC;MACZ,WAAW,EAAE,IAAI;MACjB,KAAK,EAAE,WAAa;MACpB,kBAAkB,EAAE,qBAAqB;MACzC,eAAe,EAAE,qBAAqB;MACtC,cAAc,EAAE,qBAAqB;MACrC,aAAa,EAAE,qBAAqB;MACpC,UAAU,EAAE,qBAAqB;MACjC,+EAAQ;QACJ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;QACjB,KAAK,EAAE,IAAI;AAOnB,wFAAoB;EAChB,MAAM,EAAE,cAAc",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/palette/style.scss ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Palette controls
2
+ .customize-control-palette {
3
+ label {
4
+ &.ui-button.ui-widget {
5
+ width: 95%;
6
+ background: none;
7
+ padding: 0;
8
+ .ui-button-text {
9
+ border-top: 3px solid transparent;
10
+ border-bottom: 3px solid transparent;
11
+ margin-bottom: 5px;
12
+ display: flex;
13
+ span {
14
+ padding: 10px 0;
15
+ flex-grow: 1;
16
+ font-size: 0;
17
+ line-height: 10px;
18
+ color: rgba(0,0,0,0);
19
+ -webkit-transition: all 200ms ease-in-out;
20
+ -moz-transition: all 200ms ease-in-out;
21
+ -ms-transition: all 200ms ease-in-out;
22
+ -o-transition: all 200ms ease-in-out;
23
+ transition: all 200ms ease-in-out;
24
+ &:hover {
25
+ padding: 10px;
26
+ flex-grow: 3;
27
+ min-width: 60px;
28
+ font-size: 10px;
29
+ line-height: 10px;
30
+ color: #000;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ &.ui-state-active {
36
+ &.ui-button.ui-widget {
37
+ span.ui-button-text {
38
+ border: 3px solid #333;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
includes/controls/radio-buttonset/class-kirki-controls-radio-buttonset-control.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * radio-buttonset Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Radio_Buttonset_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Radio_Buttonset_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'radio-buttonset';
25
+
26
+ public function enqueue() {
27
+ wp_enqueue_script( 'jquery-ui-button' );
28
+ wp_enqueue_style( 'kirki-radio-buttonset', trailingslashit( kirki_url() ).'includes/controls/radio-buttonset/style.css' );
29
+ }
30
+
31
+ public function render_content() {
32
+
33
+ if ( empty( $this->choices ) ) {
34
+ return;
35
+ }
36
+
37
+ $name = '_customize-radio-'.$this->id;
38
+
39
+ ?>
40
+ <span class="customize-control-title">
41
+ <?php echo esc_attr( $this->label ); ?>
42
+ <?php if ( ! empty( $this->description ) ) : ?>
43
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
44
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
45
+ <?php endif; ?>
46
+ </span>
47
+
48
+ <div id="input_<?php echo $this->id; ?>" class="buttonset">
49
+ <?php foreach ( $this->choices as $value => $label ) : ?>
50
+ <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id.esc_attr( $value ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
51
+ <label for="<?php echo $this->id.esc_attr( $value ); ?>">
52
+ <?php echo esc_html( $label ); ?>
53
+ </label>
54
+ </input>
55
+ <?php endforeach; ?>
56
+ </div>
57
+ <script>jQuery(document).ready(function($) { $( '[id="input_<?php echo $this->id; ?>"]' ).buttonset(); });</script>
58
+ <?php
59
+ }
60
+
61
+ }
includes/controls/radio-buttonset/style.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-radio-buttonset label {
2
+ padding: 5px 10px;
3
+ background: #f7f7f7;
4
+ border-left: 1px solid #dedede;
5
+ line-height: 35px; }
6
+ .customize-control-radio-buttonset label.ui-state-active {
7
+ background: #dedede; }
8
+ .customize-control-radio-buttonset label.ui-corner-left {
9
+ border-radius: 3px 0 0 3px;
10
+ border-left: 0; }
11
+ .customize-control-radio-buttonset label.ui-corner-right {
12
+ border-radius: 0 3px 3px 0; }
13
+
14
+ /*# sourceMappingURL=style.css.map */
includes/controls/radio-buttonset/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAKI,wCAAM;EACF,OAAO,EAAE,QAAQ;EACjB,UAAU,EAAE,OAAO;EACnB,WAAW,EAAE,iBAAiB;EAC9B,WAAW,EAAE,IAAI;EACjB,wDAAkB;IACd,UAAU,EAAE,OAAO;EAEvB,uDAAiB;IACb,aAAa,EAAE,WAAW;IAC1B,WAAW,EAAE,CAAC;EAElB,wDAAkB;IACd,aAAa,EAAE,WAAW",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/radio-buttonset/style.scss ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Radio-Buttonset Controls
2
+ .customize-control-radio-buttonset {
3
+ input[type=radio] {
4
+
5
+ }
6
+ label {
7
+ padding: 5px 10px;
8
+ background: #f7f7f7;
9
+ border-left: 1px solid #dedede;
10
+ line-height: 35px;
11
+ &.ui-state-active {
12
+ background: #dedede;
13
+ }
14
+ &.ui-corner-left {
15
+ border-radius: 3px 0 0 3px;
16
+ border-left: 0;
17
+ }
18
+ &.ui-corner-right {
19
+ border-radius: 0 3px 3px 0;
20
+ }
21
+ }
22
+ }
includes/controls/radio-image/class-kirki-controls-radio-image-control.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * radio-image Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Radio_Image_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Radio_Image_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'radio-image';
25
+
26
+ public function enqueue() {
27
+ wp_enqueue_script( 'jquery-ui-button' );
28
+ wp_enqueue_style( 'kirki-radio-image', trailingslashit( kirki_url() ).'includes/controls/radio-image/style.css' );
29
+ }
30
+
31
+ public function render_content() {
32
+
33
+ if ( empty( $this->choices ) ) {
34
+ return;
35
+ }
36
+
37
+ $name = '_customize-radio-'.$this->id;
38
+
39
+ ?>
40
+ <span class="customize-control-title">
41
+ <?php echo esc_attr( $this->label ); ?>
42
+ <?php if ( ! empty( $this->description ) ) : ?>
43
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
44
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
45
+ <?php endif; ?>
46
+ </span>
47
+ <div id="input_<?php echo $this->id; ?>" class="image">
48
+ <?php foreach ( $this->choices as $value => $label ) : ?>
49
+ <input class="image-select" type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" id="<?php echo $this->id.esc_attr( $value ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?>>
50
+ <label for="<?php echo $this->id.esc_attr( $value ); ?>">
51
+ <img src="<?php echo esc_html( $label ); ?>">
52
+ </label>
53
+ </input>
54
+ <?php endforeach; ?>
55
+ </div>
56
+ <script>jQuery(document).ready(function($) { $( '[id="input_<?php echo $this->id; ?>"]' ).buttonset(); });</script>
57
+ <?php
58
+ }
59
+
60
+ }
includes/controls/radio-image/style.css ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-radio-image .image.ui-buttonset input[type=radio] {
2
+ height: auto; }
3
+ .customize-control-radio-image .image.ui-buttonset label {
4
+ border: 1px solid transparent;
5
+ display: inline-block;
6
+ margin-right: 5px;
7
+ margin-bottom: 5px; }
8
+ .customize-control-radio-image .image.ui-buttonset label.ui-state-active {
9
+ background: none;
10
+ border-color: #333; }
11
+
12
+ /*# sourceMappingURL=style.css.map */
includes/controls/radio-image/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAGQ,oEAAkB;EACd,MAAM,EAAE,IAAI;AAEhB,wDAAM;EACF,MAAM,EAAE,qBAAqB;EAC7B,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,GAAG;EACjB,aAAa,EAAE,GAAG;EAClB,wEAAkB;IACd,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/radio-image/style.scss ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Radio-Image Controls
2
+ .customize-control-radio-image {
3
+ .image.ui-buttonset {
4
+ input[type=radio] {
5
+ height: auto;
6
+ }
7
+ label {
8
+ border: 1px solid transparent;
9
+ display: inline-block;
10
+ margin-right: 5px;
11
+ margin-bottom: 5px;
12
+ &.ui-state-active {
13
+ background: none;
14
+ border-color: #333;
15
+ }
16
+ }
17
+ }
18
+ }
includes/controls/select2-multiple/class-kirki-controls-select2-multiple-control.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * select2-multiple
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Select2_Multiple_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Select2_Multiple_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'select2-multiple';
25
+
26
+ protected function render() {
27
+ $id = str_replace( '[', '-', str_replace( ']', '', $this->id ) );
28
+ $class = 'customize-control customize-control-'.$this->type; ?>
29
+ <li id="customize-control-<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
30
+ <?php $this->render_content(); ?>
31
+ </li>
32
+ <?php }
33
+
34
+ public function render_content() {
35
+ $id = str_replace( '[', '-', str_replace( ']', '', $this->id ) );
36
+
37
+ if ( empty( $this->choices ) ) {
38
+ return;
39
+ } ?>
40
+
41
+ <label>
42
+ <span class="customize-control-title">
43
+ <?php echo esc_attr( $this->label ); ?>
44
+ <?php if ( ! empty( $this->description ) ) : ?>
45
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
46
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
47
+ <?php endif; ?>
48
+ </span>
49
+
50
+ <select data-customize-setting-link="<?php echo esc_attr( $id ); ?>" class="select2" multiple="multiple">
51
+ <?php foreach ( $this->choices as $value => $label ) : ?>
52
+ <option value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $label ); ?></option>
53
+ <?php endforeach; ?>
54
+ </select>
55
+ </label>
56
+
57
+ <script>
58
+ jQuery(document).ready(function($) {
59
+ $('.select2').select2();
60
+ });
61
+ </script>
62
+ <?php
63
+ }
64
+
65
+ }
includes/controls/select2/class-kirki-controls-select2-control.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * select2 Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Select2_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Select2_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'select2';
25
+
26
+ protected function render() {
27
+ $id = str_replace( '[', '-', str_replace( ']', '', $this->id ) );
28
+ $class = 'customize-control customize-control-'.$this->type; ?>
29
+ <li id="customize-control-<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
30
+ <?php $this->render_content(); ?>
31
+ </li>
32
+ <?php }
33
+
34
+ public function render_content() {
35
+ $id = str_replace( '[', '-', str_replace( ']', '', $this->id ) );
36
+
37
+ if ( empty( $this->choices ) ) {
38
+ return;
39
+ } ?>
40
+
41
+ <label>
42
+ <span class="customize-control-title">
43
+ <?php echo esc_attr( $this->label ); ?>
44
+ <?php if ( ! empty( $this->description ) ) : ?>
45
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
46
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
47
+ <?php endif; ?>
48
+ </span>
49
+
50
+ <select data-customize-setting-link="<?php echo esc_attr( $id ); ?>" class="select2">
51
+ <?php foreach ( $this->choices as $value => $label ) : ?>
52
+ <option value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $label ); ?></option>
53
+ <?php endforeach; ?>
54
+ </select>
55
+ </label>
56
+
57
+ <script>
58
+ jQuery(document).ready(function($) {
59
+ $('.select2').select2();
60
+ });
61
+ </script>
62
+ <?php
63
+ }
64
+
65
+ }
includes/controls/slider/class-kirki-controls-slider-control.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * slider Customizer Control.
4
+ *
5
+ * Creates a jQuery slider control.
6
+ * TODO: Migrate to an HTML5 range control. Range control are hard to style 'cause they don't display the value
7
+ *
8
+ * @package Kirki
9
+ * @subpackage Controls
10
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
11
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
12
+ * @since 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ // Early exit if the class already exists
21
+ if ( class_exists( 'Kirki_Controls_Slider_Control' ) ) {
22
+ return;
23
+ }
24
+
25
+ class Kirki_Controls_Slider_Control extends WP_Customize_Control {
26
+
27
+ public $type = 'slider';
28
+
29
+ public function enqueue() {
30
+
31
+ wp_enqueue_script( 'jquery-ui' );
32
+ wp_enqueue_script( 'jquery-ui-slider' );
33
+ wp_enqueue_style( 'kirki-slider', trailingslashit( kirki_url() ).'includes/controls/slider/style.css' );
34
+
35
+ }
36
+
37
+ public function render_content() { ?>
38
+ <label>
39
+
40
+ <span class="customize-control-title">
41
+ <?php echo esc_attr( $this->label ); ?>
42
+ <?php if ( ! empty( $this->description ) ) : ?>
43
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
44
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
45
+ <?php endif; ?>
46
+ </span>
47
+
48
+ <input type="text" class="kirki-slider" id="input_<?php echo $this->id; ?>" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?>/>
49
+
50
+ </label>
51
+
52
+ <div id="slider_<?php echo $this->id; ?>" class="ss-slider"></div>
53
+ <script>
54
+ jQuery(document).ready(function($) {
55
+ $( '[id="slider_<?php echo $this->id; ?>"]' ).slider({
56
+ value : <?php echo esc_attr( $this->value() ); ?>,
57
+ min : <?php echo $this->choices['min']; ?>,
58
+ max : <?php echo $this->choices['max']; ?>,
59
+ step : <?php echo $this->choices['step']; ?>,
60
+ slide : function( event, ui ) { $( '[id="input_<?php echo $this->id; ?>"]' ).val(ui.value).keyup(); }
61
+ });
62
+ $( '[id="input_<?php echo $this->id; ?>"]' ).val( $( '[id="slider_<?php echo $this->id; ?>"]' ).slider( "value" ) );
63
+
64
+ $( '[id="input_<?php echo $this->id; ?>"]' ).change(function() {
65
+ $( '[id="slider_<?php echo $this->id; ?>"]' ).slider({
66
+ value : $( this ).val()
67
+ });
68
+ });
69
+
70
+ });
71
+ </script>
72
+ <?php
73
+
74
+ }
75
+ }
includes/controls/slider/style.css ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-slider input[type="text"] {
2
+ border: none;
3
+ text-align: center;
4
+ padding: 0;
5
+ margin: 0;
6
+ font-size: 12px;
7
+ box-shadow: none;
8
+ color: #333; }
9
+ .customize-control-slider .ui-slider {
10
+ position: relative;
11
+ text-align: left;
12
+ height: 7px;
13
+ border-radius: 3px;
14
+ background: #f2f2f2;
15
+ border: 1px solid #dedede;
16
+ margin-top: 10px;
17
+ margin-bottom: 20px; }
18
+ .customize-control-slider .ui-slider .ui-slider-handle {
19
+ position: absolute;
20
+ z-index: 2;
21
+ width: 15px;
22
+ height: 15px;
23
+ top: -5px;
24
+ border-radius: 50%;
25
+ cursor: default;
26
+ -ms-touch-action: none;
27
+ touch-action: none;
28
+ background: #333;
29
+ border: 1px solid #333; }
30
+ .customize-control-slider .ui-slider .ui-slider-range {
31
+ position: absolute;
32
+ z-index: 1;
33
+ font-size: 0.7em;
34
+ display: block;
35
+ border: 0;
36
+ background-position: 0 0; }
37
+
38
+ /*# sourceMappingURL=style.css.map */
includes/controls/slider/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAEI,4CAAmB;EACf,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,SAAS,EAAE,IAAI;EACf,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;AAEf,oCAAW;EACP,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EACzB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,IAAI;EACnB,sDAAkB;IACd,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,GAAG,EAAE,IAAI;IACT,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,OAAO;IACf,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,cAAc;EAE1B,qDAAiB;IACb,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,KAAK;IAChB,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,CAAC;IACT,mBAAmB,EAAE,GAAG",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/slider/style.scss ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Slider Controls
2
+ .customize-control-slider {
3
+ input[type="text"] {
4
+ border: none;
5
+ text-align: center;
6
+ padding: 0;
7
+ margin: 0;
8
+ font-size: 12px;
9
+ box-shadow: none;
10
+ color: #333;
11
+ }
12
+ .ui-slider {
13
+ position: relative;
14
+ text-align: left;
15
+ height: 7px;
16
+ border-radius: 3px;
17
+ background: #f2f2f2;
18
+ border: 1px solid #dedede;
19
+ margin-top: 10px;
20
+ margin-bottom: 20px;
21
+ .ui-slider-handle {
22
+ position: absolute;
23
+ z-index: 2;
24
+ width: 15px;
25
+ height: 15px;
26
+ top: -5px;
27
+ border-radius: 50%;
28
+ cursor: default;
29
+ -ms-touch-action: none;
30
+ touch-action: none;
31
+ background: #333;
32
+ border: 1px solid #333;
33
+ }
34
+ .ui-slider-range {
35
+ position: absolute;
36
+ z-index: 1;
37
+ font-size: 0.7em;
38
+ display: block;
39
+ border: 0;
40
+ background-position: 0 0;
41
+ }
42
+ }
43
+ }
includes/{Controls/SortableControl.php → controls/sortable/class-kirki-controls-sortable-control.php} RENAMED
@@ -1,54 +1,74 @@
1
  <?php
 
 
 
 
 
 
 
 
 
2
 
3
- namespace Kirki\Controls;
 
 
 
 
 
 
 
 
4
 
5
- class SortableControl extends \WP_Customize_Control {
6
 
7
  public $type = 'sortable';
8
 
9
  public function enqueue() {
 
10
  wp_enqueue_script( 'jquery-ui-core' );
11
  wp_enqueue_script( 'jquery-ui-sortable' );
 
 
 
 
12
  }
13
 
14
 
15
  public function render_content() {
16
- if ( ! is_array( $this->choices ) ) {
17
- return;
18
- }
19
- if ( ! count( $this->choices ) ) {
20
  return;
21
  }
22
 
23
  ?>
24
  <label class='kirki-sortable'>
25
  <span class="customize-control-title">
26
- <?php
27
- // The label has already been sanitized in the Fields class, no need to re-sanitize it.
28
- ?>
29
- <?php echo $this->label; ?>
30
  <?php if ( ! empty( $this->description ) ) : ?>
31
- <?php
32
- // The description has already been sanitized in the Fields class, no need to re-sanitize it.
33
- ?>
34
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
35
  <?php endif; ?>
36
  </span>
37
-
38
  <?php
39
  $values = $this->value();
40
  $values = $values == '' ? array_keys( $this->choices ) : $values;
41
  $values = maybe_unserialize( $values );
42
  $this->visible_button = count( $values ) != count( $this->choices ) ? true : '';
43
  $visibleButton = '<i class="dashicons dashicons-visibility visibility"></i>';
 
 
 
 
 
 
 
44
  ?>
45
  <ul>
46
- <?php foreach ( $values as $key => $value ) : ?>
47
- <?php printf( "<li class='kirki-sortable-item' data-value='%s'><i class='dashicons dashicons-menu'></i>%s%s</li>", esc_attr( $value ), $visibleButton, $this->choices[$value] ); ?>
48
  <?php endforeach; ?>
49
- <?php $invisibleKeys = array_diff( array_keys( $this->choices ), $values ); ?>
50
  <?php foreach ( $invisibleKeys as $key => $value ) : ?>
51
- <?php printf( "<li class='kirki-sortable-item' data-value='%s'><i class='dashicons dashicons-menu'></i>%s%s</li>", esc_attr( $value ), $visibleButton, $this->choices[$value] ); ?>
52
  <?php endforeach; ?>
53
  </ul>
54
  <div style='clear: both'></div>
1
  <?php
2
+ /**
3
+ * sortable Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
 
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Sortable_Control' ) ) {
19
+ return;
20
+ }
21
 
22
+ class Kirki_Controls_Sortable_Control extends WP_Customize_Control {
23
 
24
  public $type = 'sortable';
25
 
26
  public function enqueue() {
27
+
28
  wp_enqueue_script( 'jquery-ui-core' );
29
  wp_enqueue_script( 'jquery-ui-sortable' );
30
+
31
+ wp_enqueue_script( 'kirki-sortable', trailingslashit( kirki_url() ).'includes/controls/sortable/kirki-sortable.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-sortable' ) );
32
+ wp_enqueue_style( 'kirki-sortable', trailingslashit( kirki_url() ).'includes/controls/sortable/style.css' );
33
+
34
  }
35
 
36
 
37
  public function render_content() {
38
+ if ( ! is_array( $this->choices ) || ! count( $this->choices ) ) {
 
 
 
39
  return;
40
  }
41
 
42
  ?>
43
  <label class='kirki-sortable'>
44
  <span class="customize-control-title">
45
+ <?php echo esc_attr( $this->label ); ?>
 
 
 
46
  <?php if ( ! empty( $this->description ) ) : ?>
47
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
 
 
48
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
49
  <?php endif; ?>
50
  </span>
 
51
  <?php
52
  $values = $this->value();
53
  $values = $values == '' ? array_keys( $this->choices ) : $values;
54
  $values = maybe_unserialize( $values );
55
  $this->visible_button = count( $values ) != count( $this->choices ) ? true : '';
56
  $visibleButton = '<i class="dashicons dashicons-visibility visibility"></i>';
57
+
58
+ $filtered_values = array();
59
+ foreach ( $values as $key => $value ) {
60
+ if ( in_array( $key, $this->choices ) ) {
61
+ $filtered_values[ $key ] = $value;
62
+ }
63
+ }
64
  ?>
65
  <ul>
66
+ <?php foreach ( $filtered_values as $key => $value ) : ?>
67
+ <?php printf( "<li class='kirki-sortable-item' data-value='%s'><i class='dashicons dashicons-menu'></i>%s%s</li>", esc_attr( $value ), $visibleButton, $this->choices[ $value ] ); ?>
68
  <?php endforeach; ?>
69
+ <?php $invisibleKeys = array_diff( array_keys( $this->choices ), $filtered_values ); ?>
70
  <?php foreach ( $invisibleKeys as $key => $value ) : ?>
71
+ <?php printf( "<li class='kirki-sortable-item' data-value='%s'><i class='dashicons dashicons-menu'></i>%s%s</li>", esc_attr( $value ), $visibleButton, $this->choices[ $value ] ); ?>
72
  <?php endforeach; ?>
73
  </ul>
74
  <div style='clear: both'></div>
includes/controls/sortable/kirki-sortable.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+ "use strict";
3
+ // initialize
4
+ $('.kirki-sortable > ul ~ input').each(function() {
5
+ var value = $(this).val();
6
+ try {
7
+ value = unserialize(value);
8
+ } catch (err) {
9
+ return;
10
+ }
11
+ var ul = $(this).siblings('ul:eq(0)');
12
+ ul.find('li').addClass('invisible').find('i.visibility').toggleClass('dashicons-visibility-faint');
13
+ $.each(value, function(i, val) {
14
+ ul.find('li[data-value=' + val + ']').removeClass('invisible').find('i.visibility').toggleClass('dashicons-visibility-faint');
15
+ });
16
+ });
17
+ $('.kirki-sortable > ul').each(function() {
18
+ $(this).sortable()
19
+ .disableSelection()
20
+ .on("sortstop", function(event, ui) {
21
+ kirkiUpdateSortable(ui.item.parent());
22
+ })
23
+ .find('li').each(function() {
24
+ $(this).find('i.visibility').click(function() {
25
+ $(this).toggleClass('dashicons-visibility-faint').parents('li:eq(0)').toggleClass('invisible');
26
+ });
27
+ })
28
+ .click(function() {
29
+ kirkiUpdateSortable($(this).parents('ul:eq(0)'));
30
+ })
31
+ });
32
+
33
+ });
34
+
35
+ function kirkiUpdateSortable(ul) {
36
+ "use strict";
37
+ var $ = jQuery;
38
+ var values = [];
39
+ ul.find('li').each(function() {
40
+ if (!$(this).is('.invisible')) {
41
+ values.push($(this).attr('data-value'));
42
+ }
43
+ });
44
+ ul.siblings('input').eq(0).val(serialize(values)).trigger('change');
45
+ }
includes/controls/sortable/style.css ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-sortable ul.ui-sortable li {
2
+ padding: 5px 10px;
3
+ border: 1px solid #333;
4
+ background: #fff; }
5
+ .customize-control-sortable ul.ui-sortable li .dashicons.dashicons-menu {
6
+ float: right; }
7
+ .customize-control-sortable ul.ui-sortable li .dashicons.visibility {
8
+ margin-right: 10px; }
9
+ .customize-control-sortable ul.ui-sortable li.invisible {
10
+ color: #aaa;
11
+ border: 1px dashed #aaa; }
12
+ .customize-control-sortable ul.ui-sortable li.invisible .dashicons.visibility {
13
+ color: #aaa; }
14
+
15
+ /*# sourceMappingURL=style.css.map */
includes/controls/sortable/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAGQ,6CAAG;EACC,OAAO,EAAE,QAAQ;EACjB,MAAM,EAAE,cAAc;EACtB,UAAU,EAAE,IAAI;EAEZ,uEAAiB;IACb,KAAK,EAAE,KAAK;EAEhB,mEAAa;IACT,YAAY,EAAE,IAAI;EAG1B,uDAAY;IACR,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,eAAe;IACvB,6EAAsB;MAClB,KAAK,EAAE,IAAI",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/sortable/style.scss ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Sortable Controls
2
+ .customize-control-sortable {
3
+ ul.ui-sortable {
4
+ li {
5
+ padding: 5px 10px;
6
+ border: 1px solid #333;
7
+ background: #fff;
8
+ .dashicons {
9
+ &.dashicons-menu {
10
+ float: right;
11
+ }
12
+ &.visibility {
13
+ margin-right: 10px;
14
+ }
15
+ }
16
+ &.invisible {
17
+ color: #aaa;
18
+ border: 1px dashed #aaa;
19
+ .dashicons.visibility {
20
+ color: #aaa;
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
includes/controls/switch/class-kirki-controls-switch-control.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * switch Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Switch_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Switch_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'switch';
25
+
26
+ public function enqueue() {
27
+ wp_enqueue_script( 'formstone', trailingslashit( kirki_url() ).'includes/controls/switch/formstone-core.js', array( 'jquery' ) );
28
+ wp_enqueue_script( 'formstone-touch', trailingslashit( kirki_url() ).'includes/controls/switch/formstone-touch.js', array( 'jquery', 'formstone' ) );
29
+ wp_enqueue_script( 'formstone-checkbox', trailingslashit( kirki_url() ).'includes/controls/switch/formstone-checkbox.js', array( 'jquery', 'formstone', 'formstone-touch' ) );
30
+ wp_enqueue_style( 'kirki-switch', trailingslashit( kirki_url() ).'includes/controls/switch/style.css' );
31
+ }
32
+
33
+ /**
34
+ * Render the control's content.
35
+ */
36
+ protected function render_content() { ?>
37
+ <?php $i18n = Kirki_Toolkit::i18n(); ?>
38
+ <label for="switch_<?php echo $this->id; ?>">
39
+ <span class="customize-control-title">
40
+ <?php echo esc_attr( $this->label ); ?>
41
+ <?php if ( ! empty( $this->description ) ) : ?>
42
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
43
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
44
+ <?php endif; ?>
45
+ </span>
46
+ </label>
47
+ <input name="switch_<?php echo $this->id; ?>" id="switch_<?php echo $this->id; ?>" type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
48
+ <script>
49
+ jQuery(document).ready(function($){
50
+ $('[id="switch_<?php echo $this->id; ?>"]').checkbox({
51
+ toggle:true,
52
+ labels:{
53
+ on:"<?php echo ( ! empty( $this->choices ) && isset( $this->choices['on'] ) ) ? $this->choices['on'] : $i18n['ON']; ?>",
54
+ off:"<?php echo ( ! empty( $this->choices ) && isset( $this->choices['off'] ) ) ? $this->choices['off'] : $i18n['OFF']; ?>"
55
+ }
56
+ });
57
+ });
58
+ </script>
59
+ <?php
60
+ }
61
+ }
includes/controls/switch/formstone-checkbox.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [checkbox.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ !function(a,b){"use strict";function c(b){var c=this.closest("label"),d=c.length?c.eq(0):a("label[for="+this.attr("id")+"]"),e=[p.base,b.customClass].join(" "),f="";b.radio="radio"===this.attr("type"),b.group=this.attr("name"),f+='<div class="'+p.marker+'">',f+='<div class="'+p.flag+'"></div>',b.toggle&&(e+=" "+p.toggle,f+='<span class="'+[p.state,p.state_on].join(" ")+'">'+b.labels.on+"</span>",f+='<span class="'+[p.state,p.state_off].join(" ")+'">'+b.labels.off+"</span>"),b.radio&&(e+=" "+p.radio),f+="</div>",d.length?d.addClass(p.label).wrap('<div class="'+e+'"></div>').before(f):this.before('<div class=" '+e+'">'+f+"</div>"),b.$checkbox=d.length?d.parents(o.base):this.prev(o.base),b.$marker=b.$checkbox.find(o.marker),b.$states=b.$checkbox.find(o.state),b.$label=d,this.is(":checked")&&b.$checkbox.addClass(p.checked),this.is(":disabled")&&b.$checkbox.addClass(p.disabled),this.wrap('<div class="'+p.element_wrapper+'"></div>'),this.on(q.focus,b,l).on(q.blur,b,m).on(q.change,b,i).on(q.click,b,h).on(q.deselect,b,k),b.$checkbox.touch({tap:!0}).on(q.tap,b,h)}function d(a){a.$checkbox.off(q.namespace).touch("destroy"),a.$marker.remove(),a.$states.remove(),a.$label.unwrap().removeClass(p.label),this.unwrap().off(q.namespace)}function e(a){this.prop("disabled",!1),a.$checkbox.removeClass(p.disabled)}function f(a){this.prop("disabled",!0),a.$checkbox.addClass(p.disabled)}function g(a){var b=a.$el.is(":disabled"),c=a.$el.is(":checked");b||(c?j({data:a}):k({data:a}))}function h(b){b.stopPropagation();var c=b.data;a(b.target).is(c.$el)||(b.preventDefault(),c.$el.trigger("click"))}function i(a){var b=a.data,c=b.$el.is(":disabled"),d=b.$el.is(":checked");c||(b.radio?j(a):d?j(a):k(a))}function j(b){b.data.radio&&a('input[name="'+b.data.group+'"]').not(b.data.$el).trigger("deselect"),b.data.$checkbox.addClass(p.checked)}function k(a){a.data.$checkbox.removeClass(p.checked)}function l(a){a.data.$checkbox.addClass(p.focus)}function m(a){a.data.$checkbox.removeClass(p.focus)}{var n=b.Plugin("checkbox",{widget:!0,defaults:{customClass:"",toggle:!1,labels:{on:"ON",off:"OFF"}},classes:["element_wrapper","label","marker","flag","radio","focus","checked","disabled","toggle","state","state_on","state_off"],methods:{_construct:c,_destruct:d,enable:e,disable:f,update:g},events:{deselect:"deselect",tap:"tap"}}),o=n.classes,p=o.raw,q=n.events;n.functions}}(jQuery,Formstone);
includes/controls/switch/formstone-core.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [core.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ var Formstone=this.Formstone=function(a,b,c){"use strict";function d(a){l.Plugins[a].initialized||(l.Plugins[a].methods._setup.call(c),l.Plugins[a].initialized=!0)}function e(a,b,c,d){var e,f={raw:{}};d=d||{};for(e in d)d.hasOwnProperty(e)&&("classes"===a?(f.raw[d[e]]=b+"-"+d[e],f[d[e]]="."+b+"-"+d[e]):(f.raw[e]=d[e],f[e]=d[e]+"."+b));for(e in c)c.hasOwnProperty(e)&&("classes"===a?(f.raw[e]=c[e].replace(/{ns}/g,b),f[e]=c[e].replace(/{ns}/g,"."+b)):(f.raw[e]=c[e].replace(/.{ns}/g,""),f[e]=c[e].replace(/{ns}/g,b)));return f}function f(){var a,b={transition:"transitionend",MozTransition:"transitionend",OTransition:"otransitionend",WebkitTransition:"webkitTransitionEnd"},d=["transition","-webkit-transition"],e={transform:"transform",MozTransform:"-moz-transform",OTransform:"-o-transform",msTransform:"-ms-transform",webkitTransform:"-webkit-transform"},f="transitionend",g="",h="",i=c.createElement("div");for(a in b)if(b.hasOwnProperty(a)&&a in i.style){f=b[a],l.support.transition=!0;break}o.transitionEnd=f+".{ns}";for(a in d)if(d.hasOwnProperty(a)&&d[a]in i.style){g=d[a];break}l.transition=g;for(a in e)if(e.hasOwnProperty(a)&&e[a]in i.style){l.support.transform=!0,h=e[a];break}l.transform=h}function g(){l.windowWidth=l.$window.width(),l.windowHeight=l.$window.height(),p=k.startTimer(p,q,h)}function h(){for(var a in l.ResizeHandlers)l.ResizeHandlers.hasOwnProperty(a)&&l.ResizeHandlers[a].callback.call(b,l.windowWidth,l.windowHeight)}function i(a,b){return parseInt(a.priority)-parseInt(b.priority)}var j=function(){this.Version="0.6.14",this.Plugins={},this.ResizeHandlers=[],this.window=b,this.$window=a(b),this.document=c,this.$document=a(c),this.$body=null,this.windowWidth=0,this.windowHeight=0,this.userAgent=b.navigator.userAgent||b.navigator.vendor||b.opera,this.isFirefox=/Firefox/i.test(this.userAgent),this.isChrome=/Chrome/i.test(this.userAgent),this.isSafari=/Safari/i.test(this.userAgent)&&!this.isChrome,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(this.userAgent),this.isFirefoxMobile=this.isFirefox&&this.isMobile,this.transform=null,this.transition=null,this.support={file:!!(b.File&&b.FileList&&b.FileReader),history:!!(b.history&&b.history.pushState&&b.history.replaceState),matchMedia:!(!b.matchMedia&&!b.msMatchMedia),raf:!(!b.requestAnimationFrame||!b.cancelAnimationFrame),touch:!!("ontouchstart"in b||b.DocumentTouch&&c instanceof b.DocumentTouch),transition:!1,transform:!1}},k={killEvent:function(a,b){try{a.preventDefault(),a.stopPropagation(),b&&a.stopImmediatePropagation()}catch(c){}},startTimer:function(a,b,c,d){return k.clearTimer(a),d?setInterval(c,b):setTimeout(c,b)},clearTimer:function(a,b){a&&(b?clearInterval(a):clearTimeout(a),a=null)},sortAsc:function(a,b){return parseInt(b)-parseInt(a)},sortDesc:function(a,b){return parseInt(b)-parseInt(a)}},l=new j,m=a.Deferred(),n={base:"{ns}",element:"{ns}-element"},o={namespace:".{ns}",blur:"blur.{ns}",change:"change.{ns}",click:"click.{ns}",dblClick:"dblclick.{ns}",drag:"drag.{ns}",dragEnd:"dragend.{ns}",dragEnter:"dragenter.{ns}",dragLeave:"dragleave.{ns}",dragOver:"dragover.{ns}",dragStart:"dragstart.{ns}",drop:"drop.{ns}",error:"error.{ns}",focus:"focus.{ns}",focusIn:"focusin.{ns}",focusOut:"focusout.{ns}",input:"input.{ns}",keyDown:"keydown.{ns}",keyPress:"keypress.{ns}",keyUp:"keyup.{ns}",load:"load.{ns}",mouseDown:"mousedown.{ns}",mouseEnter:"mouseenter.{ns}",mouseLeave:"mouseleave.{ns}",mouseMove:"mousemove.{ns}",mouseOut:"mouseout.{ns}",mouseOver:"mouseover.{ns}",mouseUp:"mouseup.{ns}",resize:"resize.{ns}",scroll:"scroll.{ns}",select:"select.{ns}",touchCancel:"touchcancel.{ns}",touchEnd:"touchend.{ns}",touchLeave:"touchleave.{ns}",touchMove:"touchmove.{ns}",touchStart:"touchstart.{ns}"};j.prototype.Plugin=function(c,f){return l.Plugins[c]=function(c,d){function f(b){var e="object"===a.type(b);b=a.extend(!0,{},d.defaults||{},e?b:{});for(var f=this,g=0,i=f.length;i>g;g++){var j=f.eq(g);if(!h(j)){var k="__"+d.guid++,l=d.classes.raw.base+k,m=j.data(c+"-options"),n=a.extend(!0,{$el:j,guid:k,rawGuid:l,dotGuid:"."+l},b,"object"===a.type(m)?m:{});j.addClass(d.classes.raw.element).data(s,n),d.methods._construct.apply(j,[n].concat(Array.prototype.slice.call(arguments,e?1:0)))}}return f}function g(){d.functions.iterate.apply(this,[d.methods._destruct].concat(Array.prototype.slice.call(arguments,1))),this.removeClass(d.classes.raw.element).removeData(s)}function h(a){return a.data(s)}function j(b){if(this instanceof a){var c=d.methods[b];return"object"!==a.type(b)&&b?c&&0!==b.indexOf("_")?d.functions.iterate.apply(this,[c].concat(Array.prototype.slice.call(arguments,1))):this:f.apply(this,arguments)}}function m(c){var e=d.utilities[c]||d.utilities._initialize||!1;return e?e.apply(b,Array.prototype.slice.call(arguments,"object"===a.type(c)?0:1)):void 0}function p(b){d.defaults=a.extend(!0,d.defaults,b||{})}function q(b){for(var c=this,d=0,e=c.length;e>d;d++){var f=c.eq(d),g=h(f)||{};"undefined"!==a.type(g.$el)&&b.apply(f,[g].concat(Array.prototype.slice.call(arguments,1)))}return c}var r="fs-"+c,s="fs"+c.replace(/(^|\s)([a-z])/g,function(a,b,c){return b+c.toUpperCase()});return d.initialized=!1,d.priority=d.priority||10,d.classes=e("classes",r,n,d.classes),d.events=e("events",c,o,d.events),d.functions=a.extend({getData:h,iterate:q},k,d.functions),d.methods=a.extend(!0,{_setup:a.noop,_construct:a.noop,_destruct:a.noop,_resize:!1,destroy:g},d.methods),d.utilities=a.extend(!0,{_initialize:!1,_delegate:!1,defaults:p},d.utilities),d.widget&&(a.fn[c]=a.fn[s]=j),a[c]=a[s]=d.utilities._delegate||m,d.namespace=c,d.namespaceClean=s,d.guid=0,d.methods._resize&&(l.ResizeHandlers.push({namespace:c,priority:d.priority,callback:d.methods._resize}),l.ResizeHandlers.sort(i)),d}(c,f),m.then(function(){d(c)}),l.Plugins[c]};var p=null,q=20;return l.$window.on("resize.fs",g),g(),a(function(){l.$body=a("body"),m.resolve()}),o.clickTouchStart=o.click+" "+o.touchStart,f(),l}(jQuery,this,document);
includes/controls/switch/formstone-touch.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [touch.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ !function(a,b){"use strict";function c(a){a.touches=[],a.touching=!1,this.on(r.dragStart,s.killEvent),a.tap?(a.pan=!1,a.scale=!1,a.swipe=!1,b.support.touch?this.on([r.touchStart,r.pointerDown].join(" "),a,f):this.on(r.click,a,k)):(a.pan||a.swipe||a.scale)&&(a.tap=!1,a.swipe&&(a.pan=!0),a.scale&&(a.axis=!1),a.axis?(a.axisX="x"===a.axis,a.axisY="y"===a.axis):o(this,"none"),this.on([r.touchStart,r.pointerDown].join(" "),a,e),a.pan&&!b.support.touch&&this.on(r.mouseDown,a,f))}function d(){this.off(r.namespace),o(this,"")}function e(a){a.preventManipulation&&a.preventManipulation();var b=a.data,c=a.originalEvent;if(c.type.match(/(up|end)$/i))return void j(a);if(c.pointerId){var d=!1;for(var e in b.touches)b.touches[e].id===c.pointerId&&(d=!0,b.touches[e].pageX=c.clientX,b.touches[e].pageY=c.clientY);d||b.touches.push({id:c.pointerId,pageX:c.clientX,pageY:c.clientY})}else b.touches=c.touches;c.type.match(/(down|start)$/i)?f(a):c.type.match(/move$/i)&&g(a)}function f(b){var c=b.data,d="undefined"!==a.type(c.touches)?c.touches[0]:null;if(c.touching||(c.startE=b.originalEvent,c.startX=d?d.pageX:b.pageX,c.startY=d?d.pageY:b.pageY,c.startT=(new Date).getTime(),c.scaleD=1,c.passed=!1),c.tap)c.clicked=!1,c.$el.on([r.touchMove,r.pointerMove].join(" "),c,e).on([r.touchEnd,r.touchCancel,r.pointerUp,r.pointerCancel].join(" "),c,e);else if(c.pan||c.scale){c.$links&&c.$links.off(r.click);var f=l(c.scale?r.scaleStart:r.panStart,b,c.startX,c.startY,c.scaleD,0,0,"","");if(c.scale&&c.touches&&c.touches.length>=2){var h=c.touches;c.pinch={startX:m(h[0].pageX,h[1].pageX),startY:m(h[0].pageY,h[1].pageY),startD:n(h[1].pageX-h[0].pageX,h[1].pageY-h[0].pageY)},f.pageX=c.startX=c.pinch.startX,f.pageY=c.startY=c.pinch.startY}c.touching||(c.touching=!0,c.pan&&t.on(r.mouseMove,c,g).on(r.mouseUp,c,j),t.on([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel].join(" "),c,e),c.$el.trigger(f))}}function g(b){var c=b.data,d="undefined"!==a.type(c.touches)?c.touches[0]:null,e=d?d.pageX:b.pageX,f=d?d.pageY:b.pageY,g=e-c.startX,h=f-c.startY,i=g>0?"right":"left",k=h>0?"down":"up",o=Math.abs(g)>u,p=Math.abs(h)>u;if(c.tap)(o||p)&&c.$el.off([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel].join(" "));else if(c.pan||c.scale)if(!c.passed&&c.axis&&(c.axisX&&p||c.axisY&&o))j(b);else{!c.passed&&(!c.axis||c.axis&&c.axisX&&o||c.axisY&&p)&&(c.passed=!0),c.passed&&(s.killEvent(b),s.killEvent(c.startE));var q=!0,t=l(c.scale?r.scale:r.pan,b,e,f,c.scaleD,g,h,i,k);if(c.scale)if(c.touches&&c.touches.length>=2){var v=c.touches;c.pinch.endX=m(v[0].pageX,v[1].pageX),c.pinch.endY=m(v[0].pageY,v[1].pageY),c.pinch.endD=n(v[1].pageX-v[0].pageX,v[1].pageY-v[0].pageY),c.scaleD=c.pinch.endD/c.pinch.startD,t.pageX=c.pinch.endX,t.pageY=c.pinch.endY,t.scale=c.scaleD,t.deltaX=c.pinch.endX-c.pinch.startX,t.deltaY=c.pinch.endY-c.pinch.startY}else c.pan||(q=!1);q&&c.$el.trigger(t)}}function h(b,c){b.on(r.click,c,i);var d=a._data(b[0],"events").click;d.unshift(d.pop())}function i(a){s.killEvent(a,!0),a.data.$links.off(r.click)}function j(b){var c=b.data;if(c.tap)c.$el.off([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel,r.mouseMove,r.mouseUp].join(" ")),c.startE.preventDefault(),k(b);else if(c.pan||c.scale){var d="undefined"!==a.type(c.touches)?c.touches[0]:null,e=d?d.pageX:b.pageX,f=d?d.pageY:b.pageY,g=e-c.startX,i=f-c.startY,j=(new Date).getTime(),m=c.scale?r.scaleEnd:r.panEnd,n=g>0?"right":"left",o=i>0?"down":"up",p=Math.abs(g)>1,q=Math.abs(i)>1;if(c.swipe&&Math.abs(g)>u&&j-c.startT<v&&(m=r.swipe),c.axis&&(c.axisX&&q||c.axisY&&p)||p||q){c.$links=c.$el.find("a");for(var s=0,w=c.$links.length;w>s;s++)h(c.$links.eq(s),c)}var x=l(m,b,e,f,c.scaleD,g,i,n,o);t.off([r.touchMove,r.touchEnd,r.touchCancel,r.mouseMove,r.mouseUp,r.pointerMove,r.pointerUp,r.pointerCancel].join(" ")),c.$el.trigger(x),c.touches=[],c.scale}c.touching=!1}function k(a){s.killEvent(a);var b=a.data;if(!b.clicked){"click"!==a.type&&(b.clicked=!0);var c=b.startE?b.startX:a.pageX,d=b.startE?b.startY:a.pageY,e=l(r.tap,a.originalEvent,c,d,1,0,0);b.$el.trigger(e)}}function l(b,c,d,e,f,g,h,i,j){return a.Event(b,{originalEvent:c,bubbles:!0,pageX:d,pageY:e,scale:f,deltaX:g,deltaY:h,directionX:i,directionY:j})}function m(a,b){return(a+b)/2}function n(a,b){return Math.sqrt(a*a+b*b)}function o(a,b){a.css({"-ms-touch-action":b,"touch-action":b})}var p=!b.window.PointerEvent,q=b.Plugin("touch",{widget:!0,defaults:{axis:!1,pan:!1,scale:!1,swipe:!1,tap:!1},methods:{_construct:c,_destruct:d},events:{pointerDown:p?"MSPointerDown":"pointerdown",pointerUp:p?"MSPointerUp":"pointerup",pointerMove:p?"MSPointerMove":"pointermove",pointerCancel:p?"MSPointerCancel":"pointercancel"}}),r=q.events,s=q.functions,t=b.$window,u=10,v=50;r.tap="tap",r.pan="pan",r.panStart="panstart",r.panEnd="panend",r.scale="scale",r.scaleStart="scalestart",r.scaleEnd="scaleend",r.swipe="swipe"}(jQuery,Formstone);
includes/controls/switch/style.css ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-switch .fs-checkbox.fs-checkbox-enabled {
2
+ cursor: pointer;
3
+ margin: 0 0 10px 0;
4
+ overflow: hidden; }
5
+ .customize-control-switch .fs-checkbox.fs-checkbox-enabled:focus {
6
+ box-shadow: none;
7
+ outline: none; }
8
+ .customize-control-switch .fs-checkbox-element_wrapper {
9
+ position: relative;
10
+ border: 0;
11
+ height: 0;
12
+ margin: 0;
13
+ opacity: 0;
14
+ overflow: hidden;
15
+ padding: 0;
16
+ width: 0; }
17
+ .customize-control-switch .fs-checkbox-element {
18
+ position: absolute;
19
+ top: 0;
20
+ left: 0;
21
+ z-index: -1;
22
+ pointer-events: none;
23
+ -webkit-transition: none;
24
+ transition: none; }
25
+ .customize-control-switch .fs-checkbox-label {
26
+ color: #666666;
27
+ cursor: pointer;
28
+ display: block;
29
+ font-size: 14px;
30
+ line-height: 20px;
31
+ overflow: hidden;
32
+ -webkit-user-select: none;
33
+ -moz-user-select: none;
34
+ -ms-user-select: none;
35
+ user-select: none; }
36
+ .customize-control-switch .fs-checkbox-marker {
37
+ width: 20px;
38
+ height: 20px;
39
+ background: #ffffff;
40
+ border: 1px solid #cccccc;
41
+ border-radius: 3px;
42
+ cursor: pointer;
43
+ display: block;
44
+ float: left;
45
+ margin: 0 10px 0 0;
46
+ float: right; }
47
+ .customize-control-switch .fs-checkbox-flag {
48
+ width: 100%;
49
+ height: 100%;
50
+ margin: 0; }
51
+ .customize-control-switch .fs-checkbox-flag:before {
52
+ width: 5px;
53
+ height: 10px;
54
+ border: 2px solid #999999;
55
+ border-top: 0;
56
+ border-left: 0;
57
+ content: '';
58
+ display: block;
59
+ margin: 3px 0 0 6px;
60
+ -webkit-transition: -webkit-transform 0.15s ease;
61
+ transition: transform 0.15s ease;
62
+ -webkit-transform: rotate(45deg) scale(0);
63
+ -ms-transform: rotate(45deg) scale(0);
64
+ transform: rotate(45deg) scale(0); }
65
+ .customize-control-switch .fs-checkbox-checked .fs-checkbox-flag:before {
66
+ -webkit-transform: rotate(45deg) scale(1);
67
+ -ms-transform: rotate(45deg) scale(1);
68
+ transform: rotate(45deg) scale(1); }
69
+ .customize-control-switch .fs-checkbox,
70
+ .customize-control-switch .fs-checkbox:after,
71
+ .customize-control-switch .fs-checkbox:before,
72
+ .customize-control-switch .fs-checkbox *,
73
+ .customize-control-switch .fs-checkbox *:after,
74
+ .customize-control-switch .fs-checkbox *:before {
75
+ box-sizing: border-box;
76
+ -webkit-transition: none;
77
+ transition: none;
78
+ -webkit-user-select: none !important;
79
+ -moz-user-select: none !important;
80
+ -ms-user-select: none !important;
81
+ user-select: none !important; }
82
+ .customize-control-switch .no-csstransforms .fs-checkbox-flag:before {
83
+ width: 100%;
84
+ height: 100%;
85
+ content: "\2713";
86
+ display: none;
87
+ line-height: 1;
88
+ text-align: center; }
89
+ .customize-control-switch .no-csstransforms .fs-checkbox-checked .fs-checkbox-flag:before {
90
+ display: block; }
91
+ .customize-control-switch .fs-checkbox-radio .fs-checkbox-marker {
92
+ border-radius: 100%; }
93
+ .customize-control-switch .fs-checkbox-radio .fs-checkbox-flag {
94
+ background: #999999;
95
+ border: 3px solid #ffffff;
96
+ border-radius: 100%;
97
+ -webkit-transform: scale(0);
98
+ -ms-transform: scale(0);
99
+ transform: scale(0);
100
+ -webkit-transition: -webkit-transform 0.15s ease;
101
+ transition: transform 0.15s ease; }
102
+ .customize-control-switch .fs-checkbox-radio .fs-checkbox-flag:before {
103
+ display: none; }
104
+ .customize-control-switch .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag {
105
+ -webkit-transform: scale(1);
106
+ -ms-transform: scale(1);
107
+ transform: scale(1); }
108
+ .customize-control-switch .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag:before {
109
+ display: none; }
110
+ .customize-control-switch .no-csstransforms .fs-checkbox-radio .fs-checkbox-flag:before {
111
+ display: none; }
112
+ .customize-control-switch .no-csstransforms .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag:before {
113
+ display: block; }
114
+ .customize-control-switch .fs-checkbox-focus .fs-checkbox-label {
115
+ color: #333333; }
116
+ .customize-control-switch .fs-checkbox-focus .fs-checkbox-marker {
117
+ border-color: #999999;
118
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); }
119
+ .customize-control-switch .fs-checkbox-disabled {
120
+ cursor: default;
121
+ opacity: 0.5; }
122
+ .customize-control-switch .fs-checkbox-disabled .fs-checkbox-label {
123
+ color: #666666;
124
+ cursor: default; }
125
+ .customize-control-switch .fs-checkbox-disabled .fs-checkbox-marker {
126
+ border-color: #cccccc;
127
+ cursor: default; }
128
+ .customize-control-switch .fs-checkbox-toggle {
129
+ position: relative; }
130
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-label {
131
+ line-height: 40px; }
132
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-marker {
133
+ width: 100px;
134
+ height: 40px;
135
+ position: relative;
136
+ border-radius: 3px; }
137
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-marker:after {
138
+ clear: both;
139
+ content: '';
140
+ display: table; }
141
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-flag {
142
+ width: 50%;
143
+ height: 100%;
144
+ position: absolute;
145
+ top: 0;
146
+ left: 0;
147
+ background: #999999;
148
+ border: 2px solid #ffffff;
149
+ border-radius: 3px;
150
+ display: block;
151
+ margin: 0;
152
+ -webkit-transition: left 0.15s ease;
153
+ transition: left 0.15s ease; }
154
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-flag:before {
155
+ display: none; }
156
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-flag:after {
157
+ width: 2px;
158
+ height: 10px;
159
+ position: absolute;
160
+ top: 0;
161
+ right: 0;
162
+ bottom: 0;
163
+ left: 0;
164
+ background: #ffffff;
165
+ box-shadow: 3px 0 0 #ffffff, -3px 0 0 #ffffff;
166
+ content: '';
167
+ margin: auto;
168
+ opacity: 0.75; }
169
+ .customize-control-switch .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag {
170
+ left: 50%; }
171
+ .customize-control-switch .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag:before {
172
+ display: none; }
173
+ .customize-control-switch .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag:after {
174
+ display: none; }
175
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-state {
176
+ width: 50%;
177
+ color: #666666;
178
+ display: block;
179
+ font-size: 12px;
180
+ line-height: 40px;
181
+ margin: 0;
182
+ text-align: center;
183
+ text-transform: uppercase; }
184
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-state_on {
185
+ float: left; }
186
+ .customize-control-switch .fs-checkbox-toggle .fs-checkbox-state_off {
187
+ float: right; }
188
+ .customize-control-switch .no-touch .fs-checkbox-toggle:hover .fs-checkbox-flag:after {
189
+ opacity: 1; }
includes/controls/switch/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAGI;iCAAQ;EACJ,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,YAAY;EACrB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,GAAG;EACZ,MAAM,EAAE,cAAc;EACtB,MAAM,EAAE,4BAAyB;EACjC,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,OAAO;EACf,KAAK,EAAE,KAAK;EACZ,UAAU,EAAE,qBAAqB;EACjC;2CAAQ;IACJ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,GAAG;IACR,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,4BAAyB;IACjC,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,qBAAqB;EAErC;;;wCACK;IACD,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;EAEb;uCAAI;IACA,KAAK,EAAE,IAAI;EAGX;8CAAQ;IACJ,IAAI,EAAE,GAAG;EAIb;+CAAQ;IACJ,IAAI,EAAE,EAAE;EAGhB;yCAAQ;IACJ,OAAO,EAAE,MAAM;IACf,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,GAAG;IACf;mDAAQ;MACJ,aAAa,EAAE,IAAI;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;IAGZ;uDAAQ;MACJ,IAAI,EAAE,EAAE;IAGhB;8CAAK;MACD,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,IAAI;MAChB;wDAAQ;QACJ,IAAI,EAAE,GAAG;;AAM7B,gBAAiB;EACb,KAAK,EAAE,IAAI;;AAEf,sBAAuB;EACnB,KAAK,EAAE,GAAG",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/switch/style.scss ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-switch {
2
+ .fs-checkbox {
3
+ &.fs-checkbox-enabled {
4
+ cursor: pointer;
5
+ margin: 0 0 10px 0;
6
+ overflow: hidden;
7
+ &:focus {
8
+ box-shadow: none;
9
+ outline: none;
10
+ }
11
+ }
12
+ &-element_wrapper {
13
+ position: relative;
14
+ border: 0;
15
+ height: 0;
16
+ margin: 0;
17
+ opacity: 0;
18
+ overflow: hidden;
19
+ padding: 0;
20
+ width: 0;
21
+ }
22
+ &-element {
23
+ position: absolute;
24
+ top: 0;
25
+ left: 0;
26
+ z-index: -1;
27
+ pointer-events: none;
28
+ -webkit-transition: none;
29
+ transition: none;
30
+ }
31
+ &-label {
32
+ color: #666666;
33
+ cursor: pointer;
34
+ display: block;
35
+ font-size: 14px;
36
+ line-height: 20px;
37
+ overflow: hidden;
38
+ -webkit-user-select: none;
39
+ -moz-user-select: none;
40
+ -ms-user-select: none;
41
+ user-select: none;
42
+ }
43
+ &-marker {
44
+ width: 20px;
45
+ height: 20px;
46
+ background: #ffffff;
47
+ border: 1px solid #cccccc;
48
+ border-radius: 3px;
49
+ cursor: pointer;
50
+ display: block;
51
+ float: left;
52
+ margin: 0 10px 0 0;
53
+ float: right;
54
+ }
55
+ &-flag {
56
+ width: 100%;
57
+ height: 100%;
58
+ margin: 0;
59
+ &:before {
60
+ width: 5px;
61
+ height: 10px;
62
+ border: 2px solid #999999;
63
+ border-top: 0;
64
+ border-left: 0;
65
+ content: '';
66
+ display: block;
67
+ margin: 3px 0 0 6px;
68
+ -webkit-transition: -webkit-transform 0.15s ease;
69
+ transition: transform 0.15s ease;
70
+ -webkit-transform: rotate(45deg) scale(0);
71
+ -ms-transform: rotate(45deg) scale(0);
72
+ transform: rotate(45deg) scale(0);
73
+ }
74
+ }
75
+ &-checked {
76
+ .fs-checkbox-flag:before {
77
+ -webkit-transform: rotate(45deg) scale(1);
78
+ -ms-transform: rotate(45deg) scale(1);
79
+ transform: rotate(45deg) scale(1);
80
+ }
81
+ }
82
+ }
83
+
84
+ .fs-checkbox,
85
+ .fs-checkbox:after,
86
+ .fs-checkbox:before,
87
+ .fs-checkbox *,
88
+ .fs-checkbox *:after,
89
+ .fs-checkbox *:before {
90
+ box-sizing: border-box;
91
+ -webkit-transition: none;
92
+ transition: none;
93
+ -webkit-user-select: none !important;
94
+ -moz-user-select: none !important;
95
+ -ms-user-select: none !important;
96
+ user-select: none !important;
97
+ }
98
+
99
+ .no-csstransforms {
100
+ .fs-checkbox-flag {
101
+ &:before {
102
+ width: 100%;
103
+ height: 100%;
104
+ content: "\2713";
105
+ display: none;
106
+ line-height: 1;
107
+ text-align: center;
108
+ }
109
+ }
110
+ .fs-checkbox-checked {
111
+ .fs-checkbox-flag{
112
+ &:before {
113
+ display: block;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ .fs-checkbox-radio {
120
+ .fs-checkbox-marker {
121
+ border-radius: 100%;
122
+ }
123
+ .fs-checkbox-flag {
124
+ background: #999999;
125
+ border: 3px solid #ffffff;
126
+ border-radius: 100%;
127
+ -webkit-transform: scale(0);
128
+ -ms-transform: scale(0);
129
+ transform: scale(0);
130
+ -webkit-transition: -webkit-transform 0.15s ease;
131
+ transition: transform 0.15s ease;
132
+ &:before {
133
+ display: none;
134
+ }
135
+ }
136
+ &.fs-checkbox-checked {
137
+ .fs-checkbox-flag {
138
+ -webkit-transform: scale(1);
139
+ -ms-transform: scale(1);
140
+ transform: scale(1);
141
+ &:before {
142
+ display: none;
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ .no-csstransforms {
149
+ .fs-checkbox-radio {
150
+ .fs-checkbox-flag {
151
+ &:before {
152
+ display: none;
153
+ }
154
+ }
155
+ &.fs-checkbox-checked .fs-checkbox-flag:before {
156
+ display: block;
157
+ }
158
+ }
159
+ }
160
+
161
+ .fs-checkbox-focus {
162
+ .fs-checkbox-label {
163
+ color: #333333;
164
+ }
165
+ .fs-checkbox-marker {
166
+ border-color: #999999;
167
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
168
+ }
169
+ }
170
+
171
+ .fs-checkbox-disabled {
172
+ cursor: default;
173
+ opacity: 0.5;
174
+ }
175
+
176
+ .fs-checkbox-disabled {
177
+ .fs-checkbox-label {
178
+ color: #666666;
179
+ cursor: default;
180
+ }
181
+ .fs-checkbox-marker {
182
+ border-color: #cccccc;
183
+ cursor: default;
184
+ }
185
+ }
186
+
187
+ .fs-checkbox-toggle {
188
+ position: relative;
189
+ .fs-checkbox-label {
190
+ line-height: 40px;
191
+ }
192
+ .fs-checkbox-marker {
193
+ width: 100px;
194
+ height: 40px;
195
+ position: relative;
196
+ border-radius: 3px;
197
+ }
198
+ .fs-checkbox-marker:after {
199
+ clear: both;
200
+ content: '';
201
+ display: table;
202
+ }
203
+ .fs-checkbox-flag {
204
+ width: 50%;
205
+ height: 100%;
206
+ position: absolute;
207
+ top: 0;
208
+ left: 0;
209
+ background: #999999;
210
+ border: 2px solid #ffffff;
211
+ border-radius: 3px;
212
+ display: block;
213
+ margin: 0;
214
+ -webkit-transition: left 0.15s ease;
215
+ transition: left 0.15s ease;
216
+ &:before {
217
+ display: none;
218
+ }
219
+ &:after {
220
+ width: 2px;
221
+ height: 10px;
222
+ position: absolute;
223
+ top: 0;
224
+ right: 0;
225
+ bottom: 0;
226
+ left: 0;
227
+ background: #ffffff;
228
+ box-shadow: 3px 0 0 #ffffff, -3px 0 0 #ffffff;
229
+ content: '';
230
+ margin: auto;
231
+ opacity: 0.75;
232
+ }
233
+ }
234
+ &.fs-checkbox-checked {
235
+ .fs-checkbox-flag {
236
+ left: 50%;
237
+ &:before {
238
+ display: none;
239
+ }
240
+ &:after {
241
+ display: none;
242
+ }
243
+ }
244
+ }
245
+ .fs-checkbox-state {
246
+ width: 50%;
247
+ color: #666666;
248
+ display: block;
249
+ font-size: 12px;
250
+ line-height: 40px;
251
+ margin: 0;
252
+ text-align: center;
253
+ text-transform: uppercase;
254
+ }
255
+ .fs-checkbox-state_on {
256
+ float: left;
257
+ }
258
+ .fs-checkbox-state_off {
259
+ float: right;
260
+ }
261
+ }
262
+ .no-touch {
263
+ .fs-checkbox-toggle:hover .fs-checkbox-flag:after {
264
+ opacity: 1;
265
+ }
266
+ }
267
+ }
includes/controls/toggle/class-kirki-controls-toggle-control.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * toggle Customizer Control.
4
+ *
5
+ * @package Kirki
6
+ * @subpackage Controls
7
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // Early exit if the class already exists
18
+ if ( class_exists( 'Kirki_Controls_Toggle_Control' ) ) {
19
+ return;
20
+ }
21
+
22
+ class Kirki_Controls_Toggle_Control extends WP_Customize_Control {
23
+
24
+ public $type = 'toggle';
25
+
26
+ public function enqueue() {
27
+ wp_enqueue_script( 'formstone', trailingslashit( kirki_url() ).'includes/controls/toggle/formstone-core.js', array( 'jquery' ) );
28
+ wp_enqueue_script( 'formstone-touch', trailingslashit( kirki_url() ).'includes/controls/toggle/formstone-touch.js', array( 'jquery', 'formstone' ) );
29
+ wp_enqueue_script( 'formstone-checkbox', trailingslashit( kirki_url() ).'includes/controls/toggle/formstone-checkbox.js', array( 'jquery', 'formstone', 'formstone-touch' ) );
30
+ wp_enqueue_style( 'kirki-toggle', trailingslashit( kirki_url() ).'includes/controls/toggle/style.css' );
31
+ }
32
+
33
+ /**
34
+ * Render the control's content.
35
+ */
36
+ protected function render_content() { ?>
37
+ <?php $i18n = Kirki_Toolkit::i18n(); ?>
38
+ <label for="toggle_<?php echo $this->id; ?>">
39
+ <span class="customize-control-title">
40
+ <?php echo esc_attr( $this->label ); ?>
41
+ <?php if ( ! empty( $this->description ) ) : ?>
42
+ <?php // The description has already been sanitized in the Fields class, no need to re-sanitize it. ?>
43
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
44
+ <?php endif; ?>
45
+ </span>
46
+ </label>
47
+ <input name="toggle_<?php echo $this->id; ?>" id="toggle_<?php echo $this->id; ?>" type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
48
+ <script>jQuery(document).ready(function($){$('[id="toggle_<?php echo $this->id; ?>"]').checkbox({toggle:true});});</script>
49
+ <?php
50
+ }
51
+ }
includes/controls/toggle/formstone-checkbox.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [checkbox.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ !function(a,b){"use strict";function c(b){var c=this.closest("label"),d=c.length?c.eq(0):a("label[for="+this.attr("id")+"]"),e=[p.base,b.customClass].join(" "),f="";b.radio="radio"===this.attr("type"),b.group=this.attr("name"),f+='<div class="'+p.marker+'">',f+='<div class="'+p.flag+'"></div>',b.toggle&&(e+=" "+p.toggle,f+='<span class="'+[p.state,p.state_on].join(" ")+'">'+b.labels.on+"</span>",f+='<span class="'+[p.state,p.state_off].join(" ")+'">'+b.labels.off+"</span>"),b.radio&&(e+=" "+p.radio),f+="</div>",d.length?d.addClass(p.label).wrap('<div class="'+e+'"></div>').before(f):this.before('<div class=" '+e+'">'+f+"</div>"),b.$checkbox=d.length?d.parents(o.base):this.prev(o.base),b.$marker=b.$checkbox.find(o.marker),b.$states=b.$checkbox.find(o.state),b.$label=d,this.is(":checked")&&b.$checkbox.addClass(p.checked),this.is(":disabled")&&b.$checkbox.addClass(p.disabled),this.wrap('<div class="'+p.element_wrapper+'"></div>'),this.on(q.focus,b,l).on(q.blur,b,m).on(q.change,b,i).on(q.click,b,h).on(q.deselect,b,k),b.$checkbox.touch({tap:!0}).on(q.tap,b,h)}function d(a){a.$checkbox.off(q.namespace).touch("destroy"),a.$marker.remove(),a.$states.remove(),a.$label.unwrap().removeClass(p.label),this.unwrap().off(q.namespace)}function e(a){this.prop("disabled",!1),a.$checkbox.removeClass(p.disabled)}function f(a){this.prop("disabled",!0),a.$checkbox.addClass(p.disabled)}function g(a){var b=a.$el.is(":disabled"),c=a.$el.is(":checked");b||(c?j({data:a}):k({data:a}))}function h(b){b.stopPropagation();var c=b.data;a(b.target).is(c.$el)||(b.preventDefault(),c.$el.trigger("click"))}function i(a){var b=a.data,c=b.$el.is(":disabled"),d=b.$el.is(":checked");c||(b.radio?j(a):d?j(a):k(a))}function j(b){b.data.radio&&a('input[name="'+b.data.group+'"]').not(b.data.$el).trigger("deselect"),b.data.$checkbox.addClass(p.checked)}function k(a){a.data.$checkbox.removeClass(p.checked)}function l(a){a.data.$checkbox.addClass(p.focus)}function m(a){a.data.$checkbox.removeClass(p.focus)}{var n=b.Plugin("checkbox",{widget:!0,defaults:{customClass:"",toggle:!1,labels:{on:"ON",off:"OFF"}},classes:["element_wrapper","label","marker","flag","radio","focus","checked","disabled","toggle","state","state_on","state_off"],methods:{_construct:c,_destruct:d,enable:e,disable:f,update:g},events:{deselect:"deselect",tap:"tap"}}),o=n.classes,p=o.raw,q=n.events;n.functions}}(jQuery,Formstone);
includes/controls/toggle/formstone-core.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [core.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ var Formstone=this.Formstone=function(a,b,c){"use strict";function d(a){l.Plugins[a].initialized||(l.Plugins[a].methods._setup.call(c),l.Plugins[a].initialized=!0)}function e(a,b,c,d){var e,f={raw:{}};d=d||{};for(e in d)d.hasOwnProperty(e)&&("classes"===a?(f.raw[d[e]]=b+"-"+d[e],f[d[e]]="."+b+"-"+d[e]):(f.raw[e]=d[e],f[e]=d[e]+"."+b));for(e in c)c.hasOwnProperty(e)&&("classes"===a?(f.raw[e]=c[e].replace(/{ns}/g,b),f[e]=c[e].replace(/{ns}/g,"."+b)):(f.raw[e]=c[e].replace(/.{ns}/g,""),f[e]=c[e].replace(/{ns}/g,b)));return f}function f(){var a,b={transition:"transitionend",MozTransition:"transitionend",OTransition:"otransitionend",WebkitTransition:"webkitTransitionEnd"},d=["transition","-webkit-transition"],e={transform:"transform",MozTransform:"-moz-transform",OTransform:"-o-transform",msTransform:"-ms-transform",webkitTransform:"-webkit-transform"},f="transitionend",g="",h="",i=c.createElement("div");for(a in b)if(b.hasOwnProperty(a)&&a in i.style){f=b[a],l.support.transition=!0;break}o.transitionEnd=f+".{ns}";for(a in d)if(d.hasOwnProperty(a)&&d[a]in i.style){g=d[a];break}l.transition=g;for(a in e)if(e.hasOwnProperty(a)&&e[a]in i.style){l.support.transform=!0,h=e[a];break}l.transform=h}function g(){l.windowWidth=l.$window.width(),l.windowHeight=l.$window.height(),p=k.startTimer(p,q,h)}function h(){for(var a in l.ResizeHandlers)l.ResizeHandlers.hasOwnProperty(a)&&l.ResizeHandlers[a].callback.call(b,l.windowWidth,l.windowHeight)}function i(a,b){return parseInt(a.priority)-parseInt(b.priority)}var j=function(){this.Version="0.6.14",this.Plugins={},this.ResizeHandlers=[],this.window=b,this.$window=a(b),this.document=c,this.$document=a(c),this.$body=null,this.windowWidth=0,this.windowHeight=0,this.userAgent=b.navigator.userAgent||b.navigator.vendor||b.opera,this.isFirefox=/Firefox/i.test(this.userAgent),this.isChrome=/Chrome/i.test(this.userAgent),this.isSafari=/Safari/i.test(this.userAgent)&&!this.isChrome,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(this.userAgent),this.isFirefoxMobile=this.isFirefox&&this.isMobile,this.transform=null,this.transition=null,this.support={file:!!(b.File&&b.FileList&&b.FileReader),history:!!(b.history&&b.history.pushState&&b.history.replaceState),matchMedia:!(!b.matchMedia&&!b.msMatchMedia),raf:!(!b.requestAnimationFrame||!b.cancelAnimationFrame),touch:!!("ontouchstart"in b||b.DocumentTouch&&c instanceof b.DocumentTouch),transition:!1,transform:!1}},k={killEvent:function(a,b){try{a.preventDefault(),a.stopPropagation(),b&&a.stopImmediatePropagation()}catch(c){}},startTimer:function(a,b,c,d){return k.clearTimer(a),d?setInterval(c,b):setTimeout(c,b)},clearTimer:function(a,b){a&&(b?clearInterval(a):clearTimeout(a),a=null)},sortAsc:function(a,b){return parseInt(b)-parseInt(a)},sortDesc:function(a,b){return parseInt(b)-parseInt(a)}},l=new j,m=a.Deferred(),n={base:"{ns}",element:"{ns}-element"},o={namespace:".{ns}",blur:"blur.{ns}",change:"change.{ns}",click:"click.{ns}",dblClick:"dblclick.{ns}",drag:"drag.{ns}",dragEnd:"dragend.{ns}",dragEnter:"dragenter.{ns}",dragLeave:"dragleave.{ns}",dragOver:"dragover.{ns}",dragStart:"dragstart.{ns}",drop:"drop.{ns}",error:"error.{ns}",focus:"focus.{ns}",focusIn:"focusin.{ns}",focusOut:"focusout.{ns}",input:"input.{ns}",keyDown:"keydown.{ns}",keyPress:"keypress.{ns}",keyUp:"keyup.{ns}",load:"load.{ns}",mouseDown:"mousedown.{ns}",mouseEnter:"mouseenter.{ns}",mouseLeave:"mouseleave.{ns}",mouseMove:"mousemove.{ns}",mouseOut:"mouseout.{ns}",mouseOver:"mouseover.{ns}",mouseUp:"mouseup.{ns}",resize:"resize.{ns}",scroll:"scroll.{ns}",select:"select.{ns}",touchCancel:"touchcancel.{ns}",touchEnd:"touchend.{ns}",touchLeave:"touchleave.{ns}",touchMove:"touchmove.{ns}",touchStart:"touchstart.{ns}"};j.prototype.Plugin=function(c,f){return l.Plugins[c]=function(c,d){function f(b){var e="object"===a.type(b);b=a.extend(!0,{},d.defaults||{},e?b:{});for(var f=this,g=0,i=f.length;i>g;g++){var j=f.eq(g);if(!h(j)){var k="__"+d.guid++,l=d.classes.raw.base+k,m=j.data(c+"-options"),n=a.extend(!0,{$el:j,guid:k,rawGuid:l,dotGuid:"."+l},b,"object"===a.type(m)?m:{});j.addClass(d.classes.raw.element).data(s,n),d.methods._construct.apply(j,[n].concat(Array.prototype.slice.call(arguments,e?1:0)))}}return f}function g(){d.functions.iterate.apply(this,[d.methods._destruct].concat(Array.prototype.slice.call(arguments,1))),this.removeClass(d.classes.raw.element).removeData(s)}function h(a){return a.data(s)}function j(b){if(this instanceof a){var c=d.methods[b];return"object"!==a.type(b)&&b?c&&0!==b.indexOf("_")?d.functions.iterate.apply(this,[c].concat(Array.prototype.slice.call(arguments,1))):this:f.apply(this,arguments)}}function m(c){var e=d.utilities[c]||d.utilities._initialize||!1;return e?e.apply(b,Array.prototype.slice.call(arguments,"object"===a.type(c)?0:1)):void 0}function p(b){d.defaults=a.extend(!0,d.defaults,b||{})}function q(b){for(var c=this,d=0,e=c.length;e>d;d++){var f=c.eq(d),g=h(f)||{};"undefined"!==a.type(g.$el)&&b.apply(f,[g].concat(Array.prototype.slice.call(arguments,1)))}return c}var r="fs-"+c,s="fs"+c.replace(/(^|\s)([a-z])/g,function(a,b,c){return b+c.toUpperCase()});return d.initialized=!1,d.priority=d.priority||10,d.classes=e("classes",r,n,d.classes),d.events=e("events",c,o,d.events),d.functions=a.extend({getData:h,iterate:q},k,d.functions),d.methods=a.extend(!0,{_setup:a.noop,_construct:a.noop,_destruct:a.noop,_resize:!1,destroy:g},d.methods),d.utilities=a.extend(!0,{_initialize:!1,_delegate:!1,defaults:p},d.utilities),d.widget&&(a.fn[c]=a.fn[s]=j),a[c]=a[s]=d.utilities._delegate||m,d.namespace=c,d.namespaceClean=s,d.guid=0,d.methods._resize&&(l.ResizeHandlers.push({namespace:c,priority:d.priority,callback:d.methods._resize}),l.ResizeHandlers.sort(i)),d}(c,f),m.then(function(){d(c)}),l.Plugins[c]};var p=null,q=20;return l.$window.on("resize.fs",g),g(),a(function(){l.$body=a("body"),m.resolve()}),o.clickTouchStart=o.click+" "+o.touchStart,f(),l}(jQuery,this,document);
includes/controls/toggle/formstone-touch.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! formstone v0.6.14 [touch.js] 2015-06-23 | MIT License | formstone.it */
2
+
3
+ !function(a,b){"use strict";function c(a){a.touches=[],a.touching=!1,this.on(r.dragStart,s.killEvent),a.tap?(a.pan=!1,a.scale=!1,a.swipe=!1,b.support.touch?this.on([r.touchStart,r.pointerDown].join(" "),a,f):this.on(r.click,a,k)):(a.pan||a.swipe||a.scale)&&(a.tap=!1,a.swipe&&(a.pan=!0),a.scale&&(a.axis=!1),a.axis?(a.axisX="x"===a.axis,a.axisY="y"===a.axis):o(this,"none"),this.on([r.touchStart,r.pointerDown].join(" "),a,e),a.pan&&!b.support.touch&&this.on(r.mouseDown,a,f))}function d(){this.off(r.namespace),o(this,"")}function e(a){a.preventManipulation&&a.preventManipulation();var b=a.data,c=a.originalEvent;if(c.type.match(/(up|end)$/i))return void j(a);if(c.pointerId){var d=!1;for(var e in b.touches)b.touches[e].id===c.pointerId&&(d=!0,b.touches[e].pageX=c.clientX,b.touches[e].pageY=c.clientY);d||b.touches.push({id:c.pointerId,pageX:c.clientX,pageY:c.clientY})}else b.touches=c.touches;c.type.match(/(down|start)$/i)?f(a):c.type.match(/move$/i)&&g(a)}function f(b){var c=b.data,d="undefined"!==a.type(c.touches)?c.touches[0]:null;if(c.touching||(c.startE=b.originalEvent,c.startX=d?d.pageX:b.pageX,c.startY=d?d.pageY:b.pageY,c.startT=(new Date).getTime(),c.scaleD=1,c.passed=!1),c.tap)c.clicked=!1,c.$el.on([r.touchMove,r.pointerMove].join(" "),c,e).on([r.touchEnd,r.touchCancel,r.pointerUp,r.pointerCancel].join(" "),c,e);else if(c.pan||c.scale){c.$links&&c.$links.off(r.click);var f=l(c.scale?r.scaleStart:r.panStart,b,c.startX,c.startY,c.scaleD,0,0,"","");if(c.scale&&c.touches&&c.touches.length>=2){var h=c.touches;c.pinch={startX:m(h[0].pageX,h[1].pageX),startY:m(h[0].pageY,h[1].pageY),startD:n(h[1].pageX-h[0].pageX,h[1].pageY-h[0].pageY)},f.pageX=c.startX=c.pinch.startX,f.pageY=c.startY=c.pinch.startY}c.touching||(c.touching=!0,c.pan&&t.on(r.mouseMove,c,g).on(r.mouseUp,c,j),t.on([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel].join(" "),c,e),c.$el.trigger(f))}}function g(b){var c=b.data,d="undefined"!==a.type(c.touches)?c.touches[0]:null,e=d?d.pageX:b.pageX,f=d?d.pageY:b.pageY,g=e-c.startX,h=f-c.startY,i=g>0?"right":"left",k=h>0?"down":"up",o=Math.abs(g)>u,p=Math.abs(h)>u;if(c.tap)(o||p)&&c.$el.off([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel].join(" "));else if(c.pan||c.scale)if(!c.passed&&c.axis&&(c.axisX&&p||c.axisY&&o))j(b);else{!c.passed&&(!c.axis||c.axis&&c.axisX&&o||c.axisY&&p)&&(c.passed=!0),c.passed&&(s.killEvent(b),s.killEvent(c.startE));var q=!0,t=l(c.scale?r.scale:r.pan,b,e,f,c.scaleD,g,h,i,k);if(c.scale)if(c.touches&&c.touches.length>=2){var v=c.touches;c.pinch.endX=m(v[0].pageX,v[1].pageX),c.pinch.endY=m(v[0].pageY,v[1].pageY),c.pinch.endD=n(v[1].pageX-v[0].pageX,v[1].pageY-v[0].pageY),c.scaleD=c.pinch.endD/c.pinch.startD,t.pageX=c.pinch.endX,t.pageY=c.pinch.endY,t.scale=c.scaleD,t.deltaX=c.pinch.endX-c.pinch.startX,t.deltaY=c.pinch.endY-c.pinch.startY}else c.pan||(q=!1);q&&c.$el.trigger(t)}}function h(b,c){b.on(r.click,c,i);var d=a._data(b[0],"events").click;d.unshift(d.pop())}function i(a){s.killEvent(a,!0),a.data.$links.off(r.click)}function j(b){var c=b.data;if(c.tap)c.$el.off([r.touchMove,r.touchEnd,r.touchCancel,r.pointerMove,r.pointerUp,r.pointerCancel,r.mouseMove,r.mouseUp].join(" ")),c.startE.preventDefault(),k(b);else if(c.pan||c.scale){var d="undefined"!==a.type(c.touches)?c.touches[0]:null,e=d?d.pageX:b.pageX,f=d?d.pageY:b.pageY,g=e-c.startX,i=f-c.startY,j=(new Date).getTime(),m=c.scale?r.scaleEnd:r.panEnd,n=g>0?"right":"left",o=i>0?"down":"up",p=Math.abs(g)>1,q=Math.abs(i)>1;if(c.swipe&&Math.abs(g)>u&&j-c.startT<v&&(m=r.swipe),c.axis&&(c.axisX&&q||c.axisY&&p)||p||q){c.$links=c.$el.find("a");for(var s=0,w=c.$links.length;w>s;s++)h(c.$links.eq(s),c)}var x=l(m,b,e,f,c.scaleD,g,i,n,o);t.off([r.touchMove,r.touchEnd,r.touchCancel,r.mouseMove,r.mouseUp,r.pointerMove,r.pointerUp,r.pointerCancel].join(" ")),c.$el.trigger(x),c.touches=[],c.scale}c.touching=!1}function k(a){s.killEvent(a);var b=a.data;if(!b.clicked){"click"!==a.type&&(b.clicked=!0);var c=b.startE?b.startX:a.pageX,d=b.startE?b.startY:a.pageY,e=l(r.tap,a.originalEvent,c,d,1,0,0);b.$el.trigger(e)}}function l(b,c,d,e,f,g,h,i,j){return a.Event(b,{originalEvent:c,bubbles:!0,pageX:d,pageY:e,scale:f,deltaX:g,deltaY:h,directionX:i,directionY:j})}function m(a,b){return(a+b)/2}function n(a,b){return Math.sqrt(a*a+b*b)}function o(a,b){a.css({"-ms-touch-action":b,"touch-action":b})}var p=!b.window.PointerEvent,q=b.Plugin("touch",{widget:!0,defaults:{axis:!1,pan:!1,scale:!1,swipe:!1,tap:!1},methods:{_construct:c,_destruct:d},events:{pointerDown:p?"MSPointerDown":"pointerdown",pointerUp:p?"MSPointerUp":"pointerup",pointerMove:p?"MSPointerMove":"pointermove",pointerCancel:p?"MSPointerCancel":"pointercancel"}}),r=q.events,s=q.functions,t=b.$window,u=10,v=50;r.tap="tap",r.pan="pan",r.panStart="panstart",r.panEnd="panend",r.scale="scale",r.scaleStart="scalestart",r.scaleEnd="scaleend",r.swipe="swipe"}(jQuery,Formstone);
includes/controls/toggle/style.css ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-toggle .fs-checkbox.fs-checkbox-enabled {
2
+ cursor: pointer;
3
+ margin: 0 0 10px 0;
4
+ overflow: hidden; }
5
+ .customize-control-toggle .fs-checkbox.fs-checkbox-enabled:focus {
6
+ box-shadow: none;
7
+ outline: none; }
8
+ .customize-control-toggle .fs-checkbox-element_wrapper {
9
+ position: relative;
10
+ border: 0;
11
+ height: 0;
12
+ margin: 0;
13
+ opacity: 0;
14
+ overflow: hidden;
15
+ padding: 0;
16
+ width: 0; }
17
+ .customize-control-toggle .fs-checkbox-element {
18
+ position: absolute;
19
+ top: 0;
20
+ left: 0;
21
+ z-index: -1;
22
+ pointer-events: none;
23
+ -webkit-transition: none;
24
+ transition: none; }
25
+ .customize-control-toggle .fs-checkbox-label {
26
+ color: #666666;
27
+ cursor: pointer;
28
+ display: block;
29
+ font-size: 14px;
30
+ line-height: 20px;
31
+ overflow: hidden;
32
+ -webkit-user-select: none;
33
+ -moz-user-select: none;
34
+ -ms-user-select: none;
35
+ user-select: none; }
36
+ .customize-control-toggle .fs-checkbox-marker {
37
+ width: 20px;
38
+ height: 20px;
39
+ background: #ffffff;
40
+ border: 1px solid #cccccc;
41
+ border-radius: 3px;
42
+ cursor: pointer;
43
+ display: block;
44
+ float: left;
45
+ margin: 0 10px 0 0;
46
+ float: right; }
47
+ .customize-control-toggle .fs-checkbox-flag {
48
+ width: 100%;
49
+ height: 100%;
50
+ margin: 0; }
51
+ .customize-control-toggle .fs-checkbox-flag:before {
52
+ width: 5px;
53
+ height: 10px;
54
+ border: 2px solid #999999;
55
+ border-top: 0;
56
+ border-left: 0;
57
+ content: '';
58
+ display: block;
59
+ margin: 3px 0 0 6px;
60
+ -webkit-transition: -webkit-transform 0.15s ease;
61
+ transition: transform 0.15s ease;
62
+ -webkit-transform: rotate(45deg) scale(0);
63
+ -ms-transform: rotate(45deg) scale(0);
64
+ transform: rotate(45deg) scale(0); }
65
+ .customize-control-toggle .fs-checkbox-checked .fs-checkbox-flag:before {
66
+ -webkit-transform: rotate(45deg) scale(1);
67
+ -ms-transform: rotate(45deg) scale(1);
68
+ transform: rotate(45deg) scale(1); }
69
+ .customize-control-toggle .fs-checkbox,
70
+ .customize-control-toggle .fs-checkbox:after,
71
+ .customize-control-toggle .fs-checkbox:before,
72
+ .customize-control-toggle .fs-checkbox *,
73
+ .customize-control-toggle .fs-checkbox *:after,
74
+ .customize-control-toggle .fs-checkbox *:before {
75
+ box-sizing: border-box;
76
+ -webkit-transition: none;
77
+ transition: none;
78
+ -webkit-user-select: none !important;
79
+ -moz-user-select: none !important;
80
+ -ms-user-select: none !important;
81
+ user-select: none !important; }
82
+ .customize-control-toggle .no-csstransforms .fs-checkbox-flag:before {
83
+ width: 100%;
84
+ height: 100%;
85
+ content: "\2713";
86
+ display: none;
87
+ line-height: 1;
88
+ text-align: center; }
89
+ .customize-control-toggle .no-csstransforms .fs-checkbox-checked .fs-checkbox-flag:before {
90
+ display: block; }
91
+ .customize-control-toggle .fs-checkbox-radio .fs-checkbox-marker {
92
+ border-radius: 100%; }
93
+ .customize-control-toggle .fs-checkbox-radio .fs-checkbox-flag {
94
+ background: #999999;
95
+ border: 3px solid #ffffff;
96
+ border-radius: 100%;
97
+ -webkit-transform: scale(0);
98
+ -ms-transform: scale(0);
99
+ transform: scale(0);
100
+ -webkit-transition: -webkit-transform 0.15s ease;
101
+ transition: transform 0.15s ease; }
102
+ .customize-control-toggle .fs-checkbox-radio .fs-checkbox-flag:before {
103
+ display: none; }
104
+ .customize-control-toggle .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag {
105
+ -webkit-transform: scale(1);
106
+ -ms-transform: scale(1);
107
+ transform: scale(1); }
108
+ .customize-control-toggle .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag:before {
109
+ display: none; }
110
+ .customize-control-toggle .no-csstransforms .fs-checkbox-radio .fs-checkbox-flag:before {
111
+ display: none; }
112
+ .customize-control-toggle .no-csstransforms .fs-checkbox-radio.fs-checkbox-checked .fs-checkbox-flag:before {
113
+ display: block; }
114
+ .customize-control-toggle .fs-checkbox-focus .fs-checkbox-label {
115
+ color: #333333; }
116
+ .customize-control-toggle .fs-checkbox-focus .fs-checkbox-marker {
117
+ border-color: #999999;
118
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); }
119
+ .customize-control-toggle .fs-checkbox-disabled {
120
+ cursor: default;
121
+ opacity: 0.5; }
122
+ .customize-control-toggle .fs-checkbox-disabled .fs-checkbox-label {
123
+ color: #666666;
124
+ cursor: default; }
125
+ .customize-control-toggle .fs-checkbox-disabled .fs-checkbox-marker {
126
+ border-color: #cccccc;
127
+ cursor: default; }
128
+ .customize-control-toggle .fs-checkbox-toggle {
129
+ position: relative; }
130
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-label {
131
+ line-height: 40px; }
132
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-marker {
133
+ width: 50px;
134
+ height: 20px;
135
+ position: relative;
136
+ border-radius: 3px; }
137
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-marker:after {
138
+ clear: both;
139
+ content: '';
140
+ display: table; }
141
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-flag {
142
+ width: 50%;
143
+ height: 100%;
144
+ position: absolute;
145
+ top: 0;
146
+ left: 0;
147
+ background: #999999;
148
+ border: 2px solid #ffffff;
149
+ border-radius: 3px;
150
+ display: block;
151
+ margin: 0;
152
+ -webkit-transition: left 0.15s ease;
153
+ transition: left 0.15s ease; }
154
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-flag:before {
155
+ display: none; }
156
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-flag:after {
157
+ width: 2px;
158
+ height: 10px;
159
+ position: absolute;
160
+ top: 0;
161
+ right: 0;
162
+ bottom: 0;
163
+ left: 0;
164
+ background: #ffffff;
165
+ box-shadow: 3px 0 0 #ffffff, -3px 0 0 #ffffff;
166
+ content: '';
167
+ margin: auto;
168
+ opacity: 0.75; }
169
+ .customize-control-toggle .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag {
170
+ left: 50%; }
171
+ .customize-control-toggle .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag:before {
172
+ display: none; }
173
+ .customize-control-toggle .fs-checkbox-toggle.fs-checkbox-checked .fs-checkbox-flag:after {
174
+ display: none; }
175
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-state {
176
+ width: 50%;
177
+ color: #666666;
178
+ display: block;
179
+ font-size: 12px;
180
+ line-height: 40px;
181
+ margin: 0;
182
+ text-align: center;
183
+ text-transform: uppercase;
184
+ text-indent: -9999px; }
185
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-state_on {
186
+ float: left; }
187
+ .customize-control-toggle .fs-checkbox-toggle .fs-checkbox-state_off {
188
+ float: right; }
189
+ .customize-control-toggle .no-touch .fs-checkbox-toggle:hover .fs-checkbox-flag:after {
190
+ opacity: 1; }
includes/controls/toggle/style.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "AAGI;iCAAQ;EACJ,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,YAAY;EACrB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,GAAG;EACZ,MAAM,EAAE,cAAc;EACtB,MAAM,EAAE,4BAAyB;EACjC,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,OAAO;EACf,KAAK,EAAE,KAAK;EACZ,UAAU,EAAE,qBAAqB;EACjC;2CAAQ;IACJ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,GAAG;IACR,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,4BAAyB;IACjC,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,qBAAqB;EAErC;;;wCACK;IACD,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;EAEb;uCAAI;IACA,KAAK,EAAE,IAAI;EAGX;8CAAQ;IACJ,IAAI,EAAE,GAAG;EAIb;+CAAQ;IACJ,IAAI,EAAE,EAAE;EAGhB;yCAAQ;IACJ,OAAO,EAAE,MAAM;IACf,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,GAAG;IACf;mDAAQ;MACJ,aAAa,EAAE,IAAI;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;IAGZ;uDAAQ;MACJ,IAAI,EAAE,EAAE;IAGhB;8CAAK;MACD,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,IAAI;MAChB;wDAAQ;QACJ,IAAI,EAAE,GAAG;;AAM7B,gBAAiB;EACb,KAAK,EAAE,IAAI;;AAEf,sBAAuB;EACnB,KAAK,EAAE,GAAG",
4
+ "sources": ["style.scss"],
5
+ "names": [],
6
+ "file": "style.css"
7
+ }
includes/controls/toggle/style.scss ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .customize-control-toggle {
2
+ .fs-checkbox {
3
+ &.fs-checkbox-enabled {
4
+ cursor: pointer;
5
+ margin: 0 0 10px 0;
6
+ overflow: hidden;
7
+ &:focus {
8
+ box-shadow: none;
9
+ outline: none;
10
+ }
11
+ }
12
+ &-element_wrapper {
13
+ position: relative;
14
+ border: 0;
15
+ height: 0;
16
+ margin: 0;
17
+ opacity: 0;
18
+ overflow: hidden;
19
+ padding: 0;
20
+ width: 0;
21
+ }
22
+ &-element {
23
+ position: absolute;
24
+ top: 0;
25
+ left: 0;
26
+ z-index: -1;
27
+ pointer-events: none;
28
+ -webkit-transition: none;
29
+ transition: none;
30
+ }
31
+ &-label {
32
+ color: #666666;
33
+ cursor: pointer;
34
+ display: block;
35
+ font-size: 14px;
36
+ line-height: 20px;
37
+ overflow: hidden;
38
+ -webkit-user-select: none;
39
+ -moz-user-select: none;
40
+ -ms-user-select: none;
41
+ user-select: none;
42
+ }
43
+ &-marker {
44
+ width: 20px;
45
+ height: 20px;
46
+ background: #ffffff;
47
+ border: 1px solid #cccccc;
48
+ border-radius: 3px;
49
+ cursor: pointer;
50
+ display: block;
51
+ float: left;
52
+ margin: 0 10px 0 0;
53
+ float: right;
54
+ }
55
+ &-flag {
56
+ width: 100%;
57
+ height: 100%;
58
+ margin: 0;
59
+ &:before {
60
+ width: 5px;
61
+ height: 10px;
62
+ border: 2px solid #999999;
63
+ border-top: 0;
64
+ border-left: 0;
65
+ content: '';
66
+ display: block;
67
+ margin: 3px 0 0 6px;
68
+ -webkit-transition: -webkit-transform 0.15s ease;
69
+ transition: transform 0.15s ease;
70
+ -webkit-transform: rotate(45deg) scale(0);
71
+ -ms-transform: rotate(45deg) scale(0);
72
+ transform: rotate(45deg) scale(0);
73
+ }
74
+ }
75
+ &-checked {
76
+ .fs-checkbox-flag:before {
77
+ -webkit-transform: rotate(45deg) scale(1);
78
+ -ms-transform: rotate(45deg) scale(1);
79
+ transform: rotate(45deg) scale(1);
80
+ }
81
+ }
82
+ }
83
+
84
+ .fs-checkbox,
85
+ .fs-checkbox:after,
86
+ .fs-checkbox:before,
87
+ .fs-checkbox *,
88
+ .fs-checkbox *:after,
89
+ .fs-checkbox *:before {
90
+ box-sizing: border-box;
91
+ -webkit-transition: none;
92
+ transition: none;
93
+ -webkit-user-select: none !important;
94
+ -moz-user-select: none !important;
95
+ -ms-user-select: none !important;
96
+ user-select: none !important;
97
+ }
98
+
99
+ .no-csstransforms {
100
+ .fs-checkbox-flag {
101
+ &:before {
102
+ width: 100%;
103
+ height: 100%;
104
+ content: "\2713";
105
+ display: none;
106
+ line-height: 1;
107
+ text-align: center;
108
+ }
109
+ }
110
+ .fs-checkbox-checked {
111
+ .fs-checkbox-flag{
112
+ &:before {
113
+ display: block;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ .fs-checkbox-radio {
120
+ .fs-checkbox-marker {
121
+ border-radius: 100%;
122
+ }
123
+ .fs-checkbox-flag {
124
+ background: #999999;
125
+ border: 3px solid #ffffff;
126
+ border-radius: 100%;
127
+ -webkit-transform: scale(0);
128
+ -ms-transform: scale(0);
129
+ transform: scale(0);
130
+ -webkit-transition: -webkit-transform 0.15s ease;
131
+ transition: transform 0.15s ease;
132
+ &:before {
133
+ display: none;
134
+ }
135
+ }
136
+ &.fs-checkbox-checked {
137
+ .fs-checkbox-flag {
138
+ -webkit-transform: scale(1);
139
+ -ms-transform: scale(1);
140
+ transform: scale(1);
141
+ &:before {
142
+ display: none;
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ .no-csstransforms {
149
+ .fs-checkbox-radio {
150
+ .fs-checkbox-flag {
151
+ &:before {
152
+ display: none;
153
+ }
154
+ }
155
+ &.fs-checkbox-checked .fs-checkbox-flag:before {
156
+ display: block;
157
+ }
158
+ }
159
+ }
160
+
161
+ .fs-checkbox-focus {
162
+ .fs-checkbox-label {
163
+ color: #333333;
164
+ }
165
+ .fs-checkbox-marker {
166
+ border-color: #999999;
167
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
168
+ }
169
+ }
170
+
171
+ .fs-checkbox-disabled {
172
+ cursor: default;
173
+ opacity: 0.5;
174
+ }
175
+
176
+ .fs-checkbox-disabled {
177
+ .fs-checkbox-label {
178
+ color: #666666;
179
+ cursor: default;
180
+ }
181
+ .fs-checkbox-marker {
182
+ border-color: #cccccc;
183
+ cursor: default;
184
+ }
185
+ }
186
+
187
+ .fs-checkbox-toggle {
188
+ position: relative;
189
+ .fs-checkbox-label {
190
+ line-height: 40px;
191
+ }
192
+ .fs-checkbox-marker {
193
+ width: 50px;
194
+ height: 20px;
195
+ position: relative;
196
+ border-radius: 3px;
197
+ }
198
+ .fs-checkbox-marker:after {
199
+ clear: both;
200
+ content: '';
201
+ display: table;
202
+ }
203
+ .fs-checkbox-flag {
204
+ width: 50%;
205
+ height: 100%;
206
+ position: absolute;
207
+ top: 0;
208
+ left: 0;
209
+ background: #999999;
210
+ border: 2px solid #ffffff;
211
+ border-radius: 3px;
212
+ display: block;
213
+ margin: 0;
214
+ -webkit-transition: left 0.15s ease;
215
+ transition: left 0.15s ease;
216
+ &:before {
217
+ display: none;
218
+ }
219
+ &:after {
220
+ width: 2px;
221
+ height: 10px;
222
+ position: absolute;
223
+ top: 0;
224
+ right: 0;
225
+ bottom: 0;
226
+ left: 0;
227
+ background: #ffffff;
228
+ box-shadow: 3px 0 0 #ffffff, -3px 0 0 #ffffff;
229
+ content: '';
230
+ margin: auto;
231
+ opacity: 0.75;
232
+ }
233
+ }
234
+ &.fs-checkbox-checked {
235
+ .fs-checkbox-flag {
236
+ left: 50%;
237
+ &:before {
238
+ display: none;
239
+ }
240
+ &:after {
241
+ display: none;
242
+ }
243
+ }
244
+ }
245
+ .fs-checkbox-state {
246
+ width: 50%;
247
+ color: #666666;
248
+ display: block;
249
+ font-size: 12px;
250
+ line-height: 40px;
251
+ margin: 0;
252
+ text-align: center;
253
+ text-transform: uppercase;
254
+ text-indent: -9999px;
255
+ }
256
+ .fs-checkbox-state_on {
257
+ float: left;
258
+ }
259
+ .fs-checkbox-state_off {
260
+ float: right;
261
+ }
262
+ }
263
+ .no-touch {
264
+ .fs-checkbox-toggle:hover .fs-checkbox-flag:after {
265
+ opacity: 1;
266
+ }
267
+ }
268
+ }
includes/deprecated.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file contains all the deprecated functions.
4
+ * We could easily delete all these but they are kept for backwards-compatibility purposes.
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ if ( ! function_exists( 'kirki_get_option' ) ) {
20
+ /**
21
+ * Get the value of a field.
22
+ * This is a deprecated function that we in use when there was no API.
23
+ * Please use the Kirki::get_option() method instead.
24
+ * Documentation is available for the new method on https://github.com/aristath/kirki/wiki/Getting-the-values
25
+ */
26
+ function kirki_get_option( $option = '' ) {
27
+
28
+ // Make sure the class is instanciated
29
+ Kirki_Toolkit::get_instance();
30
+
31
+ $values = array();
32
+
33
+ // Get the array of all the fields.
34
+ $fields = Kirki::$fields;
35
+ // Get the config.
36
+ $config = apply_filters( 'kirki/config', array() );
37
+ $config['option_type'] = ( isset( $config['option_type'] ) ) ? esc_attr( $config['option_type'] ) : 'theme_mod';
38
+ $config['option_name'] = ( isset( $config['option_name'] ) ) ? esc_attr( $config['option_name'] ) : '';
39
+
40
+ // If we're using options instead of theme_mods,
41
+ // then first we'll have to get the array of all options.
42
+ if ( 'option' == $config['option_type'] ) {
43
+ if ( '' == $config['option_name'] ) {
44
+ // No option name is defined.
45
+ // Each options is saved separately in the db, so we'll manually build the array here.
46
+ foreach ( $fields as $field ) {
47
+ $values[Kirki_Field::sanitize_settings( $field )] = get_option( Kirki_Field::sanitize_settings( $field ), Kirki_Field::sanitize_default( $field ) );
48
+ }
49
+ } else {
50
+ // An option_name has been defined so our options are all saved in an array there.
51
+ $values = get_option( $config['option_name'] );
52
+ foreach ( $fields as $field ) {
53
+ if ( ! isset( $values[Kirki_Field::sanitize_settings_raw( $field )] ) ) {
54
+ $values[Kirki_Field::sanitize_settings_raw( $field )] = maybe_unserialize( Kirki_Field::sanitize_default( $field ) );
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ if ( '' == $option ) {
61
+ // No option has been defined so we'll get all options and return an array
62
+ // If we're using options then we already have the $values set above.
63
+ // All we need here is a fallback for theme_mods
64
+ if ( 'option' != $config['option_type'] ) {
65
+ // We're using theme_mods
66
+ $values = get_theme_mods();
67
+ }
68
+
69
+ // Early exit and return the array of all values
70
+ return $values;
71
+
72
+ }
73
+
74
+ // If a value has been defined then we proceed.
75
+
76
+ // Early exit if this option does not exist
77
+ $field_id = ( 'option' == $config['option_type'] && '' != $config['option_name'] ) ? $config['option_name'].'['.$option.']' : $option;
78
+ if ( ! isset( $fields[$field_id] ) ) {
79
+ return;
80
+ }
81
+
82
+ if ( 'option' == $config['option_type'] ) {
83
+ // We're using options instead of theme_mods.
84
+ // We already have the array of values set from above so we'll use that.
85
+ $value = ( isset( $values[$option] ) ) ? $values[$option] : $fields[$option]['default'];
86
+
87
+ } else {
88
+ // We're using theme_mods
89
+ $value = get_theme_mod( $option, $fields[$option]['default'] );
90
+
91
+ }
92
+
93
+ // Combine background options to a single array
94
+ if ( 'background' == $fields[$field_id]['type'] ) {
95
+ if ( 'option' == $config['option_type'] ) {
96
+ $value = array(
97
+ 'background-color' => isset( $values[$option.'_color'] ) ? $values[$option.'_color'] : null,
98
+ 'background-repeat' => isset( $values[$option.'_repeat'] ) ? $values[$option.'_repeat'] : null,
99
+ 'background-attachment' => isset( $values[$option.'_attach'] ) ? $values[$option.'_attach'] : null,
100
+ 'background-image' => isset( $values[$option.'_image'] ) ? $values[$option.'_image'] : null,
101
+ 'background-position' => isset( $values[$option.'_position'] ) ? $values[$option.'_position'] : null,
102
+ 'background-clip' => isset( $values[$option.'_clip'] ) ? $values[$option.'_clip'] : null,
103
+ 'background-size' => isset( $values[$option.'_size'] ) ? $values[$option.'_size'] : null,
104
+ );
105
+ } else {
106
+ $value = array(
107
+ 'background-color' => isset( $fields[$field_id]['default']['color'] ) ? get_theme_mod( $option.'_color', $fields[$field_id]['default']['color'] ) : null,
108
+ 'background-repeat' => isset( $fields[$field_id]['default']['repeat'] ) ? get_theme_mod( $option.'_repeat', $fields[$field_id]['default']['repeat'] ) : null,
109
+ 'background-attachment' => isset( $fields[$field_id]['default']['attach'] ) ? get_theme_mod( $option.'_attach', $fields[$field_id]['default']['attach'] ) : null,
110
+ 'background-image' => isset( $fields[$field_id]['default']['image'] ) ? get_theme_mod( $option.'_image', $fields[$field_id]['default']['image'] ) : null,
111
+ 'background-position' => isset( $fields[$field_id]['default']['position'] ) ? get_theme_mod( $option.'_position', $fields[$field_id]['default']['position'] ) : null,
112
+ 'background-clip' => isset( $fields[$field_id]['default']['clip'] ) ? get_theme_mod( $option.'_clip', $fields[$field_id]['default']['clip'] ) : null,
113
+ 'background-size' => isset( $fields[$field_id]['default']['size'] ) ? get_theme_mod( $option.'_size', $fields[$field_id]['default']['size'] ) : null,
114
+ );
115
+ }
116
+ }
117
+
118
+ // Return the single value.
119
+ // Pass it through maybe_unserialize so we're sure we get a proper value.
120
+ return maybe_unserialize( $value );
121
+
122
+ }
123
+ }
124
+
125
+ if ( ! function_exists( 'kirki_sanitize_hex' ) ) {
126
+ function kirki_sanitize_hex( $color ) {
127
+ return Kirki_Color::sanitize_hex( $color );
128
+ }
129
+ }
130
+
131
+ if ( ! function_exists( 'kirki_get_rgb' ) ) {
132
+ function kirki_get_rgb( $hex, $implode = false ) {
133
+ return Kirki_Color::get_rgb( $hex, $implode );
134
+ }
135
+ }
136
+
137
+ if ( ! function_exists( 'kirki_get_rgba' ) ) {
138
+ function kirki_get_rgba( $hex = '#fff', $opacity = 100 ) {
139
+ return Kirki_Color::get_rgba( $hex, $opacity );
140
+ }
141
+ }
142
+
143
+ if ( ! function_exists( 'kirki_get_brightness' ) ) {
144
+ function kirki_get_brightness( $hex ) {
145
+ return Kirki_Color::get_brightness( $hex );
146
+ }
147
+ }
148
+
149
+ if ( ! class_exists( 'Kirki_Fonts' ) ) {
150
+
151
+ class Kirki_Fonts {
152
+
153
+ public static function get_all_fonts() {
154
+ $font_registry = Kirki_Toolkit::fonts();
155
+ return $font_registry->get_all_fonts();
156
+ }
157
+
158
+ public static function get_font_choices() {
159
+ $font_registry = Kirki_Toolkit::fonts();
160
+ return $font_registry->get_font_choices();
161
+ }
162
+
163
+ public static function is_google_font( $font ) {
164
+ $font_registry = Kirki_Toolkit::fonts();
165
+ return $font_registry->is_google_font( $font );
166
+ }
167
+
168
+ public static function get_google_font_uri( $fonts, $weight = 400, $subset = 'all' ) {
169
+ $font_registry = Kirki_Toolkit::fonts();
170
+ return $font_registry->get_google_font_uri( $fonts, $weight, $subset );
171
+ }
172
+
173
+ public static function get_google_font_subsets() {
174
+ $font_registry = Kirki_Toolkit::fonts();
175
+ return $font_registry->get_google_font_subsets();
176
+ }
177
+
178
+ public static function choose_google_font_variants( $font, $variants = array() ) {
179
+ $font_registry = Kirki_Toolkit::fonts();
180
+ return $font_registry->choose_google_font_variants( $font, $variants );
181
+ }
182
+
183
+ public static function get_standard_fonts() {
184
+ $font_registry = Kirki_Toolkit::fonts();
185
+ return $font_registry->get_standard_fonts();
186
+ }
187
+
188
+ public static function get_font_stack( $font ) {
189
+ $font_registry = Kirki_Toolkit::fonts();
190
+ return $font_registry->get_font_stack( $font );
191
+ }
192
+
193
+ public static function sanitize_font_choice( $value ) {
194
+ $font_registry = Kirki_Toolkit::fonts();
195
+ return $font_registry->sanitize_font_choice( $value );
196
+ }
197
+
198
+ public static function get_google_fonts() {
199
+ $font_registry = Kirki_Toolkit::fonts();
200
+ return $font_registry->get_google_fonts();
201
+ }
202
+
203
+ }
204
+
205
+ }
includes/functions.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper functions
4
+ *
5
+ * @package Kirki
6
+ * @category Core
7
+ * @author Aristeides Stathopoulos
8
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ if ( ! function_exists( 'kirki_path' ) ) {
19
+ function kirki_path() {
20
+ return KIRKI_PATH;
21
+ }
22
+ }
23
+
24
+ if ( ! function_exists( 'kirki_url' ) ) {
25
+ function kirki_url() {
26
+ $config = apply_filters( 'kirki/config', array() );
27
+ if ( isset( $config['url_path'] ) ) {
28
+ return esc_url_raw( $config['url_path'] );
29
+ } else {
30
+ return KIRKI_URL;
31
+ }
32
+ }
33
+ }
34
+
35
+ if ( ! function_exists( 'kirki_active_callback' ) ) {
36
+ function kirki_active_callback( $object ) {
37
+
38
+ // Get all fields
39
+ $fields = Kirki::$fields;
40
+
41
+ if ( ! isset( $fields[ $object->id ] ) ) {
42
+ return true;
43
+ }
44
+
45
+ $current_object = $fields[ $object->id ];
46
+
47
+ if ( isset( $current_object['required'] ) ) {
48
+
49
+ foreach ( $current_object['required'] as $requirement ) {
50
+
51
+ if ( ! is_object( $object->manager->get_setting( $fields[ $requirement['setting'] ]['settings'] ) ) ) {
52
+ return true;
53
+ }
54
+
55
+ if ( isset( $show ) && ! $show ) {
56
+ return false;
57
+ }
58
+
59
+ $value = $object->manager->get_setting( $fields[ $requirement['setting'] ]['settings'] )->value();
60
+ switch ( $requirement['operator'] ) {
61
+ case '===' :
62
+ $show = ( $requirement['value'] === $value ) ? true : false;
63
+ break;
64
+ case '==' :
65
+ $show = ( $requirement['value'] == $value ) ? true : false;
66
+ break;
67
+ case '!==' :
68
+ $show = ( $requirement['value'] !== $value ) ? true : false;
69
+ break;
70
+ case '!=' :
71
+ $show = ( $requirement['value'] != $value ) ? true : false;
72
+ break;
73
+ case '>=' :
74
+ $show = ( $requirement['value'] >= $value ) ? true : false;
75
+ break;
76
+ case '<=' :
77
+ $show = ( $requirement['value'] <= $value ) ? true : false;
78
+ break;
79
+ case '>' :
80
+ $show = ( $requirement['value'] > $value ) ? true : false;
81
+ break;
82
+ case '<' :
83
+ $show = ( $requirement['value'] < $value ) ? true : false;
84
+ break;
85
+ default :
86
+ $show = ( $requirement['value'] == $value ) ? true : false;
87
+
88
+ }
89
+
90
+ }
91
+
92
+ }
93
+
94
+ return ( isset( $show ) && ( false === $show ) ) ? false : true;
95
+
96
+ }
97
+ }
includes/redux-compatibility.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Redux-compatibility.
4
+ * adds a 'Redux' class and tries to emulate the way Redux adds its fields & sections.
5
+ *
6
+ * @package Kirki
7
+ * @category Core
8
+ * @author Aristeides Stathopoulos
9
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 1.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ // No need to proceed if Redux exists.
20
+ if ( class_exists( 'Redux' ) ) {
21
+ return;
22
+ }
23
+
24
+ class Redux {
25
+
26
+ public static $config = array();
27
+ public static $fields = array();
28
+ public static $panels = array();
29
+ public static $sections = array();
30
+
31
+ /**
32
+ * the class constructor
33
+ */
34
+ public function __construct() {
35
+ add_action( 'wp_loaded', array( $this, 'add_to_customizer' ), 1 );
36
+ }
37
+
38
+ public static function setArgs( $opt_name = '', $args = array() ) {
39
+ Kirki::add_config( $opt_name, array(
40
+ 'option_type' => 'option',
41
+ 'option_name' => $args['opt_name'],
42
+ ) );
43
+ }
44
+
45
+ public static function setSection( $config_id, $args = array() ) {
46
+
47
+ if ( ! isset( $args['fields'] ) || ! isset( $args['subsection'] ) || ( isset( $args['subsection'] ) && ! $args['subsection'] ) ) { // This is a panel
48
+ Kirki::$panels[] = array(
49
+ 'id' => isset( $args['id'] ) ? sanitize_key( $args['id'] ) : substr( str_shuffle( 'abcdefghijklmnopqrstuvwxyz-_' ), 0, 7 ),
50
+ 'title' => isset( $args['title'] ) ? $args['title'] : '',
51
+ 'priority' => ( isset( $args['priority'] ) ) ? $args['priority'] : 10,
52
+ 'description' => ( isset( $args['desc'] ) ) ? $args['desc'] : '',
53
+ );
54
+ } else { // This is a section
55
+ // Get the section ID
56
+ if ( isset( $args['subsection'] ) && $args['subsection'] ) {
57
+ $panel = end( array_values( Kirki::$panels ) );
58
+ $panel_id = $panel['id'];
59
+ }
60
+
61
+ Kirki::$sections[] = array(
62
+ 'id' => isset( $args['id'] ) ? sanitize_key( $args['id'] ) : substr( str_shuffle( "abcdefghijklmnopqrstuvwxyz-_" ), 0, 7 ),
63
+ 'title' => $args['title'],
64
+ 'priority' => ( isset( $args['priority'] ) ) ? $args['priority'] : 10,
65
+ 'panel' => ( isset( $panel_id ) ) ? $panel_id : '',
66
+ 'description' => ( isset( $args['desc'] ) ) ? $args['desc'] : '',
67
+ );
68
+
69
+ foreach ( $args['fields'] as $field ) {
70
+
71
+ $field['section'] = isset( $args['id'] ) ? sanitize_key( $args['id'] ) : substr( str_shuffle( "abcdefghijklmnopqrstuvwxyz-_" ), 0, 7 );
72
+ $field['settings'] = $field['id'];
73
+ $field['help'] = ( isset( $field['desc'] ) ) ? $field['desc'] : '';
74
+ $field['description'] = ( isset( $field['subtitle'] ) ) ? $field['subtitle'] : '';
75
+ $field['choices'] = ( isset( $field['options'] ) ) ? $field['options'] : '';
76
+ $field['label'] = ( isset( $field['title'] ) ) ? $field['title'] : '';
77
+
78
+ switch ( $field['type'] ) {
79
+
80
+ case 'ace_editor' :
81
+ $field['type'] = 'textarea';
82
+ break;
83
+ case 'button_set' :
84
+ $field['type'] = 'radio-buttonset';
85
+ break;
86
+ case 'checkbox' :
87
+ if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
88
+ $field['type'] = 'multicheck';
89
+ }
90
+ case 'color_rgba' :
91
+ $field['type'] = 'color-alpha';
92
+ if ( isset( $field['default'] ) && is_array( $field['default'] ) ) {
93
+ $field['default']['color'] = isset( $field['default']['color'] ) ? Kirki_Color::sanitize_hex( $field['default']['color'], true ) : '#ffffff';
94
+ $field['default']['alpha'] = isset( $field['default']['alpha'] ) ? $field['default']['alpha'] : '1';
95
+ $field['default'] = Kirki_Color::get_rgba( $field['default']['color'], $field['default']['alpha'] );
96
+ }
97
+ break;
98
+ case 'image_select' :
99
+ $field['type'] = 'radio-image';
100
+ break;
101
+ case 'info' :
102
+ $fiel['label'] = '';
103
+ $field['help'] = '';
104
+ $field['type'] = 'custom';
105
+ $background_color = '#fcf8e3';
106
+ $border_color = '#faebcc';
107
+ $text_color = '#8a6d3b';
108
+ if ( isset( $field['style'] ) ) {
109
+ if ( 'success' == $field['style'] ) {
110
+ $background_color = '#dff0d8';
111
+ $border_color = '#d6e9c6';
112
+ $text_color = '#3c763d';
113
+ } elseif ( 'critical' == $field['style'] ) {
114
+ $background_color = '#f2dede';
115
+ $border_color = '#ebccd1';
116
+ $text_color = '#a94442';
117
+ }
118
+ }
119
+ $field['default'] = '<div style="padding: 10px;background:'.$background_color.';border-radius:4px;border:1px solid '.$border_color.';color:'.$text_color.';">';
120
+ $field['default'] .= ( isset( $field['title'] ) ) ? '<h4>'.$field['title'].'</h4>' : '';
121
+ $field['default'] .= ( isset( $field['desc'] ) ) ? $field['desc'] : '';
122
+ $field['default'] .= '</div>';
123
+ break;
124
+ case 'palette' :
125
+ $field['choices'] = $field['palettes'];
126
+ break;
127
+ case 'raw' :
128
+ $field['default'] = $field['content'];
129
+ break;
130
+ case 'select' :
131
+ if ( is_array( $field['choices'] ) ) {
132
+ foreach ( $field['choices'] as $key => $value ) {
133
+ if ( is_array( $value ) ) {
134
+ foreach ( $value as $child_key => $child_value ) {
135
+ $field['choices'][$child_key] = $child_value;
136
+ }
137
+ unset( $field['choices'][$key] );
138
+ }
139
+ }
140
+ }
141
+ break;
142
+ case 'slider' :
143
+ $field['choices'] = array(
144
+ 'min' => $field['min'],
145
+ 'max' => $field['max'],
146
+ 'step' => $field['step'],
147
+ );
148
+ break;
149
+ case 'spinner' :
150
+ $field['type'] = 'number';
151
+ break;
152
+ case 'background' :
153
+ case 'border' :
154
+ case 'color_gradient' :
155
+ case 'date' :
156
+ case 'dimensions' :
157
+ case 'divide' :
158
+ case 'gallery' :
159
+ case 'import_export' :
160
+ case 'link_color' :
161
+ case 'media' :
162
+ case 'multi_text' :
163
+ case 'password' :
164
+ case 'section' :
165
+ case 'select_image' :
166
+ case 'sortable' :
167
+ case 'sorter' :
168
+ case 'spacing' :
169
+ case 'spinner' :
170
+ case 'switch' :
171
+ case 'typography' :
172
+ case 'slides' :
173
+ // TODO
174
+ break;
175
+
176
+ }
177
+
178
+ Kirki::add_field( $config_id, $field );
179
+
180
+ }
181
+
182
+ }
183
+
184
+ }
185
+
186
+ public static function setHelpTab() {}
187
+
188
+ public static function setHelpSidebar() {}
189
+
190
+ /**
191
+ * Helper function that adds the fields, sections and panels to the customizer.
192
+ */
193
+ public function add_to_customizer( $wp_customize ) {
194
+ add_filter( 'kirki/fields', array( $this, 'merge_fields' ) );
195
+ add_action( 'customize_register', array( $this, 'add_panels' ), 998 );
196
+ add_action( 'customize_register', array( $this, 'add_sections' ), 999 );
197
+ }
198
+
199
+ }
kirki-user-tests.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Kirki_Test_Field {
4
+
5
+ /**
6
+ * The field is an array
7
+ * Built just like any other field.
8
+ * See https://github.com/reduxframework/kirki/wiki/Fields
9
+ */
10
+ public $field = array();
11
+
12
+ /**
13
+ * The class constructor
14
+ */
15
+ public function __construct( $field_args = array() ) {
16
+
17
+ $this->field = $field_args;
18
+ $this->create_section();
19
+ $this->add_fields_via_api();
20
+
21
+ add_filter( 'kirki/fields', array( $this, 'add_filter_fields' ) );
22
+
23
+ }
24
+
25
+ /**
26
+ * Create the Section
27
+ */
28
+ public function create_section() {
29
+ Kirki::add_section( sanitize_key( $this->field['type'] ), array(
30
+ 'priority' => 10,
31
+ 'title' => sprintf( __( '%s test', 'kirki' ), $this->field['type'] ),
32
+ ) );
33
+ }
34
+
35
+ /**
36
+ * Add the field using the
37
+ */
38
+ public function add_filter_fields( $fields ) {
39
+
40
+ $args = $this->field;
41
+ $args['section'] = sanitize_key( $this->field['type'] );
42
+
43
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_0';
44
+ $args['label'] = sprintf( __( '%s theme_mod via filter', 'kirki' ), $args['type'] );
45
+ $args['option_type'] = 'theme_mod';
46
+ $fields[] = $args;
47
+
48
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_1';
49
+ $args['label'] = sprintf( __( '%s single option via filter', 'kirki' ), $args['type'] );
50
+ $args['option_type'] = 'option';
51
+ $fields[] = $args;
52
+
53
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_2';
54
+ $args['option_type'] = 'option';
55
+ $args['label'] = sprintf( __( '%s serialized option via filter', 'kirki' ), $args['type'] );
56
+ $args['option_name'] = 'kirki_test';
57
+ $fields[] = $args;
58
+
59
+ return $fields;
60
+
61
+ }
62
+
63
+ /**
64
+ * Add fields using the Kirki API
65
+ */
66
+ public function add_fields_via_api() {
67
+
68
+ $args = $this->field;
69
+ $args['section'] = sanitize_key( $this->field['type'] );
70
+ $args['capability'] = 'read';
71
+
72
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_3';
73
+ $args['label'] = sprintf( __( '%s theme_mod via API', 'kirki' ), $args['type'] );
74
+ $args['option_type'] = 'theme_mod';
75
+ Kirki::add_field( '', $args );
76
+
77
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_4';
78
+ $args['label'] = sprintf( __( '%s single option via API', 'kirki' ), $args['type'] );
79
+ $args['option_type'] = 'option';
80
+ Kirki::add_field( '', $args );
81
+
82
+ $args['settings'] = sanitize_key( $this->field['type'] ).'_demo_5';
83
+ $args['option_type'] = 'option';
84
+ $args['label'] = sprintf( __( '%s serialized option via API', 'kirki' ), $args['type'] );
85
+ $args['option_name'] = 'kirki_test';
86
+ Kirki::add_field( '', $args );
87
+
88
+ }
89
+
90
+ }
91
+
92
+ // checkbox
93
+ $checkbox = new Kirki_Test_Field( array( 'type' => 'checkbox', 'default' => 1 ) );
94
+
95
+ // color-alpha
96
+ $color_alpha = new Kirki_Test_Field( array( 'type' => 'color-alpha', 'default' => 'rgba(255,0,0,.75)', 'output' => array( 'element' => 'body a', 'property' => 'color' ) ) );
97
+
98
+ // color
99
+ $color = new Kirki_Test_Field( array( 'type' => 'color', 'default' => '#0000ff', 'output' => array( 'element' => 'a:hover', 'property' => 'color' ) ) );
100
+
101
+ // custom
102
+ $custom = new Kirki_Test_Field( array( 'type' => 'custom', 'default' => '<div style="text-align:center; background-color:#333; margin:10px 5px;"><h3 style="color: #fff !important;">Custom Control Test</h3></div>' ) );
103
+
104
+ // dropdown-pages
105
+ $dropdown_pages = new Kirki_Test_Field( array( 'type' => 'dropdown-pages', 'default' => 1 ) );
106
+
107
+ // editor
108
+ $editor = new Kirki_Test_Field( array( 'type' => 'editor', 'default' => 'This is the standard TinyMCE editor.' ) );
109
+
110
+ // image
111
+ $image = new Kirki_Test_Field( array( 'type' => 'image', 'default' => '' ) );
112
+
113
+ // multicheck
114
+ $multicheck = new Kirki_Test_Field( array( 'type' => 'multicheck', 'default' => array( 'option1' ), 'choices' => array( 'option1' => __( 'Option 1', 'kirki' ), 'option2' => __( 'Option 2', 'kirki' ), 'option3' => __( 'Option 3', 'kirki' ) ) ) );
115
+
116
+ // number
117
+ $number = new Kirki_Test_Field( array( 'type' => 'number', 'default' => '99' ) );
118
+
119
+ // palette
120
+ $palette = new Kirki_Test_Field( array( 'type' => 'palette', 'default' => 'red', 'choices' => array( 'red' => array( '#F9BAAF', '#FB9D8C', '#FD8069' ), 'green' => array( '#C9F7C4', '#B3F9AC', '#9DFA94' ), 'blue' => array( '#D9E3F6', '#CCDAF7', '#BED1F8' ) ) ) );
121
+
122
+ // radio-buttonset
123
+ $radio_buttonset = new Kirki_Test_Field( array( 'type' => 'radio-buttonset', 'default' => 'option2', 'choices' => array( 'option1' => __( 'Option 1', 'kirki' ), 'option2' => __( 'Option 2', 'kirki' ), 'option-3' => __( 'Option 3', 'kirki' ) ) ) );
124
+
125
+ // radio-image
126
+ $radio_image = new Kirki_Test_Field( array( 'type' => 'radio-image', 'default' => 'option3', 'choices' => array( 'option1' => admin_url().'/images/align-left-2x.png', 'option2' => admin_url().'/images/align-center-2x.png', 'option3' => admin_url().'/images/align-right-2x.png' ) ) );
127
+
128
+ // radio
129
+ $radio = new Kirki_Test_Field( array( 'type' => 'radio', 'default' => 'option1', 'choices' => array( 'option1' => __( 'Option 1', 'kirki' ), 'option2' => __( 'Option 2', 'kirki' ), 'option3' => __( 'Option 3', 'kirki' ) ) ) );
130
+
131
+ // select
132
+ $select = new Kirki_Test_Field( array( 'type' => 'select', 'default' => 'option2', 'choices' => array( 'option1' => __( 'Option 1', 'kirki' ), 'option2' => __( 'Option 2', 'kirki' ), 'option3' => __( 'Option 3', 'kirki' ) ) ) );
133
+
134
+ // slider
135
+ $slider = new Kirki_Test_Field( array( 'type' => 'slider', 'default' => 0, 'choices' => array( 'min' => -100, 'max' => 100, 'step' => 1 ) ) );
136
+
137
+ // sortable
138
+ $sortable = new Kirki_Test_Field( array( 'type' => 'sortable', 'default' => array( 'option2', 'option1' ), 'choices' => array( 'option1' => __( 'Option 1', 'kirki' ), 'option2' => __( 'Option 2', 'kirki' ), 'option3' => __( 'Option 3', 'kirki' ), 'option4' => __( 'Option 4', 'kirki' ) ) ) );
139
+
140
+ // switch
141
+ $switch = new Kirki_Test_Field( array( 'type' => 'switch', 'default' => '1' ) );
142
+
143
+ // text
144
+ $text = new Kirki_Test_Field( array( 'type' => 'text', 'default' => __( 'This is some default text for the text control.', 'kirki' ) ) );
145
+
146
+ // textarea
147
+ $textarea = new Kirki_Test_Field( array( 'type' => 'textarea', 'default' => __( 'This is some default text for the textarea control.', 'kirki' ) ) );
148
+
149
+ // toggle
150
+ $toggle = new Kirki_Test_Field( array( 'type' => 'toggle', 'default' => '1' ) );
151
+
152
+ // upload
153
+ $upload = new Kirki_Test_Field( array( 'type' => 'upload', 'default' => '' ) );
kirki.php CHANGED
@@ -1,30 +1,128 @@
1
  <?php
2
- /*
3
- Plugin Name: Kirki Framework
4
- Plugin URI: http://kirki.org
5
- Description: An options framework using and extending the WordPress Customizer
6
- Author: Aristeides Stathopoulos
7
- Author URI: http://aristeides.com
8
- Version: 0.8.4
9
- Text Domain: kirki
10
- */
 
 
 
 
 
 
 
 
11
 
 
 
 
 
 
 
12
  if ( ! defined( 'KIRKI_PATH' ) ) {
13
  define( 'KIRKI_PATH', dirname( __FILE__ ) );
14
  }
 
15
  if ( ! defined( 'KIRKI_URL' ) ) {
16
  define( 'KIRKI_URL', plugin_dir_url( __FILE__ ) );
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  // Include helper files
20
- include_once( KIRKI_PATH . '/includes/Helpers/libraries/class-kirki-color.php' );
21
- include_once( KIRKI_PATH . '/includes/Helpers/libraries/class-kirki-colourlovers.php' );
22
- include_once( KIRKI_PATH . '/includes/Helpers/deprecated.php' );
23
- include_once( KIRKI_PATH . '/includes/Helpers/sanitize.php' );
24
- include_once( KIRKI_PATH . '/includes/Helpers/helpers.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- // Include the main kirki class
27
- include_once( KIRKI_PATH . '/includes/Kirki.php' );
28
 
29
- // Make sure the class is instanciated
30
- Kirki::get_instance();
 
 
 
 
1
  <?php
2
+ /**
3
+ * Plugin Name: Kirki Toolkit
4
+ * Plugin URI: http://kirki.org
5
+ * Description: The ultimate WordPress Customizer Toolkit
6
+ * Author: Aristeides Stathopoulos
7
+ * Author URI: http://aristeides.com
8
+ * Version: 1.0.0
9
+ * Text Domain: kirki
10
+ *
11
+ *
12
+ * @package Kirki
13
+ * @category Core
14
+ * @author Aristeides Stathopoulos
15
+ * @copyright Copyright (c) 2015, Aristeides Stathopoulos
16
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
17
+ * @since 1.0
18
+ */
19
 
20
+ // Exit if accessed directly
21
+ if ( ! defined( 'ABSPATH' ) ) {
22
+ exit;
23
+ }
24
+
25
+ // Set the KIRKI_PATH constant.
26
  if ( ! defined( 'KIRKI_PATH' ) ) {
27
  define( 'KIRKI_PATH', dirname( __FILE__ ) );
28
  }
29
+ // Set the KIRKI_URL constant.
30
  if ( ! defined( 'KIRKI_URL' ) ) {
31
  define( 'KIRKI_URL', plugin_dir_url( __FILE__ ) );
32
  }
33
 
34
+ if ( ! function_exists( 'kirki_autoload_classes' ) ) {
35
+ /**
36
+ * The Kirki class autoloader.
37
+ * Finds the path to a class that we're requiring and includes the file.
38
+ */
39
+ function kirki_autoload_classes( $class_name ) {
40
+
41
+ if ( 0 === stripos( $class_name, 'Kirki' ) ) {
42
+
43
+ $foldername = ( 0 === stripos( $class_name, 'Kirki_Controls_' ) ) ? 'controls'.DIRECTORY_SEPARATOR.strtolower( str_replace( '_', '-', str_replace( '_Control', '', str_replace( 'Kirki_Controls_', '', $class_name ) ) ) ) : '';
44
+ $foldername = ( '' != $foldername ) ? $foldername.DIRECTORY_SEPARATOR : '';
45
+
46
+ $class_path = KIRKI_PATH.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR.$foldername.'class-'.strtolower( str_replace( '_', '-', $class_name ) ).'.php';
47
+ if ( file_exists( $class_path ) ) {
48
+ include $class_path;
49
+ }
50
+
51
+ }
52
+
53
+ }
54
+ // Run the autoloader
55
+ spl_autoload_register( 'kirki_autoload_classes' );
56
+ }
57
+
58
  // Include helper files
59
+ include_once( KIRKI_PATH.'/includes/functions.php' );
60
+ include_once( KIRKI_PATH.'/includes/deprecated.php' );
61
+ // Include the API class
62
+ include_once( KIRKI_PATH.'/includes/class-kirki.php' );
63
+
64
+ if ( ! function_exists( 'Kirki' ) ) {
65
+ /**
66
+ * Returns the Kirki object
67
+ */
68
+ function Kirki() {
69
+ // Make sure the class is instanciated
70
+ $kirki = Kirki_Toolkit::get_instance();
71
+
72
+ $kirki->font_registry = new Kirki_Fonts_Font_Registry();
73
+ $kirki->scripts = new Kirki_Scripts_Registry();
74
+ $kirki->api = new Kirki();
75
+ $kirki->styles = array(
76
+ 'back' => new Kirki_Styles_Customizer(),
77
+ 'front' => new Kirki_Styles_Frontend(),
78
+ );
79
+
80
+
81
+ return $kirki;
82
+
83
+ }
84
+
85
+ global $kirki;
86
+ $kirki = Kirki();
87
+ }
88
+
89
+ if ( defined( 'KIRKI_REDUX_COMPATIBILITY' ) && KIRKI_REDUX_COMPATIBILITY ) {
90
+ include_once( KIRKI_PATH.'/includes/redux-compatibility.php' );
91
+ }
92
+
93
+ if ( ! function_exists( 'kirki_load_textdomain' ) ) {
94
+ /**
95
+ * Load plugin textdomain.
96
+ *
97
+ * @since 0.8.0
98
+ */
99
+ function kirki_load_textdomain() {
100
+ $textdomain = 'kirki';
101
+
102
+ // Look for WP_LANG_DIR/{$domain}-{$locale}.mo
103
+ if ( file_exists( WP_LANG_DIR.'/'.$textdomain.'-'.get_locale().'.mo' ) ) {
104
+ $file = WP_LANG_DIR.'/'.$textdomain.'-'.get_locale().'.mo';
105
+ }
106
+ // Look for KIRKI_PATH/languages/{$domain}-{$locale}.mo
107
+ if ( ! isset( $file ) && file_exists( KIRKI_PATH.'/languages/'.$textdomain.'-'.get_locale().'.mo' ) ) {
108
+ $file = KIRKI_PATH.'/languages/'.$textdomain.'-'.get_locale().'.mo';
109
+ }
110
+
111
+ if ( isset( $file ) ) {
112
+ load_textdomain( $textdomain, $file );
113
+ }
114
+
115
+ load_plugin_textdomain( $textdomain, false, KIRKI_PATH.'/languages' );
116
+ }
117
+ add_action( 'plugins_loaded', 'kirki_load_textdomain' );
118
+ }
119
 
120
+ // Add an empty config for global fields
121
+ Kirki::add_config( '' );
122
 
123
+ /**
124
+ * The 2 following commented-out lines are for testing purposes.
125
+ * You can uncomment whichever you want and fields will flood the customizer.
126
+ */
127
+ // include_once( KIRKI_PATH . '/sample-config.php' );
128
+ // include_once( KIRKI_PATH . '/kirki-user-tests.php' );
languages/kirki-en_US.mo CHANGED
Binary file
languages/kirki-en_US.po CHANGED
@@ -1,185 +1,467 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: Kirki Framework\n"
4
- "POT-Creation-Date: 2015-03-30 01:57+0200\n"
5
- "PO-Revision-Date: 2015-03-30 01:57+0200\n"
6
  "Last-Translator: Stathopoulos Aristeides <info@aristeides.com>\n"
7
  "Language-Team: Stathopoulos Aristeides <info@aristeides.com>\n"
8
  "Language: en_US\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.7.5\n"
13
  "X-Poedit-Basepath: ..\n"
 
 
14
  "X-Poedit-SourceCharset: UTF-8\n"
15
  "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
16
  "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;"
17
  "_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
18
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
19
  "X-Poedit-SearchPath-0: .\n"
20
  "X-Poedit-SearchPathExcluded-0: *.js\n"
21
 
22
- #: includes/Control.php:179
23
  msgid "Background Color"
24
  msgstr "Background Color"
25
 
26
- #: includes/Control.php:192
27
  msgid "Background Image"
28
  msgstr "Background Image"
29
 
30
- #: includes/Control.php:206 includes/Helpers/sanitize.php:45
31
  msgid "No Repeat"
32
  msgstr "No Repeat"
33
 
34
- #: includes/Control.php:207 includes/Helpers/sanitize.php:46
35
  msgid "Repeat All"
36
  msgstr "Repeat All"
37
 
38
- #: includes/Control.php:208 includes/Helpers/sanitize.php:47
39
  msgid "Repeat Horizontally"
40
  msgstr "Repeat Horizontally"
41
 
42
- #: includes/Control.php:209 includes/Helpers/sanitize.php:48
43
  msgid "Repeat Vertically"
44
  msgstr "Repeat Vertically"
45
 
46
- #: includes/Control.php:210 includes/Control.php:227
47
- #: includes/Control.php:247 includes/Helpers/sanitize.php:49
48
- #: includes/Helpers/sanitize.php:63 includes/Helpers/sanitize.php:79
49
  msgid "Inherit"
50
  msgstr "Inherit"
51
 
52
- #: includes/Control.php:213
53
  msgid "Background Repeat"
54
  msgstr "Background Repeat"
55
 
56
- #: includes/Control.php:228 includes/Helpers/sanitize.php:64
57
  msgid "Cover"
58
  msgstr "Cover"
59
 
60
- #: includes/Control.php:229 includes/Helpers/sanitize.php:65
61
  msgid "Contain"
62
  msgstr "Contain"
63
 
64
- #: includes/Control.php:233
65
  msgid "Background Size"
66
  msgstr "Background Size"
67
 
68
- #: includes/Control.php:248 includes/Helpers/sanitize.php:80
69
  msgid "Fixed"
70
  msgstr "Fixed"
71
 
72
- #: includes/Control.php:249 includes/Helpers/sanitize.php:81
73
  msgid "Scroll"
74
  msgstr "Scroll"
75
 
76
- #: includes/Control.php:253
77
  msgid "Background Attachment"
78
  msgstr "Background Attachment"
79
 
80
- #: includes/Control.php:267 includes/Helpers/sanitize.php:95
81
  msgid "Left Top"
82
  msgstr "Left Top"
83
 
84
- #: includes/Control.php:268 includes/Helpers/sanitize.php:96
85
  msgid "Left Center"
86
  msgstr "Left Center"
87
 
88
- #: includes/Control.php:269 includes/Helpers/sanitize.php:97
89
  msgid "Left Bottom"
90
  msgstr "Left Bottom"
91
 
92
- #: includes/Control.php:270 includes/Helpers/sanitize.php:98
93
  msgid "Right Top"
94
  msgstr "Right Top"
95
 
96
- #: includes/Control.php:271 includes/Helpers/sanitize.php:99
97
  msgid "Right Center"
98
  msgstr "Right Center"
99
 
100
- #: includes/Control.php:272 includes/Helpers/sanitize.php:100
101
  msgid "Right Bottom"
102
  msgstr "Right Bottom"
103
 
104
- #: includes/Control.php:273 includes/Helpers/sanitize.php:101
105
  msgid "Center Top"
106
  msgstr "Center Top"
107
 
108
- #: includes/Control.php:274 includes/Helpers/sanitize.php:102
109
  msgid "Center Center"
110
  msgstr "Center Center"
111
 
112
- #: includes/Control.php:275 includes/Helpers/sanitize.php:103
113
  msgid "Center Bottom"
114
  msgstr "Center Bottom"
115
 
116
- #: includes/Control.php:278
117
  msgid "Background Position"
118
  msgstr "Background Position"
119
 
120
- #: includes/Control.php:296
121
  msgid "Background Opacity"
122
  msgstr "Background Opacity"
123
 
124
- #: includes/Controls/SwitchControl.php:26
125
  msgid "ON"
126
  msgstr "ON"
127
 
128
- #: includes/Controls/SwitchControl.php:27
129
  msgid "OFF"
130
  msgstr "OFF"
131
 
132
- #: includes/Fonts/FontRegistry.php:125
133
  msgid "All"
134
  msgstr "All"
135
 
136
- #: includes/Fonts/FontRegistry.php:126
137
  msgid "Cyrillic"
138
  msgstr "Cyrillic"
139
 
140
- #: includes/Fonts/FontRegistry.php:127
141
  msgid "Cyrillic Extended"
142
  msgstr "Cyrillic Extended"
143
 
144
- #: includes/Fonts/FontRegistry.php:128
145
  msgid "Devanagari"
146
  msgstr "Devanagari"
147
 
148
- #: includes/Fonts/FontRegistry.php:129
149
  msgid "Greek"
150
  msgstr "Greek"
151
 
152
- #: includes/Fonts/FontRegistry.php:130
153
  msgid "Greek Extended"
154
  msgstr "Greek Extended"
155
 
156
- #: includes/Fonts/FontRegistry.php:131
157
  msgid "Khmer"
158
  msgstr "Khmer"
159
 
160
- #: includes/Fonts/FontRegistry.php:132
161
  msgid "Latin"
162
  msgstr "Latin"
163
 
164
- #: includes/Fonts/FontRegistry.php:133
165
  msgid "Latin Extended"
166
  msgstr "Latin Extended"
167
 
168
- #: includes/Fonts/FontRegistry.php:134
169
  msgid "Vietnamese"
170
  msgstr "Vietnamese"
171
 
172
- #: includes/Fonts/FontRegistry.php:187
173
  msgctxt "font style"
174
  msgid "Serif"
175
  msgstr "Serif"
176
 
177
- #: includes/Fonts/FontRegistry.php:191
178
  msgctxt "font style"
179
  msgid "Sans Serif"
180
  msgstr "Sans Serif"
181
 
182
- #: includes/Fonts/FontRegistry.php:195
183
  msgctxt "font style"
184
- msgid "Monospaced"
185
- msgstr "Monospaced"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: Kirki Toolkit\n"
4
+ "POT-Creation-Date: 2015-07-11 05:17+0300\n"
5
+ "PO-Revision-Date: 2015-07-11 05:18+0300\n"
6
  "Last-Translator: Stathopoulos Aristeides <info@aristeides.com>\n"
7
  "Language-Team: Stathopoulos Aristeides <info@aristeides.com>\n"
8
  "Language: en_US\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
  "X-Poedit-Basepath: ..\n"
14
+ "X-Poedit-WPHeader: kirki.php\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
  "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
18
  "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;"
19
  "_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
 
20
  "X-Poedit-SearchPath-0: .\n"
21
  "X-Poedit-SearchPathExcluded-0: *.js\n"
22
 
23
+ #: includes/class-kirki-toolkit.php:52
24
  msgid "Background Color"
25
  msgstr "Background Color"
26
 
27
+ #: includes/class-kirki-toolkit.php:53
28
  msgid "Background Image"
29
  msgstr "Background Image"
30
 
31
+ #: includes/class-kirki-toolkit.php:54
32
  msgid "No Repeat"
33
  msgstr "No Repeat"
34
 
35
+ #: includes/class-kirki-toolkit.php:55
36
  msgid "Repeat All"
37
  msgstr "Repeat All"
38
 
39
+ #: includes/class-kirki-toolkit.php:56
40
  msgid "Repeat Horizontally"
41
  msgstr "Repeat Horizontally"
42
 
43
+ #: includes/class-kirki-toolkit.php:57
44
  msgid "Repeat Vertically"
45
  msgstr "Repeat Vertically"
46
 
47
+ #: includes/class-kirki-toolkit.php:58
 
 
48
  msgid "Inherit"
49
  msgstr "Inherit"
50
 
51
+ #: includes/class-kirki-toolkit.php:59
52
  msgid "Background Repeat"
53
  msgstr "Background Repeat"
54
 
55
+ #: includes/class-kirki-toolkit.php:60
56
  msgid "Cover"
57
  msgstr "Cover"
58
 
59
+ #: includes/class-kirki-toolkit.php:61
60
  msgid "Contain"
61
  msgstr "Contain"
62
 
63
+ #: includes/class-kirki-toolkit.php:62
64
  msgid "Background Size"
65
  msgstr "Background Size"
66
 
67
+ #: includes/class-kirki-toolkit.php:63
68
  msgid "Fixed"
69
  msgstr "Fixed"
70
 
71
+ #: includes/class-kirki-toolkit.php:64
72
  msgid "Scroll"
73
  msgstr "Scroll"
74
 
75
+ #: includes/class-kirki-toolkit.php:65
76
  msgid "Background Attachment"
77
  msgstr "Background Attachment"
78
 
79
+ #: includes/class-kirki-toolkit.php:66
80
  msgid "Left Top"
81
  msgstr "Left Top"
82
 
83
+ #: includes/class-kirki-toolkit.php:67
84
  msgid "Left Center"
85
  msgstr "Left Center"
86
 
87
+ #: includes/class-kirki-toolkit.php:68
88
  msgid "Left Bottom"
89
  msgstr "Left Bottom"
90
 
91
+ #: includes/class-kirki-toolkit.php:69
92
  msgid "Right Top"
93
  msgstr "Right Top"
94
 
95
+ #: includes/class-kirki-toolkit.php:70
96
  msgid "Right Center"
97
  msgstr "Right Center"
98
 
99
+ #: includes/class-kirki-toolkit.php:71
100
  msgid "Right Bottom"
101
  msgstr "Right Bottom"
102
 
103
+ #: includes/class-kirki-toolkit.php:72
104
  msgid "Center Top"
105
  msgstr "Center Top"
106
 
107
+ #: includes/class-kirki-toolkit.php:73
108
  msgid "Center Center"
109
  msgstr "Center Center"
110
 
111
+ #: includes/class-kirki-toolkit.php:74
112
  msgid "Center Bottom"
113
  msgstr "Center Bottom"
114
 
115
+ #: includes/class-kirki-toolkit.php:75
116
  msgid "Background Position"
117
  msgstr "Background Position"
118
 
119
+ #: includes/class-kirki-toolkit.php:76
120
  msgid "Background Opacity"
121
  msgstr "Background Opacity"
122
 
123
+ #: includes/class-kirki-toolkit.php:77
124
  msgid "ON"
125
  msgstr "ON"
126
 
127
+ #: includes/class-kirki-toolkit.php:78
128
  msgid "OFF"
129
  msgstr "OFF"
130
 
131
+ #: includes/class-kirki-toolkit.php:79
132
  msgid "All"
133
  msgstr "All"
134
 
135
+ #: includes/class-kirki-toolkit.php:80
136
  msgid "Cyrillic"
137
  msgstr "Cyrillic"
138
 
139
+ #: includes/class-kirki-toolkit.php:81
140
  msgid "Cyrillic Extended"
141
  msgstr "Cyrillic Extended"
142
 
143
+ #: includes/class-kirki-toolkit.php:82
144
  msgid "Devanagari"
145
  msgstr "Devanagari"
146
 
147
+ #: includes/class-kirki-toolkit.php:83
148
  msgid "Greek"
149
  msgstr "Greek"
150
 
151
+ #: includes/class-kirki-toolkit.php:84
152
  msgid "Greek Extended"
153
  msgstr "Greek Extended"
154
 
155
+ #: includes/class-kirki-toolkit.php:85
156
  msgid "Khmer"
157
  msgstr "Khmer"
158
 
159
+ #: includes/class-kirki-toolkit.php:86
160
  msgid "Latin"
161
  msgstr "Latin"
162
 
163
+ #: includes/class-kirki-toolkit.php:87
164
  msgid "Latin Extended"
165
  msgstr "Latin Extended"
166
 
167
+ #: includes/class-kirki-toolkit.php:88
168
  msgid "Vietnamese"
169
  msgstr "Vietnamese"
170
 
171
+ #: includes/class-kirki-toolkit.php:89
172
  msgctxt "font style"
173
  msgid "Serif"
174
  msgstr "Serif"
175
 
176
+ #: includes/class-kirki-toolkit.php:90
177
  msgctxt "font style"
178
  msgid "Sans Serif"
179
  msgstr "Sans Serif"
180
 
181
+ #: includes/class-kirki-toolkit.php:91
182
  msgctxt "font style"
183
+ msgid "Monospace"
184
+ msgstr "Monospace"
185
+
186
+ #: kirki-user-tests.php:31
187
+ #, php-format
188
+ msgid "%s test"
189
+ msgstr "%s test"
190
+
191
+ #: kirki-user-tests.php:44
192
+ #, php-format
193
+ msgid "%s theme_mod via filter"
194
+ msgstr "%s theme_mod via filter"
195
+
196
+ #: kirki-user-tests.php:49
197
+ #, php-format
198
+ msgid "%s single option via filter"
199
+ msgstr "%s single option via filter"
200
+
201
+ #: kirki-user-tests.php:55
202
+ #, php-format
203
+ msgid "%s serialized option via filter"
204
+ msgstr "%s serialized option via filter"
205
+
206
+ #: kirki-user-tests.php:73
207
+ #, php-format
208
+ msgid "%s theme_mod via API"
209
+ msgstr "%s theme_mod via API"
210
+
211
+ #: kirki-user-tests.php:78
212
+ #, php-format
213
+ msgid "%s single option via API"
214
+ msgstr "%s single option via API"
215
+
216
+ #: kirki-user-tests.php:84
217
+ #, php-format
218
+ msgid "%s serialized option via API"
219
+ msgstr "%s serialized option via API"
220
+
221
+ #: kirki-user-tests.php:114 kirki-user-tests.php:123
222
+ #: kirki-user-tests.php:129 kirki-user-tests.php:132
223
+ #: kirki-user-tests.php:138 sample-config.php:90 sample-config.php:117
224
+ #: sample-config.php:150 sample-config.php:169 sample-config.php:190
225
+ #: sample-config.php:273
226
+ msgid "Option 1"
227
+ msgstr "Option 1"
228
+
229
+ #: kirki-user-tests.php:114 kirki-user-tests.php:123
230
+ #: kirki-user-tests.php:129 kirki-user-tests.php:132
231
+ #: kirki-user-tests.php:138 sample-config.php:91 sample-config.php:118
232
+ #: sample-config.php:151 sample-config.php:170 sample-config.php:191
233
+ #: sample-config.php:274
234
+ msgid "Option 2"
235
+ msgstr "Option 2"
236
+
237
+ #: kirki-user-tests.php:114 kirki-user-tests.php:123
238
+ #: kirki-user-tests.php:129 kirki-user-tests.php:132
239
+ #: kirki-user-tests.php:138 sample-config.php:92 sample-config.php:119
240
+ #: sample-config.php:152 sample-config.php:171 sample-config.php:192
241
+ #: sample-config.php:275
242
+ msgid "Option 3"
243
+ msgstr "Option 3"
244
+
245
+ #: kirki-user-tests.php:138 sample-config.php:93 sample-config.php:120
246
+ #: sample-config.php:172 sample-config.php:193 sample-config.php:276
247
+ msgid "Option 4"
248
+ msgstr "Option 4"
249
+
250
+ #: kirki-user-tests.php:144
251
+ msgid "This is some default text for the text control."
252
+ msgstr "This is some default text for the text control."
253
+
254
+ #: kirki-user-tests.php:147
255
+ msgid "This is some default text for the textarea control."
256
+ msgstr "This is some default text for the textarea control."
257
+
258
+ #: sample-config.php:22
259
+ msgid "Controls with Choices"
260
+ msgstr "Controls with Choices"
261
+
262
+ #: sample-config.php:24 sample-config.php:30 sample-config.php:36
263
+ #: sample-config.php:42 sample-config.php:48 sample-config.php:54
264
+ #: sample-config.php:60
265
+ msgid "This is the section description"
266
+ msgstr "This is the section description"
267
+
268
+ #: sample-config.php:28
269
+ msgid "Color Controls"
270
+ msgstr "Color Controls"
271
+
272
+ #: sample-config.php:34
273
+ msgid "File & Image Controls"
274
+ msgstr "File & Image Controls"
275
+
276
+ #: sample-config.php:40
277
+ msgid "Text Control"
278
+ msgstr "Text Control"
279
+
280
+ #: sample-config.php:46
281
+ msgid "Background Control"
282
+ msgstr "Background Control"
283
+
284
+ #: sample-config.php:52
285
+ msgid "Numeric Controls"
286
+ msgstr "Numeric Controls"
287
+
288
+ #: sample-config.php:58
289
+ msgid "Custom Control"
290
+ msgstr "Custom Control"
291
+
292
+ #: sample-config.php:71
293
+ msgid "Boolean Controls"
294
+ msgstr "Boolean Controls"
295
+
296
+ #: sample-config.php:72
297
+ msgid "This panel contains controls that return true/false Controls"
298
+ msgstr "This panel contains controls that return true/false Controls"
299
+
300
+ #: sample-config.php:83
301
+ msgid "Radio Control"
302
+ msgstr "Radio Control"
303
+
304
+ #: sample-config.php:84 sample-config.php:101 sample-config.php:111
305
+ #: sample-config.php:128 sample-config.php:144 sample-config.php:160
306
+ #: sample-config.php:180 sample-config.php:204 sample-config.php:237
307
+ #: sample-config.php:249 sample-config.php:267 sample-config.php:294
308
+ #: sample-config.php:311 sample-config.php:332 sample-config.php:343
309
+ #: sample-config.php:354 sample-config.php:375 sample-config.php:392
310
+ #: sample-config.php:408 sample-config.php:436 sample-config.php:450
311
+ #: sample-config.php:485 sample-config.php:524 sample-config.php:536
312
+ #: sample-config.php:548 sample-config.php:562
313
+ msgid "This is the control description"
314
+ msgstr "This is the control description"
315
+
316
+ #: sample-config.php:85 sample-config.php:102 sample-config.php:112
317
+ #: sample-config.php:129 sample-config.php:145 sample-config.php:161
318
+ #: sample-config.php:181 sample-config.php:205 sample-config.php:238
319
+ #: sample-config.php:250 sample-config.php:268 sample-config.php:295
320
+ #: sample-config.php:312 sample-config.php:333 sample-config.php:344
321
+ #: sample-config.php:355 sample-config.php:376 sample-config.php:393
322
+ #: sample-config.php:409 sample-config.php:437 sample-config.php:563
323
+ msgid ""
324
+ "This is some extra help. You can use this to add some additional "
325
+ "instructions for users. The main description should go in the \"description"
326
+ "\" of the field, this is only to be used for help tips."
327
+ msgstr ""
328
+ "This is some extra help. You can use this to add some additional "
329
+ "instructions for users. The main description should go in the \"description"
330
+ "\" of the field, this is only to be used for help tips."
331
+
332
+ #: sample-config.php:100
333
+ msgid "Dropdown Pages"
334
+ msgstr "Dropdown Pages"
335
+
336
+ #: sample-config.php:110
337
+ msgid "Select"
338
+ msgstr "Select"
339
+
340
+ #: sample-config.php:127
341
+ msgid "Radio-Image"
342
+ msgstr "Radio-Image"
343
+
344
+ #: sample-config.php:143
345
+ msgid "Radio-Buttonset"
346
+ msgstr "Radio-Buttonset"
347
+
348
+ #: sample-config.php:159
349
+ msgid "Multicheck"
350
+ msgstr "Multicheck"
351
+
352
+ #: sample-config.php:179
353
+ msgid "Sortable"
354
+ msgstr "Sortable"
355
+
356
+ #: sample-config.php:194
357
+ msgid "Option 5"
358
+ msgstr "Option 5"
359
+
360
+ #: sample-config.php:195
361
+ msgid "Option 6"
362
+ msgstr "Option 6"
363
+
364
+ #: sample-config.php:203
365
+ msgid "Palette"
366
+ msgstr "Palette"
367
+
368
+ #: sample-config.php:236
369
+ msgid "Palettes from Colourlovers"
370
+ msgstr "Palettes from Colourlovers"
371
+
372
+ #: sample-config.php:248
373
+ msgid "Select2"
374
+ msgstr "Select2"
375
+
376
+ #: sample-config.php:266
377
+ msgid "Select2 - multiple"
378
+ msgstr "Select2 - multiple"
379
+
380
+ #: sample-config.php:293 sample-config.php:310 sample-config.php:374
381
+ #: sample-config.php:391 sample-config.php:407 sample-config.php:435
382
+ #: sample-config.php:523 sample-config.php:535 sample-config.php:547
383
+ #: sample-config.php:561
384
+ msgid "This is the label"
385
+ msgstr "This is the label"
386
+
387
+ #: sample-config.php:331
388
+ msgid "Text"
389
+ msgstr "Text"
390
+
391
+ #: sample-config.php:342
392
+ msgid "Textarea"
393
+ msgstr "Textarea"
394
+
395
+ #: sample-config.php:353
396
+ msgid "Editor"
397
+ msgstr "Editor"
398
+
399
+ #: sample-config.php:449
400
+ msgid "Color Control"
401
+ msgstr "Color Control"
402
+
403
+ #: sample-config.php:451 sample-config.php:486 sample-config.php:525
404
+ #: sample-config.php:537 sample-config.php:549
405
+ msgid ""
406
+ "This is some extra help. You can use this to add some additional "
407
+ "instructions for users."
408
+ msgstr ""
409
+ "This is some extra help. You can use this to add some additional "
410
+ "instructions for users."
411
+
412
+ #: sample-config.php:484
413
+ msgid "Color-Alpha Control"
414
+ msgstr "Color-Alpha Control"
415
+
416
+ #: sample-config.php:585
417
+ msgid ""
418
+ "This is the theme description. You can edit it in the Kirki configuration "
419
+ "and add whatever you want here."
420
+ msgstr ""
421
+ "This is the theme description. You can edit it in the Kirki configuration "
422
+ "and add whatever you want here."
423
+
424
+ #: tests/test-kirki-scripts-frontend-google-fonts.php:9
425
+ msgid "Font Family"
426
+ msgstr "Font Family"
427
+
428
+ #: tests/test-kirki-scripts-frontend-google-fonts.php:25
429
+ msgid "Google-Font subsets"
430
+ msgstr "Google-Font subsets"
431
+
432
+ #: tests/test-kirki-scripts-frontend-google-fonts.php:26
433
+ msgid "The subsets used from Google's API."
434
+ msgstr "The subsets used from Google's API."
435
+
436
+ #: tests/test-kirki-scripts-frontend-google-fonts.php:42
437
+ msgid "Font Weight"
438
+ msgstr "Font Weight"
439
+
440
+ #: tests/test-kirki.php:55 tests/test-kirki.php:64 tests/test-kirki.php:73
441
+ #: tests/test-kirki.php:131
442
+ msgid "My custom control"
443
+ msgstr "My custom control"
444
+
445
+ #: tests/test-kirki.php:142
446
+ msgid "My custom control 2"
447
+ msgstr "My custom control 2"
448
+
449
+ #. Plugin Name of the plugin/theme
450
+ msgid "Kirki Toolkit"
451
+ msgstr "Kirki Toolkit"
452
+
453
+ #. Plugin URI of the plugin/theme
454
+ msgid "http://kirki.org"
455
+ msgstr "http://kirki.org"
456
+
457
+ #. Description of the plugin/theme
458
+ msgid "The ultimate WordPress Customizer Toolkit"
459
+ msgstr "The ultimate WordPress Customizer Toolkit"
460
+
461
+ #. Author of the plugin/theme
462
+ msgid "Aristeides Stathopoulos"
463
+ msgstr "Aristeides Stathopoulos"
464
+
465
+ #. Author URI of the plugin/theme
466
+ msgid "http://aristeides.com"
467
+ msgstr "http://aristeides.com"
package.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "kirki-toolkit",
3
+ "version": "1.0.0",
4
+ "author": "Aristeides Stathopoulos",
5
+ "homepage": "http://kirki.org",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/reduxframework/kirki"
9
+ },
10
+ "bugs": {
11
+ "url" : "https://github.com/reduxframework/kirki/issues"
12
+ },
13
+ "licenses": [{
14
+ "type": "GPL v2",
15
+ "url": "http://www.gnu.org/licenses/gpl-2.0.html"
16
+ }],
17
+ "engines": {
18
+ "node": ">= 0.10.0"
19
+ },
20
+ "devDependencies": {
21
+ "grunt": "~0.4.1",
22
+ "grunt-contrib-sass": "~0.9.0"
23
+ }
24
+ }
phpunit.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="tests/test-bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite>
11
+ <directory prefix="test-" suffix=".php">./tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ <logging>
15
+ <log type="coverage-clover" target="build/logs/clover.xml"/>
16
+ <log type="coverage-html" target="build/logs/html"/>
17
+ </logging>
18
+ </phpunit>
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Kirki ===
2
  Contributors: aristath, fovoc
3
- Tags: customizer, options famework, theme mods
4
  Donate link: http://kirki.org/
5
  Requires at least: 4.0
6
  Tested up to: 4.2
7
- Stable tag: 0.8.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -18,8 +18,6 @@ You can add beautiful options to your theme\'s customizer panel and allow your u
18
 
19
  Converting from the default customizer to the syntax used by Kirki will only take a few minutes and will save you a lot of time in the long run. :)
20
 
21
- **CAUTION**: This plugin requires PHP 5.3 and is not compatible with PHP 5.2
22
-
23
  The following controls are included:
24
 
25
  * Radio-Buttonset
@@ -43,8 +41,9 @@ The following controls are included:
43
  * Number
44
  * Palette
45
  * Editor (TinyMCE)
 
46
 
47
- For documentation and examples on how to use these controls, please visit [kirki.org](http://kirki.org/#fields).
48
 
49
 
50
  == Installation ==
@@ -53,188 +52,243 @@ For documentation and examples on how to use these controls, please visit [kirki
53
  From your dashboard go to Plugins => Add New.
54
  Search for "Kirki" and install it.
55
  Once you install it, activate it.
56
- For configuration instructions please visit http://kirki.org/#configuration
57
 
58
  **Method 2: Embed in your theme**
59
- Please visit http://kirki.org for documentation and instructions.
 
 
 
 
60
 
61
  == Changelog ==
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  = 0.8.4 =
64
 
65
  April 6, 2014, dev time: 0.5 hours
66
 
67
- * Fix: Color sanitization was distorting 0 characters in the color hex.
68
- * Fix: Properly sanitizing ColorAlpha controls
69
- * Fix: Sanitizing more properties in the Fields class
70
- * Fix: removing remnant double-sanitization calls from the controls classes
71
 
72
  = 0.8.3 =
73
 
74
  April 5, 2014, dev time: 28 hours
75
 
76
- * New: Introduce a Field class
77
- * New: Introduce a Builder class
78
- * Tweak: Code Cleanups
79
- * New: Added ability to use 'option' as the setting type
80
  * Fix : Bugs in the color calculation class
81
- * Tweak: Everything gets sanitized in the "Field" class
82
- * Fix: Bugs in sortable field
83
- * Fix: Editor control had no description
84
- * New: Added a color-alpha control. To use it just set an rgba color as the default value.
85
- * Tweak: SCSS & CSS improvements
86
- * Fix: Various PHP notices and warnings when no fields are defined
87
- * Tweak: More efficient color sanitization method
88
- * Tweak: Improved number control presentation
89
- * Tweak: Improved the way background fields are handled
90
- * Tweak: Checkboxes styling
91
- * New: Allow using rgba values for background colors
92
- * Fix: CSS fix - :focus color for active section
93
- * New: Add a static 'prepare' method to the ScriptRegistry class
94
- * Fix: Issues with the URL when Kirki is embedded in a theme
95
 
96
  = 0.8.2 =
97
 
98
  March 30, 2015, dev time: 5 minutes
99
 
100
- * Fix: Autoloader could not properly include files due to strtolower()
101
 
102
  = 0.8.1 =
103
 
104
  March 30, 2015, dev time: 30 minutes
105
 
106
- * Fix: Translation strings now overridable using the config filter.
107
 
108
  = 0.8.0 =
109
 
110
  March 30, 2015, dev time: 32 hours
111
 
112
  * Improvement: OOP redesign (props @vpratfr)
113
- * New: Added Palette control
114
- * New: Added Editor control (WYSIWYG - uses TinyMCE)
115
- * New: Added Custom control (free html)
116
- * New: Added a Kirki_Colourlovers class to use palettes from the colourlovers API
117
- * New: Added a composer file (props @vpratfr)
118
- * Fix: Wrong settings IDs
119
- * Fix: Color calculation on RGBA functions were off
120
- * Tweak: Restructuring the plugin (props @vpratfr)
121
- * New: added a functional kirki_get_option() function
122
- * Tweak: Simplified configuration options.
123
- * New: Turn Kirki into a singleton and a facade (props @vpratfr)
124
- * Tweak: Completely re-written the customizer styles
125
- * New: Using SASS for customizer styles
126
- * Tweak: Deprecating the group_title control in favor of the new custom control
127
- * Tweak: Changed the CSS for checkboxes
128
 
129
  = 0.7.1 =
130
 
131
  March 15, 2015, dev time: 2 hours
132
 
133
- * Removed: Remove the `kirki_get_option` function that was introduced in 0.7 as it's not working properly yet.
134
- * Fix: Undefined index notice when a default value for the control was not defined
135
- * Tweak: `logo_image` now injects an `img` element instead of a `div` with custom background
136
- * New: Added `description` argument in the kirki configuration (replaces the theme description)
137
 
138
  = 0.7 =
139
 
140
  March 14, 2015, dev time: 10 hours
141
 
142
- * Fix: Array to string conversion that happened conditionally when used with googlefonts. (props @groucho75)
143
- * Fix: Background opacity affects background-position of bg image
144
- * Fix: font-weight not being applied on google fonts
145
- * New: Added `kirki_get_option( $setting );` function that also gets default values
146
- * Tweak: Singleton for main plugin class
147
- * Fix: Prevent empty help tooltips
148
- * New: Added `toggle` control
149
- * New: Added `switch` control
150
- * Fix: Color controls were not being reset to default:
151
- * Tweak: Tooltips now loaded via jQuery
152
- * Tweak: Renamed `setting` to settings for consistency with WordPress core
153
- * Tweak: Renamed `description` to `help` and `subtitle` to `description for consistency with WordPress core
154
- * Tweak: Backwards-compatibility improvements
155
- * New: Allow hiding background control elements by not including default values for them
156
- * Tweak: Performance improvements
157
- * Tweak: Using WordPress core controls instead of custom ones when those are available
158
- * Tweak: Separate logic for multiple-type controls that were using the "mode" argument. This has been deprecated in favor of completely separate control types.
159
 
160
  = 0.6.2 =
161
 
162
  March 2, 2015, dev time: 3 hours
163
 
164
- * Fix: Frontend styles were not properly enqueued (props @dmgawel)
165
- * New: Allow multiple output styles per control defined as an array of arrays.
166
- * Fix: Background control styles
167
- * Fix: Serialise default values for the sortable control. Now you can define default values as an array.
168
- * Fix: Required script
169
- * Fix: \'_opacity\' was added to a lot of controls by mistake. Removed it and wrote a migration script.
170
 
171
  = 0.6.1 =
172
 
173
  February 25, 2015, dev time: 1 hours
174
 
175
- * Fix: Sortables controls had a JS conflict
176
- * Fix: Switches & Toggles were not properly working
177
 
178
  = 0.6.0 =
179
 
180
  February 25, 2015, dev time: 9 hours
181
 
182
- * Fix: Tooltips now properly working
183
- * New: Added checkbox switches
184
- * New: Added checkbox toggles
185
- * Fix: Generated CSS is not properly combined & minified
186
- * Fix: Re-structuring files hierarchy
187
- * Fix: Simplify the way controls are loaded
188
- * New: Only load control classes when they are needed
189
- * New: Introducing Kirki_Customize_Control class
190
- * Fix: CSS tweaks
191
- * New: Sortable control (creating one is identical to a select control, but with `\'type\' => \'sortable\'`)
192
- * Fix: Double output CSS (props @agusmu)
193
- * New: Google fonts now parsed from a json file.
194
 
195
  = 0.5.1 =
196
 
197
  January 22, 2015
198
 
199
- * Fix: Transport defaults to refresh instead of postMessage
200
- * Fix: undefined index notice.
201
 
202
  = 0.5 =
203
 
204
  January 21, 2015
205
 
206
- * New: Automatic output of styles for generic controls.
207
- * New: Automatic output of styles + scripts for fonts (including googlefonts )
208
- * New: The \'output\' argument on background controls is now an array for consistency with other controls. Older syntax is still compatible though. :)
209
- * New: Add the ability to auto-generate styles for colors.
210
- * Fix: Add a blank stylesheet if we need one and no stylesheet_id has been defined in the config options.
211
- * Fix: CSS-only tooltips. Fixes issue with tooltips now showing up on WP >= 4.1
212
- * Fix: Code cleanups
213
- * New: Added support for WordPress\'s transport arguments
214
- * Fix: All controls now have a sanitization callback. Users can override the default sanitizations by adding their own \'sanitize_callback\' argument.
215
- * Fix: OOP rewrite
216
- * Fix: Strip protocol from Google API link
217
- * Fix: Loading order for some files
218
- * Fix: Removed deprecated less_var argument
219
 
220
  = 0.4 =
221
 
222
  October 25, 2014
223
 
224
- * Fix: bugfix for selector
225
- * New: Change the Kirki theme based on which admin theme is selected.
226
- * Fix: Tranlsation domain issue
227
- * New: Added a \"group_title\" control
228
- * Fix: Updated the required script
229
- * Fix: Updating CSS
230
  * Other minor improvements and bugfixes
231
 
232
  = 0.3 =
233
 
234
  May 26, 2014
235
 
236
- * new: added background field
237
- * new: added \'output\' argument to directly output the CSS
238
 
239
  = 0.2 =
240
 
1
  === Kirki ===
2
  Contributors: aristath, fovoc
3
+ Tags: customizer, options framework, theme, mods, toolkit
4
  Donate link: http://kirki.org/
5
  Requires at least: 4.0
6
  Tested up to: 4.2
7
+ Stable tag: 1.0.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
18
 
19
  Converting from the default customizer to the syntax used by Kirki will only take a few minutes and will save you a lot of time in the long run. :)
20
 
 
 
21
  The following controls are included:
22
 
23
  * Radio-Buttonset
41
  * Number
42
  * Palette
43
  * Editor (TinyMCE)
44
+ * Select2
45
 
46
+ For documentation and examples on how to use these controls, please visit the [Kirki Wiki on Github](https://github.com/aristath/kirki/wiki).
47
 
48
 
49
  == Installation ==
52
  From your dashboard go to Plugins => Add New.
53
  Search for "Kirki" and install it.
54
  Once you install it, activate it.
55
+ For configuration instructions please visit the [Kirki Wiki on Github](https://github.com/aristath/kirki/wiki).
56
 
57
  **Method 2: Embed in your theme**
58
+ Please visit https://github.com/aristath/kirki/wiki/Embedding-in-a-theme for documentation and instructions.
59
+
60
+ == Sample Theme ==
61
+
62
+ To get an idea on how to include Kirki in your next project, a [sample theme](https://github.com/aristath/kirki/wiki/Sample-Theme-with-Kirki) has been created.
63
 
64
  == Changelog ==
65
 
66
+ = 1.0.0 =
67
+
68
+ July 11, 2014, dev time: 177 hours
69
+
70
+ * NEW: Added PHPUnit tests
71
+ * NEW: Use wp_add_inline_style to add customizer styles
72
+ * NEW: Rebuilt the background fields calculation
73
+ * NEW: Now using Formstone for switches & toggles
74
+ * NEW: Added a new API. See https://github.com/aristath/kirki/wiki for documentation.
75
+ * NEW: Minimum PHP requirement is now PHP 5.2
76
+ * NEW: Added a Select2 field type.
77
+ * NEW: Introducing the Kirki::get_option() method to get values.
78
+ * NEW: added 'media_query' argument to output.
79
+ * NEW: Added ability to get variables for CSS preprocessors from the customizer values. See https://github.com/aristath/kirki/wiki/variables for documentation
80
+ * NEW: now supporting 'units' to all outputs to support '!important'
81
+ * NEW: Ability to create panels & sections using the new API.
82
+ * NEW: added a get_posts method to the Kirki class.
83
+ * NEW: Implement width argument in the styling options. See https://github.com/aristath/kirki/wiki/Styling-the-Customizer
84
+ * NEW: add 'kirki/control_types' filter
85
+ * FIX: Properly saving values in the db when using serialized options
86
+ * FIX: Check if classes & functions exist before adding them (allows for better compatibility when embedded in a theme)
87
+ * FIX: PHP Warnings & Notices
88
+ * FIX: Other minor bugfixes
89
+ * FIX: Now using consistently `option_type` instead of `options_type` everywhere
90
+ * FIX: `Kirki::get_option()` method now works for all fields, including background fields.
91
+ * FIX: avoid errors when Color is undefined in background fields
92
+ * FIX: Use WP_Filesystem to get the google fonts array from a json file
93
+ * FIX: Radio-Button styling
94
+ * FIX: PHP Notices
95
+ * FIX: Typos
96
+ * FIX: Properly sanitizing rgba colors
97
+ * FIX: Properly sanitize numbers
98
+ * FIX: Make sure all variables are escaped on output
99
+ * TWEAK: Simplify the Colourlovers integration.
100
+ * TWEAK: Improve sanitization
101
+ * TWEAK: Improve the Kirki_Styles_Customizer class
102
+ * TWEAK: Code cleanups
103
+ * TWEAK: Added more inline docs (lots of them)
104
+ * TWEAK: Use active_callback for required arguments instead of custom JS
105
+ * TWEAK: Updated translation files
106
+ * TWEAK: Better color manipulation in the Kirki_Color class
107
+ * TWEAK: Move secondary classes instantiation to the Kirki() function.
108
+ * TWEAK: set a $kirki global
109
+ * TWEAK: deprecate getOrThrow method in the Kirki_Config class.
110
+ * TWEAK: Move sanitisation functions to a Kirki_Sanitize class.
111
+ * TWEAK: Rename Kirki_Framework to Kirki_Toolkit.
112
+ * TWEAK: Move variables to the new API
113
+ * TWEAK: simplify Kirki_Controls class
114
+ * TWEAK: move the kirki/fields & kirki/controls filters to the new API
115
+ * REMOVED: remove the 'stylesheet_id' from the configuration.
116
+
117
  = 0.8.4 =
118
 
119
  April 6, 2014, dev time: 0.5 hours
120
 
121
+ * FIX: Color sanitization was distorting 0 characters in the color hex.
122
+ * FIX: Properly sanitizing ColorAlpha controls
123
+ * FIX: Sanitizing more properties in the Fields class
124
+ * FIX: removing remnant double-sanitization calls from the controls classes
125
 
126
  = 0.8.3 =
127
 
128
  April 5, 2014, dev time: 28 hours
129
 
130
+ * NEW: Introduce a Field class
131
+ * NEW: Introduce a Builder class
132
+ * TWEAK: Code Cleanups
133
+ * NEW: Added ability to use 'option' as the setting type
134
  * Fix : Bugs in the color calculation class
135
+ * TWEAK: Everything gets sanitized in the "Field" class
136
+ * FIX: Bugs in sortable field
137
+ * FIX: Editor control had no description
138
+ * NEW: Added a color-alpha control. To use it just set an rgba color as the default value.
139
+ * TWEAK: SCSS & CSS improvements
140
+ * FIX: Various PHP notices and warnings when no fields are defined
141
+ * TWEAK: More efficient color sanitization method
142
+ * TWEAK: Improved number control presentation
143
+ * TWEAK: Improved the way background fields are handled
144
+ * TWEAK: Checkboxes styling
145
+ * NEW: Allow using rgba values for background colors
146
+ * FIX: CSS fix - :focus color for active section
147
+ * NEW: Add a static 'prepare' method to the ScriptRegistry class
148
+ * FIX: Issues with the URL when Kirki is embedded in a theme
149
 
150
  = 0.8.2 =
151
 
152
  March 30, 2015, dev time: 5 minutes
153
 
154
+ * FIX: Autoloader could not properly include files due to strtolower()
155
 
156
  = 0.8.1 =
157
 
158
  March 30, 2015, dev time: 30 minutes
159
 
160
+ * FIX: Translation strings now overridable using the config filter.
161
 
162
  = 0.8.0 =
163
 
164
  March 30, 2015, dev time: 32 hours
165
 
166
  * Improvement: OOP redesign (props @vpratfr)
167
+ * NEW: Added Palette control
168
+ * NEW: Added Editor control (WYSIWYG - uses TinyMCE)
169
+ * NEW: Added Custom control (free html)
170
+ * NEW: Added a Kirki_Colourlovers class to use palettes from the colourlovers API
171
+ * NEW: Added a composer file (props @vpratfr)
172
+ * FIX: Wrong settings IDs
173
+ * FIX: Color calculation on RGBA functions were off
174
+ * TWEAK: Restructuring the plugin (props @vpratfr)
175
+ * NEW: added a functional kirki_get_option() function
176
+ * TWEAK: Simplified configuration options.
177
+ * NEW: Turn Kirki into a singleton and a facade (props @vpratfr)
178
+ * TWEAK: Completely re-written the customizer styles
179
+ * NEW: Using SASS for customizer styles
180
+ * TWEAK: Deprecating the group_title control in favor of the new custom control
181
+ * TWEAK: Changed the CSS for checkboxes
182
 
183
  = 0.7.1 =
184
 
185
  March 15, 2015, dev time: 2 hours
186
 
187
+ * REMOVED: Remove the `kirki_get_option` function that was introduced in 0.7 as it's not working properly yet.
188
+ * FIX: Undefined index notice when a default value for the control was not defined
189
+ * TWEAK: `logo_image` now injects an `img` element instead of a `div` with custom background
190
+ * NEW: Added `description` argument in the kirki configuration (replaces the theme description)
191
 
192
  = 0.7 =
193
 
194
  March 14, 2015, dev time: 10 hours
195
 
196
+ * FIX: Array to string conversion that happened conditionally when used with googlefonts. (props @groucho75)
197
+ * FIX: Background opacity affects background-position of bg image
198
+ * FIX: font-weight not being applied on google fonts
199
+ * NEW: Added `kirki_get_option( $setting );` function that also gets default values
200
+ * TWEAK: Singleton for main plugin class
201
+ * FIX: Prevent empty help tooltips
202
+ * NEW: Added `toggle` control
203
+ * NEW: Added `switch` control
204
+ * FIX: Color controls were not being reset to default:
205
+ * TWEAK: Tooltips now loaded via jQuery
206
+ * TWEAK: Renamed `setting` to settings for consistency with WordPress core
207
+ * TWEAK: Renamed `description` to `help` and `subtitle` to `description for consistency with WordPress core
208
+ * TWEAK: Backwards-compatibility improvements
209
+ * NEW: Allow hiding background control elements by not including default values for them
210
+ * TWEAK: Performance improvements
211
+ * TWEAK: Using WordPress core controls instead of custom ones when those are available
212
+ * TWEAK: Separate logic for multiple-type controls that were using the "mode" argument. This has been deprecated in favor of completely separate control types.
213
 
214
  = 0.6.2 =
215
 
216
  March 2, 2015, dev time: 3 hours
217
 
218
+ * FIX: Frontend styles were not properly enqueued (props @dmgawel)
219
+ * NEW: Allow multiple output styles per control defined as an array of arrays.
220
+ * FIX: Background control styles
221
+ * FIX: Serialise default values for the sortable control. Now you can define default values as an array.
222
+ * FIX: Required script
223
+ * FIX: \'_opacity\' was added to a lot of controls by mistake. Removed it and wrote a migration script.
224
 
225
  = 0.6.1 =
226
 
227
  February 25, 2015, dev time: 1 hours
228
 
229
+ * FIX: Sortables controls had a JS conflict
230
+ * FIX: Switches & Toggles were not properly working
231
 
232
  = 0.6.0 =
233
 
234
  February 25, 2015, dev time: 9 hours
235
 
236
+ * FIX: Tooltips now properly working
237
+ * NEW: Added checkbox switches
238
+ * NEW: Added checkbox toggles
239
+ * FIX: Generated CSS is not properly combined & minified
240
+ * FIX: Re-structuring files hierarchy
241
+ * FIX: Simplify the way controls are loaded
242
+ * NEW: Only load control classes when they are needed
243
+ * NEW: Introducing Kirki_Customize_Control class
244
+ * FIX: CSS tweaks
245
+ * NEW: Sortable control (creating one is identical to a select control, but with `\'type\' => \'sortable\'`)
246
+ * FIX: Double output CSS (props @agusmu)
247
+ * NEW: Google fonts now parsed from a json file.
248
 
249
  = 0.5.1 =
250
 
251
  January 22, 2015
252
 
253
+ * FIX: Transport defaults to refresh instead of postMessage
254
+ * FIX: undefined index notice.
255
 
256
  = 0.5 =
257
 
258
  January 21, 2015
259
 
260
+ * NEW: Automatic output of styles for generic controls.
261
+ * NEW: Automatic output of styles + scripts for fonts (including googlefonts )
262
+ * NEW: The \'output\' argument on background controls is now an array for consistency with other controls. Older syntax is still compatible though. :)
263
+ * NEW: Add the ability to auto-generate styles for colors.
264
+ * FIX: Add a blank stylesheet if we need one and no stylesheet_id has been defined in the config options.
265
+ * FIX: CSS-only tooltips. Fixes issue with tooltips now showing up on WP >= 4.1
266
+ * FIX: Code cleanups
267
+ * NEW: Added support for WordPress\'s transport arguments
268
+ * FIX: All controls now have a sanitization callback. Users can override the default sanitizations by adding their own \'sanitize_callback\' argument.
269
+ * FIX: OOP rewrite
270
+ * FIX: Strip protocol from Google API link
271
+ * FIX: Loading order for some files
272
+ * FIX: Removed deprecated less_var argument
273
 
274
  = 0.4 =
275
 
276
  October 25, 2014
277
 
278
+ * FIX: bugfix for selector
279
+ * NEW: Change the Kirki theme based on which admin theme is selected.
280
+ * FIX: Tranlsation domain issue
281
+ * NEW: Added a \"group_title\" control
282
+ * FIX: Updated the required script
283
+ * FIX: Updating CSS
284
  * Other minor improvements and bugfixes
285
 
286
  = 0.3 =
287
 
288
  May 26, 2014
289
 
290
+ * NEW: added background field
291
+ * NEW: added \'output\' argument to directly output the CSS
292
 
293
  = 0.2 =
294
 
sample-config.php ADDED
@@ -0,0 +1,594 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Kirki Advanced Customizer
4
+ * This is a sample configuration file to demonstrate all fields & capabilities.
5
+ * @package Kirki
6
+ */
7
+
8
+ // Early exit if Kirki is not installed
9
+ if ( ! class_exists( 'Kirki' ) ) {
10
+ return;
11
+ }
12
+
13
+ /**
14
+ * Create sections using the WordPress Customizer API.
15
+ */
16
+ function kirki_demo_sections( $wp_customize ) {
17
+
18
+ /**
19
+ * Add sections
20
+ */
21
+ $wp_customize->add_section( 'controls_with_choices', array(
22
+ 'title' => __( 'Controls with Choices', 'kirki' ),
23
+ 'priority' => 10,
24
+ 'description' => __( 'This is the section description', 'kirki' ),
25
+ ) );
26
+
27
+ $wp_customize->add_section( 'color_section', array(
28
+ 'title' => __( 'Color Controls', 'kirki' ),
29
+ 'priority' => 10,
30
+ 'description' => __( 'This is the section description', 'kirki' ),
31
+ ) );
32
+
33
+ $wp_customize->add_section( 'file_controls_section', array(
34
+ 'title' => __( 'File & Image Controls', 'kirki' ),
35
+ 'priority' => 10,
36
+ 'description' => __( 'This is the section description', 'kirki' ),
37
+ ) );
38
+
39
+ $wp_customize->add_section( 'text_section', array(
40
+ 'title' => __( 'Text Control', 'kirki' ),
41
+ 'priority' => 10,
42
+ 'description' => __( 'This is the section description', 'kirki' ),
43
+ ) );
44
+
45
+ $wp_customize->add_section( 'background_section', array(
46
+ 'title' => __( 'Background Control', 'kirki' ),
47
+ 'priority' => 10,
48
+ 'description' => __( 'This is the section description', 'kirki' ),
49
+ ) );
50
+
51
+ $wp_customize->add_section( 'numeric', array(
52
+ 'title' => __( 'Numeric Controls', 'kirki' ),
53
+ 'priority' => 10,
54
+ 'description' => __( 'This is the section description', 'kirki' ),
55
+ ) );
56
+
57
+ $wp_customize->add_section( 'custom_section', array(
58
+ 'title' => __( 'Custom Control', 'kirki' ),
59
+ 'priority' => 10,
60
+ 'description' => __( 'This is the section description', 'kirki' ),
61
+ ) );
62
+
63
+ }
64
+ add_action( 'customize_register', 'kirki_demo_sections' );
65
+
66
+ /**
67
+ * Create panels using the Kirki API
68
+ */
69
+ Kirki::add_section( 'boolean_controls', array(
70
+ 'priority' => 10,
71
+ 'title' => __( 'Boolean Controls', 'kirki' ),
72
+ 'description' => __( 'This panel contains controls that return true/false Controls', 'kirki' ),
73
+ ) );
74
+
75
+ /**
76
+ * Add controls using the 'kirki/fields' filter.
77
+ */
78
+ function kirki_controls_with_choices_fields( $fields ) {
79
+
80
+ $fields[] = array(
81
+ 'type' => 'radio',
82
+ 'settings' => 'radio_demo',
83
+ 'label' => __( 'Radio Control', 'kirki' ),
84
+ 'description' => __( 'This is the control description', 'kirki' ),
85
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
86
+ 'section' => 'controls_with_choices',
87
+ 'default' => 'option-1',
88
+ 'priority' => 10,
89
+ 'choices' => array(
90
+ 'option-1' => __( 'Option 1', 'kirki' ),
91
+ 'option-2' => __( 'Option 2', 'kirki' ),
92
+ 'option-3' => __( 'Option 3', 'kirki' ),
93
+ 'option-4' => __( 'Option 4', 'kirki' ),
94
+ ),
95
+ );
96
+
97
+ $fields[] = array(
98
+ 'type' => 'dropdown-pages',
99
+ 'settings' => 'dropdown_pages_demo',
100
+ 'label' => __( 'Dropdown Pages', 'kirki' ),
101
+ 'description' => __( 'This is the control description', 'kirki' ),
102
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
103
+ 'section' => 'controls_with_choices',
104
+ 'priority' => 10,
105
+ );
106
+
107
+ $fields[] = array(
108
+ 'type' => 'select',
109
+ 'settings' => 'select_demo',
110
+ 'label' => __( 'Select', 'kirki' ),
111
+ 'description' => __( 'This is the control description', 'kirki' ),
112
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
113
+ 'section' => 'controls_with_choices',
114
+ 'default' => 'option-1',
115
+ 'priority' => 10,
116
+ 'choices' => array(
117
+ 'option-1' => __( 'Option 1', 'kirki' ),
118
+ 'option-2' => __( 'Option 2', 'kirki' ),
119
+ 'option-3' => __( 'Option 3', 'kirki' ),
120
+ 'option-4' => __( 'Option 4', 'kirki' ),
121
+ ),
122
+ );
123
+
124
+ $fields[] = array(
125
+ 'type' => 'radio-image',
126
+ 'settings' => 'radio_image_demo',
127
+ 'label' => __( 'Radio-Image', 'kirki' ),
128
+ 'description' => __( 'This is the control description', 'kirki' ),
129
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
130
+ 'section' => 'controls_with_choices',
131
+ 'default' => 'option-1',
132
+ 'priority' => 10,
133
+ 'choices' => array(
134
+ 'option-1' => admin_url().'/images/align-left-2x.png',
135
+ 'option-2' => admin_url().'/images/align-center-2x.png',
136
+ 'option-3' => admin_url().'/images/align-right-2x.png',
137
+ ),
138
+ );
139
+
140
+ $fields[] = array(
141
+ 'type' => 'radio-buttonset',
142
+ 'settings' => 'radio_buttonset_demo',
143
+ 'label' => __( 'Radio-Buttonset', 'kirki' ),
144
+ 'description' => __( 'This is the control description', 'kirki' ),
145
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
146
+ 'section' => 'controls_with_choices',
147
+ 'default' => 'option-1',
148
+ 'priority' => 10,
149
+ 'choices' => array(
150
+ 'option-1' => __( 'Option 1', 'kirki' ),
151
+ 'option-2' => __( 'Option 2', 'kirki' ),
152
+ 'option-3' => __( 'Option 3', 'kirki' ),
153
+ ),
154
+ );
155
+
156
+ $fields[] = array(
157
+ 'type' => 'multicheck',
158
+ 'settings' => 'multicheck_demo',
159
+ 'label' => __( 'Multicheck', 'kirki' ),
160
+ 'description' => __( 'This is the control description', 'kirki' ),
161
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
162
+ 'section' => 'controls_with_choices',
163
+ 'default' => array(
164
+ 'option-1',
165
+ 'option-2'
166
+ ),
167
+ 'priority' => 10,
168
+ 'choices' => array(
169
+ 'option-1' => __( 'Option 1', 'kirki' ),
170
+ 'option-2' => __( 'Option 2', 'kirki' ),
171
+ 'option-3' => __( 'Option 3', 'kirki' ),
172
+ 'option-4' => __( 'Option 4', 'kirki' ),
173
+ ),
174
+ );
175
+
176
+ $fields[] = array(
177
+ 'type' => 'sortable',
178
+ 'settings' => 'sortable_demo',
179
+ 'label' => __( 'Sortable', 'kirki' ),
180
+ 'description' => __( 'This is the control description', 'kirki' ),
181
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
182
+ 'section' => 'controls_with_choices',
183
+ 'default' => array(
184
+ 'option-3',
185
+ 'option-1',
186
+ 'option-4'
187
+ ),
188
+ 'priority' => 10,
189
+ 'choices' => array(
190
+ 'option-1' => __( 'Option 1', 'kirki' ),
191
+ 'option-2' => __( 'Option 2', 'kirki' ),
192
+ 'option-3' => __( 'Option 3', 'kirki' ),
193
+ 'option-4' => __( 'Option 4', 'kirki' ),
194
+ 'option-5' => __( 'Option 5', 'kirki' ),
195
+ 'option-6' => __( 'Option 6', 'kirki' ),
196
+ ),
197
+ );
198
+
199
+ // Define custom palettes
200
+ $fields[] = array(
201
+ 'type' => 'palette',
202
+ 'settings' => 'palette_demo',
203
+ 'label' => __( 'Palette', 'kirki' ),
204
+ 'description' => __( 'This is the control description', 'kirki' ),
205
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
206
+ 'section' => 'controls_with_choices',
207
+ 'default' => 'red',
208
+ 'priority' => 10,
209
+ 'choices' => array(
210
+ 'red' => array(
211
+ '#ef9a9a',
212
+ '#f44336',
213
+ '#ff1744',
214
+ ),
215
+ 'pink' => array(
216
+ '#fce4ec',
217
+ '#f06292',
218
+ '#e91e63',
219
+ '#ad1457',
220
+ '#f50057',
221
+ ),
222
+ 'cyan' => array(
223
+ '#e0f7fa',
224
+ '#80deea',
225
+ '#26c6da',
226
+ '#0097a7',
227
+ '#00e5ff',
228
+ ),
229
+ ),
230
+ );
231
+
232
+ // Define custom palettes
233
+ $fields[] = array(
234
+ 'type' => 'palette',
235
+ 'settings' => 'palette_demo_colourlovers',
236
+ 'label' => __( 'Palettes from Colourlovers', 'kirki' ),
237
+ 'description' => __( 'This is the control description', 'kirki' ),
238
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
239
+ 'section' => 'controls_with_choices',
240
+ 'default' => 'red',
241
+ 'priority' => 10,
242
+ 'choices' => Kirki_Colourlovers::get_palettes( 5 ),
243
+ );
244
+
245
+ $fields[] = array(
246
+ 'type' => 'select2',
247
+ 'settings' => 'select_demo_2',
248
+ 'label' => __( 'Select2', 'kirki' ),
249
+ 'description' => __( 'This is the control description', 'kirki' ),
250
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
251
+ 'section' => 'controls_with_choices',
252
+ 'default' => 'option-1',
253
+ 'priority' => 10,
254
+ 'choices' => Kirki_Fonts::get_font_choices(),
255
+ 'output' => array(
256
+ array(
257
+ 'element' => 'body p',
258
+ 'property' => 'font-family',
259
+ )
260
+ )
261
+ );
262
+
263
+ $fields[] = array(
264
+ 'type' => 'select2-multiple',
265
+ 'settings' => 'select_demo_3',
266
+ 'label' => __( 'Select2 - multiple', 'kirki' ),
267
+ 'description' => __( 'This is the control description', 'kirki' ),
268
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
269
+ 'section' => 'controls_with_choices',
270
+ 'default' => 'option-1',
271
+ 'priority' => 10,
272
+ 'choices' => array(
273
+ 'option-1' => __( 'Option 1', 'kirki' ),
274
+ 'option-2' => __( 'Option 2', 'kirki' ),
275
+ 'option-3' => __( 'Option 3', 'kirki' ),
276
+ 'option-4' => __( 'Option 4', 'kirki' ),
277
+ ),
278
+ );
279
+
280
+ return $fields;
281
+
282
+ }
283
+ add_filter( 'kirki/fields', 'kirki_controls_with_choices_fields' );
284
+
285
+ /**
286
+ * Add file controls
287
+ */
288
+ function kirki_file_controls_fields( $fields ) {
289
+
290
+ $fields[] = array(
291
+ 'type' => 'image',
292
+ 'settings' => 'image_demo',
293
+ 'label' => __( 'This is the label', 'kirki' ),
294
+ 'description' => __( 'This is the control description', 'kirki' ),
295
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
296
+ 'section' => 'file_controls_section',
297
+ 'default' => '',
298
+ 'priority' => 10,
299
+ 'output' => array(
300
+ array(
301
+ 'element' => 'p',
302
+ 'property' => 'background-image',
303
+ ),
304
+ ),
305
+ );
306
+
307
+ $fields[] = array(
308
+ 'type' => 'upload',
309
+ 'settings' => 'file_controls_section',
310
+ 'label' => __( 'This is the label', 'kirki' ),
311
+ 'description' => __( 'This is the control description', 'kirki' ),
312
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
313
+ 'section' => 'file_controls_section',
314
+ 'default' => '',
315
+ 'priority' => 10,
316
+ );
317
+
318
+ return $fields;
319
+
320
+ }
321
+ add_filter( 'kirki/fields', 'kirki_file_controls_fields' );
322
+
323
+ /**
324
+ * Add text fields
325
+ */
326
+ function kirki_text_controls_fields( $fields ) {
327
+
328
+ $fields[] = array(
329
+ 'type' => 'text',
330
+ 'settings' => 'text_demo',
331
+ 'label' => __( 'Text', 'kirki' ),
332
+ 'description' => __( 'This is the control description', 'kirki' ),
333
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
334
+ 'section' => 'text_section',
335
+ 'default' => 'This is some default text',
336
+ 'priority' => 10,
337
+ );
338
+
339
+ $fields[] = array(
340
+ 'type' => 'textarea',
341
+ 'settings' => 'textarea_demo',
342
+ 'label' => __( 'Textarea', 'kirki' ),
343
+ 'description' => __( 'This is the control description', 'kirki' ),
344
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
345
+ 'section' => 'text_section',
346
+ 'default' => 'This is some default text',
347
+ 'priority' => 10,
348
+ );
349
+
350
+ $fields[] = array(
351
+ 'type' => 'editor',
352
+ 'settings' => 'wysiwyg',
353
+ 'label' => __( 'Editor', 'kirki' ),
354
+ 'description' => __( 'This is the control description', 'kirki' ),
355
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
356
+ 'default' => '',
357
+ 'section' => 'text_section',
358
+ );
359
+
360
+ return $fields;
361
+
362
+ }
363
+ add_filter( 'kirki/fields', 'kirki_text_controls_fields' );
364
+
365
+ /**
366
+ * Add numeric fields
367
+ */
368
+ function kirki_numeric_fields( $fields ) {
369
+
370
+ // step = 10
371
+ $fields[] = array(
372
+ 'type' => 'slider',
373
+ 'settings' => 'slider_demo',
374
+ 'label' => __( 'This is the label', 'kirki' ),
375
+ 'description' => __( 'This is the control description', 'kirki' ),
376
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
377
+ 'section' => 'numeric',
378
+ 'default' => 20,
379
+ 'priority' => 10,
380
+ 'choices' => array(
381
+ 'min' => -100,
382
+ 'max' => 100,
383
+ 'step' => 10
384
+ ),
385
+ );
386
+
387
+ // step = 0.01
388
+ $fields[] = array(
389
+ 'type' => 'slider',
390
+ 'settings' => 'slider_demo_2',
391
+ 'label' => __( 'This is the label', 'kirki' ),
392
+ 'description' => __( 'This is the control description', 'kirki' ),
393
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
394
+ 'section' => 'numeric',
395
+ 'default' => 1.58,
396
+ 'priority' => 20,
397
+ 'choices' => array(
398
+ 'min' => 0,
399
+ 'max' => 5,
400
+ 'step' => .01
401
+ ),
402
+ );
403
+
404
+ $fields[] = array(
405
+ 'type' => 'number',
406
+ 'settings' => 'number_demo',
407
+ 'label' => __( 'This is the label', 'kirki' ),
408
+ 'description' => __( 'This is the control description', 'kirki' ),
409
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
410
+ 'section' => 'numeric',
411
+ 'default' => '42',
412
+ 'priority' => 10,
413
+ );
414
+
415
+ return $fields;
416
+
417
+ }
418
+ add_filter( 'kirki/fields', 'kirki_numeric_fields' );
419
+
420
+ /**
421
+ * Create a config instance that will be used by fields added via the static methods.
422
+ * For this example we'll be defining our options to be serialized in the db, under the 'kirki_demo' option.
423
+ */
424
+ Kirki::add_config( 'kirki_demo', array(
425
+ 'option_type' => 'option',
426
+ 'option_name' => 'kirki_demo'
427
+ ) );
428
+
429
+ /**
430
+ * Create Custom field using the Kirki API static functions
431
+ */
432
+ Kirki::add_field( 'kirki_demo', array(
433
+ 'type' => 'custom',
434
+ 'settings' => 'custom_demo',
435
+ 'label' => __( 'This is the label', 'kirki' ),
436
+ 'description' => __( 'This is the control description', 'kirki' ),
437
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
438
+ 'section' => 'custom_section',
439
+ 'default' => '<div style="padding: 30px;background-color: #333; color: #fff; border-radius: 50px;">You can enter custom markup in this control and use it however you want</div>',
440
+ 'priority' => 10,
441
+ ) );
442
+
443
+ /**
444
+ * Create Color fields using the Kirki API static functions
445
+ */
446
+ Kirki::add_field( 'kirki_demo', array(
447
+ 'type' => 'color',
448
+ 'settings' => 'color_demo',
449
+ 'label' => __( 'Color Control', 'kirki' ),
450
+ 'description' => __( 'This is the control description', 'kirki' ),
451
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users.', 'kirki' ),
452
+ 'section' => 'color_section',
453
+ 'default' => '#0088cc',
454
+ 'priority' => 10,
455
+ 'output' => array(
456
+ array(
457
+ 'element' => 'a, a:visited',
458
+ 'property' => 'color',
459
+ 'units' => ' !important'
460
+ ),
461
+ array(
462
+ 'element' => '#content',
463
+ 'property' => 'border-color'
464
+ ),
465
+ ),
466
+ 'transport' => 'postMessage',
467
+ 'js_vars' => array(
468
+ array(
469
+ 'element' => 'a, a:visited',
470
+ 'function' => 'css',
471
+ 'property' => 'color',
472
+ ),
473
+ array(
474
+ 'element' => '#content',
475
+ 'function' => 'css',
476
+ 'property' => 'background-color',
477
+ ),
478
+ )
479
+ ) );
480
+
481
+ Kirki::add_field( 'kirki_demo', array(
482
+ 'type' => 'color-alpha',
483
+ 'settings' => 'color_alpha_demo',
484
+ 'label' => __( 'Color-Alpha Control', 'kirki' ),
485
+ 'description' => __( 'This is the control description', 'kirki' ),
486
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users.', 'kirki' ),
487
+ 'section' => 'color_section',
488
+ 'default' => '#0088cc',
489
+ 'priority' => 10,
490
+ 'output' => array(
491
+ array(
492
+ 'element' => 'a, a:visited',
493
+ 'property' => 'color',
494
+ 'units' => ' !important'
495
+ ),
496
+ array(
497
+ 'element' => '#content',
498
+ 'property' => 'border-color'
499
+ ),
500
+ ),
501
+ 'transport' => 'postMessage',
502
+ 'js_vars' => array(
503
+ array(
504
+ 'element' => 'a, a:visited',
505
+ 'function' => 'css',
506
+ 'property' => 'color',
507
+ ),
508
+ array(
509
+ 'element' => '#content',
510
+ 'function' => 'css',
511
+ 'property' => 'background-color',
512
+ ),
513
+ )
514
+ ) );
515
+
516
+ /**
517
+ * Create Boolean fields using the Kirki API static functions
518
+ */
519
+ // Checkbox
520
+ Kirki::add_field( 'kirki_demo', array(
521
+ 'type' => 'checkbox',
522
+ 'settings' => 'checkbox_demo_0',
523
+ 'label' => __( 'This is the label', 'kirki' ),
524
+ 'description' => __( 'This is the control description', 'kirki' ),
525
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users.', 'kirki' ),
526
+ 'section' => 'boolean_controls',
527
+ 'default' => 1,
528
+ 'priority' => 10,
529
+ ) );
530
+
531
+ // Switch
532
+ Kirki::add_field( 'kirki_demo', array(
533
+ 'type' => 'switch',
534
+ 'settings' => 'switch_demo_0',
535
+ 'label' => __( 'This is the label', 'kirki' ),
536
+ 'description' => __( 'This is the control description', 'kirki' ),
537
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users.', 'kirki' ),
538
+ 'section' => 'boolean_controls',
539
+ 'default' => '1',
540
+ 'priority' => 10,
541
+ ) );
542
+
543
+ // Toggle
544
+ Kirki::add_field( 'kirki_demo', array(
545
+ 'type' => 'toggle',
546
+ 'settings' => 'toggle_demo_1',
547
+ 'label' => __( 'This is the label', 'kirki' ),
548
+ 'description' => __( 'This is the control description', 'kirki' ),
549
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users.', 'kirki' ),
550
+ 'section' => 'boolean_controls',
551
+ 'default' => 1,
552
+ 'priority' => 10,
553
+ ) );
554
+
555
+ /**
556
+ * Add the background field
557
+ */
558
+ Kirki::add_field( 'kirki_demo', array(
559
+ 'type' => 'background',
560
+ 'settings' => 'background_demo',
561
+ 'label' => __( 'This is the label', 'kirki' ),
562
+ 'description' => __( 'This is the control description', 'kirki' ),
563
+ 'help' => __( 'This is some extra help. You can use this to add some additional instructions for users. The main description should go in the "description" of the field, this is only to be used for help tips.', 'kirki' ),
564
+ 'section' => 'background_section',
565
+ 'default' => array(
566
+ 'color' => '#ffffff',
567
+ 'image' => '',
568
+ 'repeat' => 'no-repeat',
569
+ 'size' => 'cover',
570
+ 'attach' => 'fixed',
571
+ 'position' => 'left-top',
572
+ 'opacity' => 90,
573
+ ),
574
+ 'priority' => 10,
575
+ 'output' => '.hentry',
576
+ ) );
577
+
578
+ /**
579
+ * Configuration sample for the Kirki Customizer.
580
+ */
581
+ function kirki_demo_configuration_sample() {
582
+
583
+ $args = array(
584
+ 'logo_image' => 'http://kirki.org/img/kirki-new-logo-white.png',
585
+ 'description' => __( 'This is the theme description. You can edit it in the Kirki configuration and add whatever you want here.', 'kirki' ),
586
+ 'color_accent' => '#00bcd4',
587
+ 'color_back' => '#455a64',
588
+ );
589
+
590
+ return $args;
591
+
592
+ }
593
+
594
+ add_filter( 'kirki/config', 'kirki_demo_configuration_sample' );
tests/test-bootstrap.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $_tests_dir = getenv( 'WP_TESTS_DIR' );
4
+ if ( ! $_tests_dir ) {
5
+ $_tests_dir = '/tmp/wordpress-tests-lib';
6
+ }
7
+
8
+ require_once $_tests_dir . '/includes/functions.php';
9
+
10
+ function _manually_load_plugin() {
11
+ require dirname( dirname( __FILE__ ) ) . '/kirki.php';
12
+ }
13
+ tests_add_filter( 'after_setup_theme', '_manually_load_plugin' );
14
+
15
+ require $_tests_dir . '/includes/bootstrap.php';
tests/test-deprecated.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Deprecated extends WP_UnitTestCase {
4
+
5
+ public function add_theme_mod_field() {
6
+ Kirki::add_field( '', array(
7
+ 'type' => 'text',
8
+ 'settings' => 'the_mod_option',
9
+ 'section' => 'my_section',
10
+ 'default' => 'foo',
11
+ 'priority' => 20,
12
+ 'option_type' => 'theme_mod',
13
+ ) );
14
+ }
15
+
16
+ public function test_kirki_get_option() {
17
+ $this->add_theme_mod_field();
18
+ $this->assertEquals( 'foo', kirki_get_option( 'the_mod_option' ) );
19
+ set_theme_mod( 'the_mod_option', 'bar' );
20
+ $this->assertEquals( 'bar', kirki_get_option( 'the_mod_option' ) );
21
+ }
22
+
23
+ public function test_kirki_sanitize_hex() {
24
+ $random_color = str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
25
+ $this->assertEquals( kirki_sanitize_hex( $random_color ), Kirki_Color::sanitize_hex( $random_color ) );
26
+ }
27
+
28
+ public function test_kirki_get_rgb() {
29
+ $random_color = str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
30
+ $this->assertEquals( kirki_get_rgb( $random_color ), Kirki_Color::get_rgb( $random_color ) );
31
+ }
32
+
33
+ public function test_kirki_get_rgba() {
34
+ $random_color = str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
35
+ $this->assertEquals( kirki_get_rgba( $random_color ), Kirki_Color::get_rgba( $random_color ) );
36
+ }
37
+
38
+ public function test_kirki_get_brightness() {
39
+ $random_color = str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT) . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
40
+ $this->assertEquals( kirki_get_brightness( $random_color ), Kirki_Color::get_brightness( $random_color ) );
41
+ }
42
+
43
+ public function test_kirki_fonts() {
44
+ $this->assertEquals( Kirki_Fonts::get_all_fonts(), Kirki_Toolkit::fonts()->get_all_fonts() );
45
+ $this->assertEquals( Kirki_Fonts::get_font_choices(), Kirki_Toolkit::fonts()->get_font_choices() );
46
+ $this->assertEquals( Kirki_Fonts::is_google_font( 'Open Sans' ), Kirki_Toolkit::fonts()->is_google_font( 'Open Sans' ) );
47
+ $this->assertEquals( Kirki_Fonts::get_google_font_uri( array( 'Roboto' ) ), Kirki_Toolkit::fonts()->get_google_font_uri( array( 'Roboto' ) ) );
48
+ $this->assertEquals( Kirki_Fonts::get_google_font_subsets(), Kirki_Toolkit::fonts()->get_google_font_subsets() );
49
+ $this->assertEquals( Kirki_Fonts::choose_google_font_variants( 'Roboto' ), Kirki_Toolkit::fonts()->choose_google_font_variants( 'Roboto' ) );
50
+ $this->assertEquals( Kirki_Fonts::get_standard_fonts(), Kirki_Toolkit::fonts()->get_standard_fonts() );
51
+ $this->assertEquals( Kirki_Fonts::get_font_stack( '' ), Kirki_Toolkit::fonts()->get_font_stack( '' ) );
52
+ $this->assertEquals( Kirki_Fonts::sanitize_font_choice( '' ), Kirki_Toolkit::fonts()->sanitize_font_choice( '' ) );
53
+ $this->assertEquals( Kirki_Fonts::get_google_fonts(), Kirki_Toolkit::fonts()->get_google_fonts() );
54
+ }
55
+ }
tests/test-kirki-color.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Color extends WP_UnitTestCase {
4
+
5
+ public function test_hex_sanitize() {
6
+
7
+ /**
8
+ * White
9
+ */
10
+ // 1-letter hex
11
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'f' ) );
12
+ // 2-letter hex
13
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'ff' ) );
14
+ // 3-letter hex
15
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'fff' ) );
16
+ // 4-letter hex
17
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'ffff' ) );
18
+ // 5-letter hex
19
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'fffff' ) );
20
+ // 6-letter hex
21
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'ffffff' ) );
22
+ // 7-letter hex
23
+ $this->assertEquals( '#ffffff', Kirki_Color::sanitize_hex( 'fffffff' ) );
24
+
25
+ /**
26
+ * Black
27
+ */
28
+ // 1-letter hex
29
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '0' ) );
30
+ // 2-letter hex
31
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '00' ) );
32
+ // 3-letter hex
33
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '000' ) );
34
+ // 4-letter hex
35
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '0000' ) );
36
+ // 5-letter hex
37
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '00000' ) );
38
+ // 6-letter hex
39
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '000000' ) );
40
+ // 7-letter hex
41
+ $this->assertEquals( '#000000', Kirki_Color::sanitize_hex( '0000000' ) );
42
+
43
+ /**
44
+ * Invalid color characters
45
+ */
46
+ $this->assertEquals( '#ff8855', Kirki_Color::sanitize_hex( 'fg8p5m' ) );
47
+
48
+ }
49
+
50
+ public function test_get_rgb() {
51
+ /**
52
+ * White
53
+ */
54
+ $this->assertEquals( array( 255, 255, 255 ), Kirki_Color::get_rgb( '#ffffff' ) );
55
+ $this->assertEquals( '255,255,255', Kirki_Color::get_rgb( '#ffffff', true ) );
56
+ /**
57
+ * Black
58
+ */
59
+ $this->assertEquals( array( 0, 0, 0 ), Kirki_Color::get_rgb( '#000000' ) );
60
+ $this->assertEquals( '0,0,0', Kirki_Color::get_rgb( '#000000', true ) );
61
+ }
62
+
63
+ public function test_rgba2hex() {
64
+ /**
65
+ * White
66
+ */
67
+ $this->assertEquals( '#ffffff', Kirki_Color::rgba2hex( 'rgba(255,255,255,1)' ) );
68
+ $this->assertEquals( '#ffffff', Kirki_Color::rgba2hex( 'rgba(255,255,255,0)' ) );
69
+ $this->assertEquals( '#ffffff', Kirki_Color::rgba2hex( 'rgba( 255, 255, 255, 0 ) ' ) );
70
+ $this->assertEquals( true, ( '#ffffff' != Kirki_Color::rgba2hex( 'rgba(255,230,255,1)' ) ) );
71
+ /**
72
+ * Black
73
+ */
74
+ $this->assertEquals( '#000000', Kirki_Color::rgba2hex( 'rgba(0,0,0,1)' ) );
75
+ $this->assertEquals( '#000000', Kirki_Color::rgba2hex( 'rgba( 0, 0, 0, 1)' ) );
76
+ $this->assertEquals( true, ( '#000000' != Kirki_Color::rgba2hex( 'rgba(0,0,0,.1)' ) ) );
77
+ /**
78
+ * Opacity
79
+ */
80
+ $this->assertEquals( '#7f7f7f', Kirki_Color::rgba2hex( 'rgba(0,0,0,.5)' ) );
81
+ $this->assertEquals( '#ff7f7f', Kirki_Color::rgba2hex( 'rgba(255,0,0,.5)' ) );
82
+ $this->assertEquals( '#7fff7f', Kirki_Color::rgba2hex( 'rgba(0,255,0,.5)' ) );
83
+ $this->assertEquals( '#7f7fff', Kirki_Color::rgba2hex( 'rgba(0,0,255,.5)' ) );
84
+ /**
85
+ * invalid
86
+ */
87
+ $this->assertEquals( '#ffffff', Kirki_Color::rgba2hex( 'rgba(0,.5)' ) );
88
+ $this->assertEquals( '#ffffff', Kirki_Color::rgba2hex( '#ffffff' ) );
89
+ }
90
+
91
+ public function test_get_rgba() {
92
+ // White
93
+ $this->assertEquals( 'rgba(255,255,255,1)', Kirki_Color::get_rgba( '#ffffff', 1 ) );
94
+ $this->assertEquals( 'rgba(255,255,255,1)', Kirki_Color::get_rgba( '#ffffff', 100 ) );
95
+ // Transparent
96
+ $this->assertEquals( 'rgba(255,255,255,0)', Kirki_Color::get_rgba( '#ffffff', 0 ) );
97
+ // grey
98
+ $this->assertEquals( 'rgba(0,0,0,0.5)', Kirki_Color::get_rgba( '#000000', .5 ) );
99
+ // colors
100
+ $this->assertEquals( 'rgba(255,0,0,0.5)', Kirki_Color::get_rgba( '#ff0000', .5 ) );
101
+ $this->assertEquals( 'rgba(0,255,0,0.5)', Kirki_Color::get_rgba( '#00ff00', .5 ) );
102
+ $this->assertEquals( 'rgba(0,0,255,0.5)', Kirki_Color::get_rgba( '#0000ff', .5 ) );
103
+ }
104
+
105
+ public function test_get_brightness() {
106
+ $this->assertEquals( '0', Kirki_Color::get_brightness( '#000000' ) );
107
+ $this->assertEquals( '255', Kirki_Color::get_brightness( '#ffffff' ) );
108
+ $this->assertEquals( 127, Kirki_Color::get_brightness( '#7f7f7f' ) );
109
+ $this->assertEquals( 105, Kirki_Color::get_brightness( '#ff00ff' ) );
110
+ }
111
+
112
+ public function test_adjust_brightness() {
113
+ $this->assertEquals( '#ffffff', Kirki_Color::adjust_brightness( '#000000', 255 ) );
114
+ $this->assertEquals( '#000000', Kirki_Color::adjust_brightness( '#000000', 0 ) );
115
+ $this->assertEquals( '#ffffff', Kirki_Color::adjust_brightness( '#fff', 0 ) );
116
+ $this->assertEquals( '#000000', Kirki_Color::adjust_brightness( '#fff', -255 ) );
117
+ $this->assertEquals( '#7f7f7f', Kirki_Color::adjust_brightness( '#fff', (0 - 255/2) ) );
118
+ }
119
+
120
+ public function test_mix_colors() {
121
+ $this->assertEquals( '#ffffff', Kirki_Color::mix_colors( '#ffffff', 'fff', 100 ) );
122
+ $this->assertEquals( '#ffffff', Kirki_Color::mix_colors( '#ffffff', 'fff', 0 ) );
123
+ $this->assertEquals( '#ffffff', Kirki_Color::mix_colors( '#ffffff', 'fff', 37 ) );
124
+
125
+ $this->assertEquals( '#000000', Kirki_Color::mix_colors( '#000000', '000', 100 ) );
126
+ $this->assertEquals( '#000000', Kirki_Color::mix_colors( '#000000', '000', 0 ) );
127
+ $this->assertEquals( '#000000', Kirki_Color::mix_colors( '#000000', '0000', 37 ) );
128
+
129
+ $this->assertEquals( '#7f7f7f', Kirki_Color::mix_colors( '#ffffff', '000', 50 ) );
130
+ $this->assertEquals( '#7f7f7f', Kirki_Color::mix_colors( '#ffffff', '#000000', 50 ) );
131
+ $this->assertEquals( '#7f7f7f', Kirki_Color::mix_colors( '#000000', '#ffffff', 50 ) );
132
+ }
133
+
134
+ public function test_hex_to_hsv() {
135
+
136
+ $white = array( 'h' => 0, 's' => 0, 'v' => 1 );
137
+ $black = array( 'h' => 0, 's' => 0, 'v' => 0 );
138
+ $red = array( 'h' => 0, 's' => 1, 'v' => 1 );
139
+ $green = array( 'h' => 0.33, 's' => 1, 'v' => 1 );
140
+ $blue = array( 'h' => 0.67, 's' => 1, 'v' => 1 );
141
+
142
+ $this->assertEquals( $white, Kirki_Color::hex_to_hsv( '#ffffff' ) );
143
+ $this->assertEquals( $black, Kirki_Color::hex_to_hsv( '#000000' ) );
144
+ $this->assertEquals( $red, Kirki_Color::hex_to_hsv( '#ff0000' ) );
145
+ $this->assertEquals( $green, Kirki_Color::hex_to_hsv( '#00ff00' ) );
146
+ $this->assertEquals( $blue, Kirki_Color::hex_to_hsv( '#0000ff' ) );
147
+ }
148
+
149
+ public function test_rgb_to_hsv() {
150
+
151
+ $white = array( 'h' => 0, 's' => 0, 'v' => 1 );
152
+ $black = array( 'h' => 0, 's' => 0, 'v' => 0 );
153
+ $red = array( 'h' => 0, 's' => 1, 'v' => 1 );
154
+ $green = array( 'h' => 0.33, 's' => 1, 'v' => 1 );
155
+ $blue = array( 'h' => 0.67, 's' => 1, 'v' => 1 );
156
+
157
+ $this->assertEquals( $white, Kirki_Color::rgb_to_hsv( array( 255, 255, 255 ) ) );
158
+ $this->assertEquals( $black, Kirki_Color::rgb_to_hsv( array( 0, 0, 0 ) ) );
159
+ $this->assertEquals( $red, Kirki_Color::rgb_to_hsv( array( 255, 0, 0 ) ) );
160
+ $this->assertEquals( $green, Kirki_Color::rgb_to_hsv( array( 0, 255, 0 ) ) );
161
+ $this->assertEquals( $blue, Kirki_Color::rgb_to_hsv( array( 0, 0, 255 ) ) );
162
+ }
163
+
164
+ public function test_color_difference() {
165
+ $this->assertEquals( '0', Kirki_Color::color_difference( 'fff', '#ffffff' ) );
166
+ $this->assertEquals( '765', Kirki_Color::color_difference( 'fff', '000' ) );
167
+ $this->assertEquals( '765', Kirki_Color::color_difference( '#000000', '#ffffff' ) );
168
+ $this->assertEquals( '522', Kirki_Color::color_difference( '#f2f2f2', '#c00' ) );
169
+ $this->assertEquals( '39', Kirki_Color::color_difference( '#f2f2f2', '#ffffff' ) );
170
+ }
171
+
172
+ public function test_brightness_difference() {
173
+ $this->assertEquals( '0', Kirki_Color::brightness_difference( 'fff', '#ffffff' ) );
174
+ $this->assertEquals( '255', Kirki_Color::brightness_difference( 'fff', '000' ) );
175
+ $this->assertEquals( '255', Kirki_Color::brightness_difference( '#000000', '#ffffff' ) );
176
+ $this->assertEquals( '181', Kirki_Color::brightness_difference( '#f2f2f2', '#c00' ) );
177
+ $this->assertEquals( '13', Kirki_Color::brightness_difference( '#f2f2f2', '#ffffff' ) );
178
+ }
179
+
180
+ public function test_lumosity_difference() {
181
+ $this->assertEquals( '1', Kirki_Color::lumosity_difference( 'fff', '#ffffff' ) );
182
+ $this->assertEquals( '21', Kirki_Color::lumosity_difference( 'fff', '000' ) );
183
+ $this->assertEquals( '21', Kirki_Color::lumosity_difference( '#000000', '#ffffff' ) );
184
+ $this->assertEquals( '5.23', Kirki_Color::lumosity_difference( '#f2f2f2', '#c00' ) );
185
+ $this->assertEquals( '1.12', Kirki_Color::lumosity_difference( '#f2f2f2', '#ffffff' ) );
186
+ }
187
+
188
+ }
tests/test-kirki-explode-background-field.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Explode_Background_Field extends WP_UnitTestCase {
4
+
5
+ public function initial_fields() {
6
+ return array( array(
7
+ 'type' => 'background',
8
+ 'settings' => 'my_setting',
9
+ 'label' => 'Control Title',
10
+ 'section' => 'my_section',
11
+ 'default' => array(
12
+ 'image' => 'http://example.com/foo.png',
13
+ 'color' => 'rgba(255,230,34,1)',
14
+ 'repeat' => 'no-repeat',
15
+ 'size' => 'cover',
16
+ 'attach' => 'fixed',
17
+ 'position' => 'left-top',
18
+ 'opacity' => 1
19
+ ),
20
+ 'priority' => 20,
21
+ 'output' => 'body',
22
+ ) );
23
+ }
24
+
25
+ public function final_fields() {
26
+ $initial_fields = $this->initial_fields();
27
+ return array(
28
+ $initial_fields[0],
29
+ 'my_setting_color' => array(
30
+ 'type' => 'color-alpha',
31
+ 'label' => '',
32
+ 'section' => 'my_section',
33
+ 'settings' => 'my_setting_color',
34
+ 'priority' => 20,
35
+ 'help' => '',
36
+ 'description' => 'Background Color',
37
+ 'required' => null,
38
+ 'transport' => 'refresh',
39
+ 'default' => 'rgba(255,230,34,1)',
40
+ 'output' => array(
41
+ array(
42
+ 'element' => 'body',
43
+ 'property' => 'background-color',
44
+ ),
45
+ ),
46
+ 'settings_raw' => 'my_setting',
47
+ 'option_type' => 'theme_mod',
48
+ 'choices' => array(),
49
+ 'sanitize_callback' => array( 'Kirki_Sanitize', 'color' ),
50
+ 'js_vars' => null,
51
+ 'id' => 'my_setting_color',
52
+ 'capability' => 'edit_theme_options',
53
+ 'variables' => false,
54
+ 'active_callback' => '__return_true',
55
+ ),
56
+ 'my_setting_image' => array(
57
+ 'type' => 'image',
58
+ 'label' => 'Control Title',
59
+ 'section' => 'my_section',
60
+ 'settings' => 'my_setting_image',
61
+ 'priority' => 20,
62
+ 'help' => '',
63
+ 'description' => 'Background Image',
64
+ 'required' => null,
65
+ 'transport' => 'refresh',
66
+ 'default' => 'http://example.com/foo.png',
67
+ 'output' => array(
68
+ array(
69
+ 'element' => 'body',
70
+ 'property' => 'background-image',
71
+ ),
72
+ ),
73
+ 'settings_raw' => 'my_setting',
74
+ 'option_type' => 'theme_mod',
75
+ 'choices' => array(),
76
+ 'sanitize_callback' => 'esc_url_raw',
77
+ 'js_vars' => null,
78
+ 'id' => 'my_setting_image',
79
+ 'capability' => 'edit_theme_options',
80
+ 'variables' => false,
81
+ 'active_callback' => '__return_true',
82
+ ),
83
+ 'my_setting_repeat' => array(
84
+ 'type' => 'select',
85
+ 'label' => '',
86
+ 'section' => 'my_section',
87
+ 'settings' => 'my_setting_repeat',
88
+ 'priority' => 20,
89
+ 'choices' => array(
90
+ 'no-repeat' => 'No Repeat',
91
+ 'repeat' => 'Repeat All',
92
+ 'repeat-x' => 'Repeat Horizontally',
93
+ 'repeat-y' => 'Repeat Vertically',
94
+ 'inherit' => 'Inherit',
95
+ ),
96
+ 'help' => '',
97
+ 'description' => 'Background Repeat',
98
+ 'required' => null,
99
+ 'transport' => 'refresh',
100
+ 'default' => 'no-repeat',
101
+ 'output' => array(
102
+ array(
103
+ 'element' => 'body',
104
+ 'property' => 'background-repeat',
105
+ ),
106
+ ),
107
+ 'settings_raw' => 'my_setting',
108
+ 'option_type' => 'theme_mod',
109
+ 'sanitize_callback' => 'esc_attr',
110
+ 'js_vars' => null,
111
+ 'id' => 'my_setting_repeat',
112
+ 'capability' => 'edit_theme_options',
113
+ 'variables' => false,
114
+ 'active_callback' => '__return_true',
115
+ ),
116
+ 'my_setting_size' => array(
117
+ 'type' => 'select',
118
+ 'label' => '',
119
+ 'section' => 'my_section',
120
+ 'settings' => 'my_setting_size',
121
+ 'priority' => 20,
122
+ 'choices' => array(
123
+ 'inherit' => 'Inherit',
124
+ 'cover' => 'Cover',
125
+ 'contain' => 'Contain',
126
+ ),
127
+ 'help' => '',
128
+ 'description' => 'Background Size',
129
+ 'required' => null,
130
+ 'transport' => 'refresh',
131
+ 'default' => 'cover',
132
+ 'output' => array(
133
+ array(
134
+ 'element' => 'body',
135
+ 'property' => 'background-size',
136
+ ),
137
+ ),
138
+ 'settings_raw' => 'my_setting',
139
+ 'option_type' => 'theme_mod',
140
+ 'sanitize_callback' => 'esc_attr',
141
+ 'js_vars' => null,
142
+ 'id' => 'my_setting_size',
143
+ 'capability' => 'edit_theme_options',
144
+ 'variables' => false,
145
+ 'active_callback' => '__return_true',
146
+ ),
147
+ 'my_setting_attach' => array(
148
+ 'type' => 'select',
149
+ 'label' => '',
150
+ 'section' => 'my_section',
151
+ 'settings' => 'my_setting_attach',
152
+ 'priority' => 20,
153
+ 'choices' => array(
154
+ 'inherit' => 'Inherit',
155
+ 'fixed' => 'Fixed',
156
+ 'scroll' => 'Scroll',
157
+ ),
158
+ 'help' => '',
159
+ 'description' => 'Background Attachment',
160
+ 'required' => null,
161
+ 'transport' => 'refresh',
162
+ 'default' => 'fixed',
163
+ 'output' => array(
164
+ array(
165
+ 'element' => 'body',
166
+ 'property' => 'background-attachment',
167
+ ),
168
+ ),
169
+ 'settings_raw' => 'my_setting',
170
+ 'option_type' => 'theme_mod',
171
+ 'sanitize_callback' => 'esc_attr',
172
+ 'js_vars' => null,
173
+ 'id' => 'my_setting_attach',
174
+ 'capability' => 'edit_theme_options',
175
+ 'variables' => false,
176
+ 'active_callback' => '__return_true',
177
+ ),
178
+ 'my_setting_position' => array(
179
+ 'type' => 'select',
180
+ 'label' => '',
181
+ 'section' => 'my_section',
182
+ 'settings' => 'my_setting_position',
183
+ 'priority' => 20,
184
+ 'choices' => array(
185
+ 'left-top' => 'Left Top',
186
+ 'left-center' => 'Left Center',
187
+ 'left-bottom' => 'Left Bottom',
188
+ 'right-top' => 'Right Top',
189
+ 'right-center' => 'Right Center',
190
+ 'right-bottom' => 'Right Bottom',
191
+ 'center-top' => 'Center Top',
192
+ 'center-center' => 'Center Center',
193
+ 'center-bottom' => 'Center Bottom',
194
+ ),
195
+ 'help' => '',
196
+ 'description' => 'Background Position',
197
+ 'required' => null,
198
+ 'transport' => 'refresh',
199
+ 'default' => 'left-top',
200
+ 'output' => array(
201
+ array(
202
+ 'element' => 'body',
203
+ 'property' => 'background-position',
204
+ ),
205
+ ),
206
+ 'settings_raw' => 'my_setting',
207
+ 'option_type' => 'theme_mod',
208
+ 'sanitize_callback' => 'esc_attr',
209
+ 'js_vars' => null,
210
+ 'id' => 'my_setting_position',
211
+ 'capability' => 'edit_theme_options',
212
+ 'variables' => false,
213
+ 'active_callback' => '__return_true',
214
+ )
215
+ );
216
+ }
217
+
218
+ public function test_build_background_fields() {
219
+ $this->assertEquals( $this->final_fields(), Kirki_Explode_Background_Field::process_fields( $this->initial_fields() ) );
220
+ }
221
+
222
+ }
tests/test-kirki-field.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Field extends WP_UnitTestCase {
4
+
5
+ public function test_sanitize_control_type() {
6
+
7
+ $this->assertEquals( 'checkbox', Kirki_Field::sanitize_control_type( array( 'type' => 'checkbox' ) ) );
8
+
9
+ $this->assertEquals( 'color-alpha', Kirki_Field::sanitize_control_type( array( 'type' => 'color-alpha' ) ) );
10
+ $this->assertEquals( 'color-alpha', Kirki_Field::sanitize_control_type( array( 'type' => 'color_alpha' ) ) );
11
+ $this->assertEquals( 'color-alpha', Kirki_Field::sanitize_control_type( array( 'type' => 'color', 'default' => 'rgba(0,0,0,1)' ) ) );
12
+ $this->assertEquals( 'color', Kirki_Field::sanitize_control_type( array( 'type' => 'color' ) ) );
13
+ $this->assertEquals( 'custom', Kirki_Field::sanitize_control_type( array( 'type' => 'custom' ) ) );
14
+ $this->assertEquals( 'custom', Kirki_Field::sanitize_control_type( array( 'type' => 'group-title' ) ) );
15
+ $this->assertEquals( 'custom', Kirki_Field::sanitize_control_type( array( 'type' => 'group_title' ) ) );
16
+ $this->assertEquals( 'dropdown-pages', Kirki_Field::sanitize_control_type( array( 'type' => 'dropdown-pages' ) ) );
17
+ $this->assertEquals( 'editor', Kirki_Field::sanitize_control_type( array( 'type' => 'editor' ) ) );
18
+ $this->assertEquals( 'image', Kirki_Field::sanitize_control_type( array( 'type' => 'image' ) ) );
19
+ $this->assertEquals( 'multicheck', Kirki_Field::sanitize_control_type( array( 'type' => 'multicheck' ) ) );
20
+ $this->assertEquals( 'number', Kirki_Field::sanitize_control_type( array( 'type' => 'number' ) ) );
21
+ $this->assertEquals( 'palette', Kirki_Field::sanitize_control_type( array( 'type' => 'palette' ) ) );
22
+ $this->assertEquals( 'radio-buttonset', Kirki_Field::sanitize_control_type( array( 'type' => 'radio-buttonset' ) ) );
23
+ $this->assertEquals( 'radio-buttonset', Kirki_Field::sanitize_control_type( array( 'type' => 'radio', 'mode' => 'buttonset' ) ) );
24
+ $this->assertEquals( 'radio-image', Kirki_Field::sanitize_control_type( array( 'type' => 'radio-image' ) ) );
25
+ $this->assertEquals( 'radio-image', Kirki_Field::sanitize_control_type( array( 'type' => 'radio', 'mode' => 'image' ) ) );
26
+ $this->assertEquals( 'radio', Kirki_Field::sanitize_control_type( array( 'type' => 'radio' ) ) );
27
+ $this->assertEquals( 'select', Kirki_Field::sanitize_control_type( array( 'type' => 'select' ) ) );
28
+ $this->assertEquals( 'slider', Kirki_Field::sanitize_control_type( array( 'type' => 'slider' ) ) );
29
+ $this->assertEquals( 'sortable', Kirki_Field::sanitize_control_type( array( 'type' => 'sortable' ) ) );
30
+ $this->assertEquals( 'switch', Kirki_Field::sanitize_control_type( array( 'type' => 'switch' ) ) );
31
+ $this->assertEquals( 'switch', Kirki_Field::sanitize_control_type( array( 'type' => 'checkbox', 'mode' => 'switch' ) ) );
32
+ $this->assertEquals( 'text', Kirki_Field::sanitize_control_type( array( 'type' => 'text' ) ) );
33
+ $this->assertEquals( 'textarea', Kirki_Field::sanitize_control_type( array( 'type' => 'textarea' ) ) );
34
+ $this->assertEquals( 'toggle', Kirki_Field::sanitize_control_type( array( 'type' => 'toggle' ) ) );
35
+ $this->assertEquals( 'toggle', Kirki_Field::sanitize_control_type( array( 'type' => 'checkbox', 'mode' => 'toggle' ) ) );
36
+ $this->assertEquals( 'upload', Kirki_Field::sanitize_control_type( array( 'type' => 'upload' ) ) );
37
+
38
+ $this->assertEquals( 'text', Kirki_Field::sanitize_control_type( array() ) );
39
+
40
+ }
41
+
42
+ public function test_sanitize_field() {
43
+ $this->assertEquals(
44
+ array(
45
+ 'settings' => 'foo',
46
+ 'section' => 'foo',
47
+ 'type' => 'text',
48
+ 'settings_raw' => 'foo',
49
+ 'default' => '',
50
+ 'label' => '',
51
+ 'help' => '',
52
+ 'description' => '',
53
+ 'required' => null,
54
+ 'transport' => 'refresh',
55
+ 'option_type' => 'theme_mod',
56
+ 'priority' => 10,
57
+ 'choices' => array(),
58
+ 'output' => null,
59
+ 'sanitize_callback' => 'esc_textarea',
60
+ 'js_vars' => null,
61
+ 'id' => 'foo',
62
+ 'capability' => 'edit_theme_options',
63
+ 'variables' => false,
64
+ 'active_callback' => '__return_true',
65
+ ),
66
+ Kirki_Field::sanitize_field( array(
67
+ 'settings' => 'foo',
68
+ 'section' => 'foo',
69
+ 'type' => 'text',
70
+ ) ) );
71
+ }
72
+
73
+ public function test_sanitize_type() {
74
+ $this->assertEquals( 'theme_mod', Kirki_Field::sanitize_type( array( 'option_type' => 'theme_mod' ) ) );
75
+ $this->assertEquals( 'option', Kirki_Field::sanitize_type( array( 'option_type' => 'option' ) ) );
76
+ $this->assertEquals( 'theme_mod', Kirki_Field::sanitize_type( array() ) );
77
+ add_filter( 'kirki/config', function() {
78
+ return array(
79
+ 'option_type' => 'option',
80
+ );
81
+ });
82
+ $this->assertEquals( 'option', Kirki_Field::sanitize_type( array() ) );
83
+ }
84
+
85
+ public function test_sanitize_variables() {
86
+ $this->assertEquals( false, Kirki_Field::sanitize_variables( array() ) );
87
+ $this->assertEquals( array(), Kirki_Field::sanitize_variables( array( 'variables' => array() ) ) );
88
+ }
89
+
90
+ public function test_sanitize_active_callback() {
91
+ $this->assertEquals( '__return_true', Kirki_Field::sanitize_active_callback( array( 'active_callback' => '__return_true' ) ) );
92
+ $this->assertEquals( '__return_true', Kirki_Field::sanitize_active_callback( array() ) );
93
+ $this->assertEquals( 'kirki_active_callback', Kirki_Field::sanitize_active_callback( array( 'required' => array() ) ) );
94
+ }
95
+
96
+ public function test_sanitize_capability() {
97
+ $capabilities = array(
98
+ 'activate_plugins',
99
+ 'delete_others_pages',
100
+ 'delete_others_posts',
101
+ 'delete_pages',
102
+ 'delete_posts',
103
+ 'delete_private_pages',
104
+ 'delete_private_posts',
105
+ 'delete_published_pages',
106
+ 'delete_published_posts',
107
+ 'edit_dashboard',
108
+ 'edit_others_pages',
109
+ 'edit_others_posts',
110
+ 'edit_pages',
111
+ 'edit_posts',
112
+ 'edit_private_pages',
113
+ 'edit_private_posts',
114
+ 'edit_published_pages',
115
+ 'edit_published_posts',
116
+ 'edit_theme_options',
117
+ 'export',
118
+ 'import',
119
+ 'list_users',
120
+ 'manage_categories',
121
+ 'manage_links',
122
+ 'manage_options',
123
+ 'moderate_comments',
124
+ 'promote_users',
125
+ 'publish_pages',
126
+ 'publish_posts',
127
+ 'read_private_pages',
128
+ 'read_private_posts',
129
+ 'read',
130
+ );
131
+ foreach ( $capabilities as $capability ) {
132
+ $this->assertEquals( $capability, Kirki_Field::sanitize_capability( array( 'capability' => $capability ) ) );
133
+ }
134
+
135
+ $this->assertEquals( 'edit_theme_options', Kirki_Field::sanitize_capability( array() ) );
136
+
137
+ add_filter( 'kirki/config', function() {
138
+ return array(
139
+ 'capability' => 'activate_plugins',
140
+ );
141
+ });
142
+ $this->assertEquals( 'activate_plugins', Kirki_Field::sanitize_capability( array() ) );
143
+ }
144
+
145
+ public function test_sanitize_settings_raw() {
146
+ $this->assertEquals( 'my_settingsub-setting', Kirki_Field::sanitize_settings_raw( array( 'settings' => 'my_setting[sub-setting]' ) ) );
147
+ $this->assertEquals( 'my_settingsub-setting', Kirki_Field::sanitize_settings_raw( array( 'settings' => 'my_setting["sub-setting"]' ) ) );
148
+ $this->assertEquals( 'my_settingsub-setting', Kirki_Field::sanitize_settings_raw( array( 'settings' => 'my_setting sub-setting' ) ) );
149
+
150
+ $this->assertEquals( 'my_settingsub-setting', Kirki_Field::sanitize_settings_raw( array( 'setting' => 'my_setting sub-setting' ) ) );
151
+ }
152
+
153
+ public function test_sanitize_settings() {
154
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_settings( array( 'settings' => 'foo' ) ) );
155
+ $this->assertEquals( 'foo[bar]', Kirki_Field::sanitize_settings( array( 'settings' => 'bar', 'option_type' => 'option', 'option_name' => 'foo' ) ) );
156
+ $this->assertEquals( 'foo[bar]', Kirki_Field::sanitize_settings( array( 'settings' => 'foo[bar]' ) ) );
157
+ }
158
+
159
+ public function test_sanitize_label() {
160
+ $this->assertEquals( 'This is my LABEL', Kirki_Field::sanitize_label( array( 'label' => 'This is my LABEL' ) ) );
161
+ }
162
+
163
+ public function test_sanitize_section() {
164
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_section( array( 'section' => 'foo' ) ) );
165
+ $this->assertEquals( 'title_tagline', Kirki_Field::sanitize_section( array() ) );
166
+ }
167
+
168
+ public function test_sanitize_id() {
169
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_id( array( 'settings' => 'foo' ) ) );
170
+ $this->assertEquals( 'foo-bar', Kirki_Field::sanitize_id( array( 'settings' => 'foo[bar]' ) ) );
171
+ $this->assertEquals( 'foo-bar', Kirki_Field::sanitize_id( array( 'settings' => 'foo[ bar ]' ) ) );
172
+ }
173
+
174
+ public function test_sanitize_default() {
175
+ $this->assertEquals( '<div class="foo">bar</div>', Kirki_Field::sanitize_default( array( 'type' => 'custom', 'default' => '<div class="foo">bar</div>' ) ) );
176
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_default( array( 'default' => 'foo' ) ) );
177
+ $this->assertEquals( array( 'foo', 'bar' ), Kirki_Field::sanitize_default( array( 'default' => array( 'foo', 'bar' ) ) ) );
178
+ $this->assertEquals( 'rgba(0,0,0,0)', Kirki_Field::sanitize_default( array( 'default' => 'rgba(0,0,0,0)' ) ) );
179
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_default( array( 'type' => 'text', 'default' => 'foo', ) ) );
180
+ }
181
+
182
+ public function test_sanitize_description() {
183
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_description( array( 'description' => 'foo' ) ) );
184
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_description( array( 'subtitle' => 'foo' ) ) );
185
+ $this->assertEquals( 'bar', Kirki_Field::sanitize_description( array( 'description' => '<div class="foo">bar</div>' ) ) );
186
+ $this->assertEquals( '', Kirki_Field::sanitize_description( array() ) );
187
+ }
188
+
189
+ public function test_sanitize_help() {
190
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_help( array( 'help' => 'foo' ) ) );
191
+ $this->assertEquals( 'bar', Kirki_Field::sanitize_help( array( 'subtitle' => 'foo', 'description' => 'bar' ) ) );
192
+ $this->assertEquals( 'bar', Kirki_Field::sanitize_help( array( 'help' => '<div class="foo">bar</div>' ) ) );
193
+ $this->assertEquals( '', Kirki_Field::sanitize_help( array( 'subtitle' => 'foo' ) ) );
194
+ }
195
+
196
+ public function test_sanitize_choices() {
197
+ $this->assertEquals(
198
+ array( 'min' => -10, 'max' => 999, 'step' => 3 ),
199
+ Kirki_Field::sanitize_choices(
200
+ array( 'choices' => array( 'min' => -10, 'max' => 999, 'step' => 3 ) )
201
+ )
202
+ );
203
+ $this->assertEquals(
204
+ array( 'foo', 'bar' ),
205
+ Kirki_Field::sanitize_choices( array( 'choices' => array( 'foo', 'bar' ) ) )
206
+ );
207
+ $this->assertEquals( array(), Kirki_Field::sanitize_choices( array() ) );
208
+
209
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_choices( array( 'choices' => 'foo' ) ) );
210
+ }
211
+
212
+ public function test_sanitize_output() {
213
+ $this->assertEquals( 'foo', Kirki_Field::sanitize_output( array( 'output' => 'foo' ) ) );
214
+ $this->assertEquals(
215
+ array(
216
+ array(
217
+ 'element' => 'body > #main',
218
+ 'property' => 'font-family',
219
+ 'units' => '',
220
+ 'media_query' => 'global',
221
+ )
222
+ ),
223
+ Kirki_Field::sanitize_output( array( 'output' => array(
224
+ 'element' => 'body > #main',
225
+ 'property' => 'font-family',
226
+ ) ) )
227
+ );
228
+ $this->assertEquals(
229
+ array(
230
+ array(
231
+ 'element' => 'body > #main',
232
+ 'property' => 'font-size',
233
+ 'units' => 'px !important',
234
+ 'media_query' => '@media (min-width: 700px) and (orientation: landscape)',
235
+ )
236
+ ),
237
+ Kirki_Field::sanitize_output( array( 'output' => array(
238
+ array(
239
+ 'element' => 'body > #main',
240
+ 'property' => 'font-size',
241
+ 'units' => 'px !important',
242
+ 'prefix' => '@media (min-width: 700px) and (orientation: landscape) {',
243
+ 'suffix' => '}',
244
+ )
245
+ ) ) )
246
+ );
247
+ }
248
+
249
+ public function test_sanitize_transport() {
250
+ $this->assertEquals( 'refresh', Kirki_Field::sanitize_transport( array() ) );
251
+ $this->assertEquals( 'refresh', Kirki_Field::sanitize_transport( array( 'transport' => '' ) ) );
252
+ $this->assertEquals( 'refresh', Kirki_Field::sanitize_transport( array( 'transport' => 'invalid' ) ) );
253
+ $this->assertEquals( 'postMessage', Kirki_Field::sanitize_transport( array( 'transport' => 'postMessage' ) ) );
254
+ }
255
+
256
+ public function test_sanitize_callback() {
257
+ $this->assertEquals( '__return_true', Kirki_Field::sanitize_callback( array( 'sanitize_callback' => '__return_true' ) ) );
258
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::sanitize_callback( array( 'type' => 'checkbox' ) ) );
259
+ $this->assertEquals( array( 'Kirki_Sanitize', 'color' ), Kirki_Field::sanitize_callback( array( 'type' => 'color-alpha' ) ) );
260
+ $this->assertEquals( array( 'Kirki_Sanitize', 'color' ), Kirki_Field::sanitize_callback( array( 'type' => 'color' ) ) );
261
+ $this->assertEquals( array( 'Kirki_Sanitize', 'unfiltered' ), Kirki_Field::sanitize_callback( array( 'type' => 'custom' ) ) );
262
+ $this->assertEquals( array( 'Kirki_Sanitize', 'dropdown_pages' ), Kirki_Field::sanitize_callback( array( 'type' => 'dropdown-pages' ) ) );
263
+ $this->assertEquals( 'esc_textarea', Kirki_Field::sanitize_callback( array( 'type' => 'editor' ) ) );
264
+ $this->assertEquals( 'esc_url_raw', Kirki_Field::sanitize_callback( array( 'type' => 'image' ) ) );
265
+ $this->assertEquals( array( 'Kirki_Sanitize', 'multicheck' ), Kirki_Field::sanitize_callback( array( 'type' => 'multicheck' ) ) );
266
+ $this->assertEquals( array( 'Kirki_Sanitize', 'number' ), Kirki_Field::sanitize_callback( array( 'type' => 'number' ) ) );
267
+ $this->assertEquals( 'esc_attr', Kirki_Field::sanitize_callback( array( 'type' => 'palette' ) ) );
268
+ $this->assertEquals( 'esc_attr', Kirki_Field::sanitize_callback( array( 'type' => 'radio-buttonset' ) ) );
269
+ $this->assertEquals( 'esc_attr', Kirki_Field::sanitize_callback( array( 'type' => 'radio-image' ) ) );
270
+ $this->assertEquals( 'esc_attr', Kirki_Field::sanitize_callback( array( 'type' => 'radio' ) ) );
271
+ $this->assertEquals( 'esc_attr', Kirki_Field::sanitize_callback( array( 'type' => 'select' ) ) );
272
+ $this->assertEquals( array( 'Kirki_Sanitize', 'number' ), Kirki_Field::sanitize_callback( array( 'type' => 'slider' ) ) );
273
+ $this->assertEquals( array( 'Kirki_Sanitize', 'sortable' ), Kirki_Field::sanitize_callback( array( 'type' => 'sortable' ) ) );
274
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::sanitize_callback( array( 'type' => 'switch' ) ) );
275
+ $this->assertEquals( 'esc_textarea', Kirki_Field::sanitize_callback( array( 'type' => 'text' ) ) );
276
+ $this->assertEquals( 'esc_textarea', Kirki_Field::sanitize_callback( array( 'type' => 'textarea' ) ) );
277
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::sanitize_callback( array( 'type' => 'toggle' ) ) );
278
+ $this->assertEquals( 'esc_url_raw', Kirki_Field::sanitize_callback( array( 'type' => 'upload' ) ) );
279
+ }
280
+
281
+ public function test_sanitize_js_vars() {
282
+ $this->assertEquals( null, Kirki_Field::sanitize_js_vars( array() ) );
283
+ $this->assertEquals( null, Kirki_Field::sanitize_js_vars( array( 'js_vars' => 'foo' ) ) );
284
+ $this->assertEquals(
285
+ array(
286
+ array(
287
+ 'element' => '#main',
288
+ 'function' => 'css',
289
+ 'property' => 'color',
290
+ 'units' => '',
291
+ )
292
+ ),
293
+ Kirki_Field::sanitize_js_vars( array( 'js_vars' => array(
294
+ 'element' => '#main',
295
+ 'function' => 'css',
296
+ 'property' => 'color',
297
+ ) ) )
298
+ );
299
+ $this->assertEquals(
300
+ array(
301
+ array(
302
+ 'element' => 'body > #main',
303
+ 'function' => 'css',
304
+ 'property' => 'font-size',
305
+ 'units' => 'px'
306
+ )
307
+ ),
308
+ Kirki_Field::sanitize_js_vars( array( 'js_vars' => array(
309
+ array(
310
+ 'element' => 'body > #main',
311
+ 'function' => 'css',
312
+ 'property' => 'font-size',
313
+ 'units' => 'px'
314
+ )
315
+ ) ) )
316
+ );
317
+ }
318
+
319
+ public function test_sanitize_required() {
320
+ $this->assertEquals(
321
+ array(
322
+ array(
323
+ 'setting' => 'my-setting',
324
+ 'operator' => '==',
325
+ 'value' => '1',
326
+ )
327
+ ),
328
+ Kirki_Field::sanitize_required( array( 'required' => array(
329
+ 'setting' => 'my-setting',
330
+ ) ) )
331
+ );
332
+ $this->assertEquals(
333
+ array(
334
+ array(
335
+ 'setting' => 'my-setting',
336
+ 'operator' => '>=',
337
+ 'value' => '#333ff2'
338
+ )
339
+ ),
340
+ Kirki_Field::sanitize_required( array( 'required' => array(
341
+ array(
342
+ 'setting' => 'my-setting',
343
+ 'operator' => '>=',
344
+ 'value' => '#333ff2'
345
+ )
346
+ ) ) )
347
+ );
348
+
349
+ $this->assertEquals( null, Kirki_Field::sanitize_required( array() ) );
350
+ }
351
+
352
+ public function test_sanitize_priority() {
353
+ $this->assertEquals( 10, Kirki_Field::sanitize_priority( array() ) );
354
+ $this->assertEquals( 10, Kirki_Field::sanitize_priority( array( 'priority' => 'invalid priority' ) ) );
355
+ $this->assertEquals( 20, Kirki_Field::sanitize_priority( array( 'priority' => '-20' ) ) );
356
+ $this->assertEquals( 20, Kirki_Field::sanitize_priority( array( 'priority' => -20 ) ) );
357
+ $this->assertEquals( 20, Kirki_Field::sanitize_priority( array( 'priority' => 20 ) ) );
358
+ $this->assertEquals( 20, Kirki_Field::sanitize_priority( array( 'priority' => 20.356 ) ) );
359
+ $this->assertEquals( 20, Kirki_Field::sanitize_priority( array( 'priority' => '20.356' ) ) );
360
+ }
361
+
362
+ public function test_fallback_callback() {
363
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::fallback_callback( 'checkbox' ) );
364
+ $this->assertEquals( array( 'Kirki_Sanitize', 'color' ), Kirki_Field::fallback_callback( 'color-alpha' ) );
365
+ $this->assertEquals( array( 'Kirki_Sanitize', 'color' ), Kirki_Field::fallback_callback( 'color' ) );
366
+ $this->assertEquals( array( 'Kirki_Sanitize', 'unfiltered' ), Kirki_Field::fallback_callback( 'custom' ) );
367
+ $this->assertEquals( array( 'Kirki_Sanitize', 'dropdown_pages' ), Kirki_Field::fallback_callback( 'dropdown-pages' ) );
368
+ $this->assertEquals( 'esc_textarea', Kirki_Field::fallback_callback( 'editor' ) );
369
+ $this->assertEquals( 'esc_url_raw', Kirki_Field::fallback_callback( 'image' ) );
370
+ $this->assertEquals( array( 'Kirki_Sanitize', 'multicheck' ), Kirki_Field::fallback_callback( 'multicheck' ) );
371
+ $this->assertEquals( array( 'Kirki_Sanitize', 'number' ), Kirki_Field::fallback_callback( 'number' ) );
372
+ $this->assertEquals( 'esc_attr', Kirki_Field::fallback_callback( 'palette' ) );
373
+ $this->assertEquals( 'esc_attr', Kirki_Field::fallback_callback( 'radio-buttonset' ) );
374
+ $this->assertEquals( 'esc_attr', Kirki_Field::fallback_callback( 'radio-image' ) );
375
+ $this->assertEquals( 'esc_attr', Kirki_Field::fallback_callback( 'radio' ) );
376
+ $this->assertEquals( 'esc_attr', Kirki_Field::fallback_callback( 'select' ) );
377
+ $this->assertEquals( array( 'Kirki_Sanitize', 'number' ), Kirki_Field::fallback_callback( 'slider' ) );
378
+ $this->assertEquals( array( 'Kirki_Sanitize', 'sortable' ), Kirki_Field::fallback_callback( 'sortable' ) );
379
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::fallback_callback( 'switch' ) );
380
+ $this->assertEquals( 'esc_textarea', Kirki_Field::fallback_callback( 'text' ) );
381
+ $this->assertEquals( 'esc_textarea', Kirki_Field::fallback_callback( 'textarea' ) );
382
+ $this->assertEquals( array( 'Kirki_Sanitize', 'checkbox' ), Kirki_Field::fallback_callback( 'toggle' ) );
383
+ $this->assertEquals( 'esc_url_raw', Kirki_Field::fallback_callback( 'upload' ) );
384
+ }
385
+
386
+ }
tests/test-kirki-functions.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Functions extends WP_UnitTestCase {
4
+
5
+ public function test_kirki_path() {
6
+ $this->assertEquals( KIRKI_PATH, kirki_path() );
7
+ }
8
+
9
+ public function test_kirki_url() {
10
+ $this->assertEquals( KIRKI_URL, kirki_url() );
11
+ add_filter( 'kirki/config', function( $config ) {
12
+ $config['url_path'] = get_stylesheet_directory_uri().'/inc';
13
+ return $config;
14
+ });
15
+ $this->assertEquals( get_stylesheet_directory_uri().'/inc', kirki_url() );
16
+ }
17
+
18
+ }
tests/test-kirki-output.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Output extends WP_UnitTestCase {
4
+
5
+ public function timestwo( $value ) {
6
+ return 2 * intval( $value );
7
+ }
8
+
9
+ public function test_css_theme_mod() {
10
+ set_theme_mod( 'foo', '#333' );
11
+ $this->assertEquals(
12
+ '@media (min-width: 700px){body > #foo{background-color:#333!important;}body > #foo a:after{color:#333;}}#bar{color:#333;}',
13
+ Kirki_Output::css(
14
+ 'foo',
15
+ 'theme_mod',
16
+ array(
17
+ array(
18
+ 'element' => 'body > #foo',
19
+ 'property' => 'background-color',
20
+ 'units' => '!important',
21
+ 'prefix' => '@media (min-width: 700px) {',
22
+ 'suffix' => '}',
23
+ ),
24
+ array(
25
+ 'element' => '#bar',
26
+ 'property' => 'color',
27
+ ),
28
+ array(
29
+ 'element' => 'body > #foo a:after',
30
+ 'property' => 'color',
31
+ 'media_query' => '@media (min-width: 700px)',
32
+ ),
33
+ ),
34
+ ''
35
+ )
36
+ );
37
+ }
38
+
39
+ public function test_css_option() {
40
+ update_option( 'foo', '#333' );
41
+ $this->assertEquals(
42
+ '@media (min-width: 700px){body > #foo{background-color:#333!important;}body > #foo a:after{color:#333;}}#bar{color:#333;}',
43
+ Kirki_Output::css(
44
+ 'foo',
45
+ 'option',
46
+ array(
47
+ array(
48
+ 'element' => 'body > #foo',
49
+ 'property' => 'background-color',
50
+ 'units' => '!important',
51
+ 'prefix' => '@media (min-width: 700px) {',
52
+ 'suffix' => '}',
53
+ ),
54
+ array(
55
+ 'element' => '#bar',
56
+ 'property' => 'color',
57
+ ),
58
+ array(
59
+ 'element' => 'body > #foo a:after',
60
+ 'property' => 'color',
61
+ 'media_query' => '@media (min-width: 700px)',
62
+ ),
63
+ ),
64
+ ''
65
+ )
66
+ );
67
+ }
68
+
69
+ public function test_css_option_serialized() {
70
+ update_option( 'foo', array( 'bar' => '#333' ) );
71
+ $this->assertEquals(
72
+ '@media (min-width: 700px){body > #foo{background-color:#333!important;}body > #foo a:after{color:#333;}}#bar{color:#333;}',
73
+ Kirki_Output::css(
74
+ 'foo[bar]',
75
+ 'option',
76
+ array(
77
+ array(
78
+ 'element' => 'body > #foo',
79
+ 'property' => 'background-color',
80
+ 'units' => '!important',
81
+ 'prefix' => '@media (min-width: 700px) {',
82
+ 'suffix' => '}',
83
+ ),
84
+ array(
85
+ 'element' => '#bar',
86
+ 'property' => 'color',
87
+ ),
88
+ array(
89
+ 'element' => 'body > #foo a:after',
90
+ 'property' => 'color',
91
+ 'media_query' => '@media (min-width: 700px)',
92
+ ),
93
+ ),
94
+ ''
95
+ )
96
+ );
97
+ }
98
+
99
+ public function test_css() {
100
+ $this->assertEquals( null, Kirki_Output::css() );
101
+ set_theme_mod( 'foo', '3' );
102
+ $this->assertEquals( 'body{font-size:6px;}',
103
+ Kirki_Output::css(
104
+ 'foo',
105
+ 'theme_mod',
106
+ array( array(
107
+ 'element' => 'body',
108
+ 'property' => 'font-size',
109
+ 'units' => 'px',
110
+
111
+ ) ),
112
+ array( $this, 'timestwo' )
113
+ )
114
+ );
115
+
116
+ set_theme_mod( 'foo', 'http://foo.com/bar.png' );
117
+ $this->assertEquals( 'body{background-image:url("http://foo.com/bar.png");}',
118
+ Kirki_Output::css(
119
+ 'foo',
120
+ 'theme_mod',
121
+ array( array(
122
+ 'element' => 'body',
123
+ 'property' => 'background-image',
124
+
125
+ ) ),
126
+ ''
127
+ )
128
+ );
129
+
130
+ set_theme_mod( 'foo', 'left-top' );
131
+ $this->assertEquals( 'body{background-position:left top;}',
132
+ Kirki_Output::css(
133
+ 'foo',
134
+ 'theme_mod',
135
+ array( array(
136
+ 'element' => 'body',
137
+ 'property' => 'background-position',
138
+
139
+ ) ),
140
+ ''
141
+ )
142
+ );
143
+ }
144
+
145
+ public function test_add_prefixes() {
146
+ $this->assertEquals( null, Kirki_Output::add_prefixes( '' ) );
147
+ $css = array();
148
+ $css['global']['body']['border-radius'] = '3px';
149
+ $css['global']['body']['box-shadow'] = '10px 10px 5px 0px rgba(0,0,0,0.75)';
150
+ $css['global']['body']['box-sizing'] = 'border-box';
151
+ $css['global']['body']['text-shadow'] = '0';
152
+ $css['global']['body']['transform'] = 'rotate(30deg)';
153
+ $css['global']['body']['background-size'] = 'cover';
154
+ $css['global']['body']['transition'] = 'width 1s';
155
+ $css['global']['body']['transition-property'] = 'width';
156
+ $this->assertEquals(
157
+ array( 'global' => array( 'body' => array(
158
+ 'border-radius' => '3px',
159
+ '-moz-border-radius' => '3px',
160
+ '-webkit-border-radius' => '3px',
161
+ 'box-shadow' => '10px 10px 5px 0px rgba(0,0,0,0.75)',
162
+ '-moz-box-shadow' => '10px 10px 5px 0px rgba(0,0,0,0.75)',
163
+ '-webkit-box-shadow' => '10px 10px 5px 0px rgba(0,0,0,0.75)',
164
+ 'box-sizing' => 'border-box',
165
+ '-moz-box-sizing' => 'border-box',
166
+ '-webkit-box-sizing' => 'border-box',
167
+ 'text-shadow' => '0',
168
+ '-moz-text-shadow' => '0',
169
+ '-webkit-text-shadow' => '0',
170
+ 'transform' => 'rotate(30deg)',
171
+ '-moz-transform' => 'rotate(30deg)',
172
+ '-webkit-transform' => 'rotate(30deg)',
173
+ '-ms-transform' => 'rotate(30deg)',
174
+ '-o-transform' => 'rotate(30deg)',
175
+ 'background-size' => 'cover',
176
+ '-moz-background-size' => 'cover',
177
+ '-webkit-background-size' => 'cover',
178
+ '-ms-background-size' => 'cover',
179
+ '-o-background-size' => 'cover',
180
+ 'transition' => 'width 1s',
181
+ '-moz-transition' => 'width 1s',
182
+ '-webkit-transition' => 'width 1s',
183
+ '-ms-transition' => 'width 1s',
184
+ '-o-transition' => 'width 1s',
185
+ 'transition-property' => 'width',
186
+ '-moz-transition-property' => 'width',
187
+ '-webkit-transition-property' => 'width',
188
+ '-ms-transition-property' => 'width',
189
+ '-o-transition-property' => 'width',
190
+ ) ) ),
191
+ Kirki_Output::add_prefixes( $css )
192
+ );
193
+ }
194
+
195
+ }
tests/test-kirki-scripts-customizer-branding.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Scripts_Customizer_Branding extends WP_UnitTestCase {
4
+
5
+ public function test_generate_script() {
6
+ add_filter( 'kirki/config', function() {
7
+ return array(
8
+ 'logo_image' => 'http://foo.com/bar.png',
9
+ 'description' => 'Lorem ipsum dolor sit amet',
10
+ );
11
+ });
12
+ $this->assertEquals(
13
+ '$( \'div#customize-info .preview-notice\' ).replaceWith( \'<img src="http://foo.com/bar.png">\' );$( \'div#customize-info .accordion-section-content\' ).replaceWith( \'<div class="accordion-section-content"><div class="theme-description">Lorem ipsum dolor sit amet</div></div>\' );',
14
+ Kirki()->scripts->branding->generate_script()
15
+ );
16
+ }
17
+
18
+ public function test_customize_controls_print_scripts() {
19
+ add_filter( 'kirki/config', function() {
20
+ return array();
21
+ });
22
+ $this->expectOutputString( '' );
23
+ print '';
24
+
25
+ add_filter( 'kirki/config', function() {
26
+ return array(
27
+ 'logo_image' => 'http://foo.com/bar.png',
28
+ 'description' => 'Lorem ipsum dolor sit amet',
29
+ );
30
+ });
31
+ $script = '$( \'div#customize-info .preview-notice\' ).replaceWith( \'<img src="http://foo.com/bar.png">\' );$( \'div#customize-info .accordion-section-content\' ).replaceWith( \'<div class="accordion-section-content"><div class="theme-description">Lorem ipsum dolor sit amet</div></div>\' );';
32
+ $this->expectOutputString( '<script>jQuery(document).ready(function($) { "use strict"; '.$script.'});</script>' );
33
+ Kirki()->scripts->branding->customize_controls_print_scripts();
34
+ }
35
+ }
tests/test-kirki-scripts-customizer-postmessage.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Customizer_Script_Postmessage extends WP_UnitTestCase {
4
+
5
+ public function init_customizer() {
6
+ global $wp_customize;
7
+ if ( ! isset( $wp_customize ) ) {
8
+ if ( ! class_exists( 'WP_Customize_Manager' ) ) {
9
+ require_once( ABSPATH . '/wp-includes/class-wp-customize-manager.php' );
10
+ }
11
+ $wp_customize = new WP_Customize_Manager();
12
+ }
13
+ return $wp_customize;
14
+ }
15
+
16
+ public function test_generate_script() {
17
+ $js_vars = array(
18
+ 'element' => 'body',
19
+ 'function' => 'css',
20
+ 'property' => 'color',
21
+ );
22
+ Kirki::add_field( '', array( 'settings' => 'foo', 'type' => 'text', 'transport' => 'postMessage', 'js_vars' => $js_vars ) );
23
+ set_theme_mod( 'foo', '#333' );
24
+ $wp_customize = $this->init_customizer();
25
+
26
+ $this->assertEquals(
27
+ 'wp.customize( \'foo\', function( value ) {value.bind( function( newval ) {$(\'body\').css(\'color\', newval );}); });',
28
+ Kirki()->scripts->postmessage->generate_script()
29
+ );
30
+
31
+ $js_vars = array(
32
+ 'element' => 'body',
33
+ 'function' => 'html',
34
+ );
35
+ Kirki::add_field( '', array( 'settings' => 'foo', 'type' => 'text', 'transport' => 'postMessage', 'js_vars' => $js_vars ) );
36
+ set_theme_mod( 'foo', 'this is a string' );
37
+ $wp_customize = $this->init_customizer();
38
+
39
+ $this->assertEquals(
40
+ 'wp.customize( \'foo\', function( value ) {value.bind( function( newval ) {$(\'body\').html( newval );}); });',
41
+ Kirki()->scripts->postmessage->generate_script()
42
+ );
43
+ }
44
+ }
tests/test-kirki-scripts-customizer-tooltips.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Scripts_Customizer_Tooltips extends WP_UnitTestCase {
4
+
5
+ public function test_generate_script() {
6
+ Kirki::add_field( '', array(
7
+ 'settings' => 'foo',
8
+ 'type' => 'text',
9
+ 'section' => 'bar',
10
+ 'help' => 'Lorem Ipsum',
11
+ ) );
12
+ $this->assertEquals(
13
+ '$( "<a href=\'#\' class=\'tooltip hint--left\' data-hint=\'Lorem Ipsum\'><span class=\'dashicons dashicons-info\'></span></a>" ).prependTo( "#customize-control-foo" );',
14
+ Kirki()->scripts->tooltips->generate_script()
15
+ );
16
+ }
17
+
18
+ public function test_customize_controls_print_scripts() {
19
+ Kirki::add_field( '', array(
20
+ 'settings' => 'foo',
21
+ 'type' => 'text',
22
+ 'section' => 'bar',
23
+ 'help' => 'Lorem Ipsum',
24
+ ) );
25
+ $script = '$( "<a href=\'#\' class=\'tooltip hint--left\' data-hint=\'Lorem Ipsum\'><span class=\'dashicons dashicons-info\'></span></a>" ).prependTo( "#customize-control-foo" );';
26
+ $this->expectOutputString( '<script>jQuery(document).ready(function($) { "use strict"; '.$script.'});</script>' );
27
+ Kirki()->scripts->tooltips->customize_controls_print_footer_scripts();
28
+ }
29
+ }
tests/test-kirki-scripts-frontend-google-fonts.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Scripts_Frontend_Google_Fonts extends WP_UnitTestCase {
4
+
5
+ public function add_font_family_field() {
6
+ Kirki::add_field( '', array(
7
+ 'type' => 'select',
8
+ 'setting' => 'font_family',
9
+ 'label' => __( 'Font Family', 'example' ),
10
+ 'section' => 'base_typography',
11
+ 'default' => 'Roboto',
12
+ 'priority' => 20,
13
+ 'choices' => Kirki_Fonts::get_font_choices(),
14
+ 'output' => array(
15
+ 'element' => 'body',
16
+ 'property' => 'font-family',
17
+ ),
18
+ ) );
19
+ }
20
+
21
+ public function add_font_subsets_field() {
22
+ Kirki::add_field( '', array(
23
+ 'type' => 'multicheck',
24
+ 'setting' => 'subsets',
25
+ 'label' => __( 'Google-Font subsets', 'example' ),
26
+ 'description' => __( 'The subsets used from Google\'s API.', 'example' ),
27
+ 'section' => 'base_typography',
28
+ 'default' => 'all',
29
+ 'priority' => 22,
30
+ 'choices' => Kirki_Fonts::get_google_font_subsets(),
31
+ 'output' => array(
32
+ 'element' => 'body',
33
+ 'property' => 'font-subset',
34
+ ),
35
+ ) );
36
+ }
37
+
38
+ public function add_font_weight_field() {
39
+ Kirki::add_field( '', array(
40
+ 'type' => 'slider',
41
+ 'setting' => 'font_weight',
42
+ 'label' => __( 'Font Weight', 'example' ),
43
+ 'section' => 'base_typography',
44
+ 'default' => 300,
45
+ 'priority' => 24,
46
+ 'choices' => array(
47
+ 'min' => 100,
48
+ 'max' => 900,
49
+ 'step' => 100,
50
+ ),
51
+ 'output' => array(
52
+ 'element' => 'body',
53
+ 'property' => 'font-weight',
54
+ ),
55
+ ) );
56
+ }
57
+
58
+ public function test_google_link_font_family_roboto() {
59
+ $this->add_font_family_field();
60
+ set_theme_mod( 'font_family', 'Roboto' );
61
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
62
+ $link = $googlefonts->google_link();
63
+ $this->assertEquals(
64
+ $link,
65
+ '//fonts.googleapis.com/css?family=Roboto:regular,italic,700,400&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese'
66
+ );
67
+ }
68
+
69
+ public function test_google_link_font_family_open_sans() {
70
+ $this->add_font_family_field();
71
+ set_theme_mod( 'font_family', 'Open Sans' );
72
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
73
+ $link = $googlefonts->google_link();
74
+ $this->assertEquals(
75
+ $link,
76
+ '//fonts.googleapis.com/css?family=Open+Sans:regular,italic,700,400&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese'
77
+ );
78
+ }
79
+
80
+ public function test_google_link_font_subset_roboto() {
81
+ $this->add_font_family_field();
82
+ $this->add_font_subsets_field();
83
+ set_theme_mod( 'font_family', 'Roboto' );
84
+ set_theme_mod( 'subsets', 'greek' );
85
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
86
+ $link = $googlefonts->google_link();
87
+ $this->assertEquals(
88
+ $link,
89
+ '//fonts.googleapis.com/css?family=Roboto:regular,italic,700,400&subset=greek'
90
+ );
91
+ }
92
+
93
+ public function test_google_link_font_subset_open_sans() {
94
+ $this->add_font_family_field();
95
+ $this->add_font_subsets_field();
96
+ set_theme_mod( 'font_family', 'Open Sans' );
97
+ set_theme_mod( 'subsets', 'devangari' );
98
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
99
+ $link = $googlefonts->google_link();
100
+ $this->assertEquals(
101
+ $link,
102
+ '//fonts.googleapis.com/css?family=Open+Sans:regular,italic,700,400&subset=devangari'
103
+ );
104
+ }
105
+
106
+ public function test_google_link_font_combo_roboto() {
107
+ $this->add_font_family_field();
108
+ $this->add_font_subsets_field();
109
+ $this->add_font_weight_field();
110
+ set_theme_mod( 'font_family', 'Roboto' );
111
+ set_theme_mod( 'subsets', 'greek' );
112
+ set_theme_mod( 'font_weight', '900' );
113
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
114
+ $link = $googlefonts->google_link();
115
+ $this->assertEquals(
116
+ $link,
117
+ '//fonts.googleapis.com/css?family=Roboto:regular,italic,700,900&subset=greek'
118
+ );
119
+ }
120
+
121
+ public function test_google_link_font_combo_open_sans() {
122
+ $this->add_font_family_field();
123
+ $this->add_font_subsets_field();
124
+ $this->add_font_weight_field();
125
+ set_theme_mod( 'font_family', 'Open Sans' );
126
+ set_theme_mod( 'subsets', 'devangari' );
127
+ set_theme_mod( 'font_weight', 100 );
128
+ $googlefonts = new Kirki_Scripts_Frontend_Google_Fonts();
129
+ $link = $googlefonts->google_link();
130
+ $this->assertEquals(
131
+ $link,
132
+ '//fonts.googleapis.com/css?family=Open+Sans:regular,italic,700,100&subset=devangari'
133
+ );
134
+ }
135
+
136
+ public function test_google_font_enqueued() {
137
+ $this->add_font_family_field();
138
+ $this->add_font_subsets_field();
139
+ $this->add_font_weight_field();
140
+ set_theme_mod( 'font_family', 'Open Sans' );
141
+ set_theme_mod( 'subsets', 'devangari' );
142
+ set_theme_mod( 'font_weight', 100 );
143
+
144
+ Kirki();
145
+
146
+ $this->go_to( home_url() );
147
+ do_action( 'wp_enqueue_scripts' );
148
+ $styles = $GLOBALS['wp_styles']->registered;
149
+ $this->assertTrue( isset( $styles['kirki_google_fonts'] ) );
150
+ }
151
+
152
+ }
tests/test-kirki-styles-customizer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Styles_Customizer extends WP_UnitTestCase {
4
+
5
+ public function test_google_font_enqueued() {
6
+ Kirki();
7
+ do_action( 'customize_controls_print_styles' );
8
+ $styles = $GLOBALS['wp_styles']->registered;
9
+ $this->assertTrue( isset( $styles['kirki-customizer-css'] ) );
10
+ }
11
+
12
+ public function test_custom_css() {
13
+ add_filter( 'kirki/config', function( $config ) {
14
+ $config['color_accent'] = '#00bcd4';
15
+ $config['color_back'] = '#455a64';
16
+ $config['width'] = '20%';
17
+ return $config;
18
+ });
19
+
20
+ do_action( 'customize_controls_print_styles' );
21
+ $this->assertTrue( false !== strpos( Kirki()->styles['back']->custom_css(), '#00bcd4' ) );
22
+ $this->assertTrue( false !== strpos( Kirki()->styles['back']->custom_css(), '#455a64' ) );
23
+ $this->assertTrue( false !== strpos( Kirki()->styles['back']->custom_css(), '20%' ) );
24
+ }
25
+
26
+ }
tests/test-kirki-toolkit.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Toolkit extends WP_UnitTestCase {
4
+
5
+ function test_font_registry() {
6
+ $this->assertTrue( is_object( Kirki()->font_registry ) );
7
+ }
8
+
9
+ function test_scripts() {
10
+ $this->assertTrue( is_object( Kirki()->scripts ) );
11
+ }
12
+
13
+ function test_api() {
14
+ $this->assertTrue( is_object( Kirki()->api ) );
15
+ }
16
+
17
+ function test_styles() {
18
+ $this->assertTrue( is_array( Kirki()->styles ) );
19
+ }
20
+
21
+ function test_styles_back() {
22
+ $this->assertTrue( is_object( Kirki()->styles['back'] ) );
23
+ }
24
+
25
+ function test_styles_front() {
26
+ $this->assertTrue( is_object( Kirki()->styles['front'] ) );
27
+ }
28
+
29
+ function test_i18n() {
30
+ $this->assertTrue( is_array( Kirki_Toolkit::i18n() ) );
31
+ }
32
+ }
tests/test-kirki.php ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki extends WP_UnitTestCase {
4
+
5
+ public function init_customizer() {
6
+ global $wp_customize;
7
+ if ( ! isset( $wp_customize ) ) {
8
+ if ( ! class_exists( 'WP_Customize_Manager' ) ) {
9
+ require_once( ABSPATH . '/wp-includes/class-wp-customize-manager.php' );
10
+ }
11
+ $wp_customize = new WP_Customize_Manager();
12
+ }
13
+ return $wp_customize;
14
+ }
15
+
16
+
17
+ public function add_config() {
18
+ Kirki::add_config( 'my_config_theme_mods', array(
19
+ 'option_type' => 'theme_mod',
20
+ 'capability' => 'edit_posts',
21
+ ) );
22
+ Kirki::add_config( 'my_config_options', array(
23
+ 'option_type' => 'option',
24
+ 'capability' => 'edit_posts',
25
+ ) );
26
+ Kirki::add_config( 'my_config_options_serialized', array(
27
+ 'option_type' => 'option',
28
+ 'option_name' => 'my_option',
29
+ 'capability' => 'edit_posts',
30
+ ) );
31
+ }
32
+
33
+ public function add_panel() {
34
+ Kirki::add_panel( 'panel_id', array(
35
+ 'priority' => 10,
36
+ 'title' => 'My Title',
37
+ 'description' => 'My Description',
38
+ ) );
39
+ }
40
+
41
+ public function add_section() {
42
+ Kirki::add_section( 'section_id', array(
43
+ 'title' => 'My Title',
44
+ 'description' => 'My Description',
45
+ 'panel' => 'panel_id',
46
+ 'priority' => 160,
47
+ 'capability' => 'edit_theme_options',
48
+ ) );
49
+ }
50
+
51
+ public function add_field() {
52
+
53
+ Kirki::add_field( 'my_config_theme_mods', array(
54
+ 'settings' => 'my_setting_theme_mods',
55
+ 'label' => __( 'My custom control', 'translation_domain' ),
56
+ 'section' => 'my_section',
57
+ 'type' => 'text',
58
+ 'priority' => 10,
59
+ 'default' => 'some-default-value',
60
+ ) );
61
+
62
+ Kirki::add_field( 'my_config_options', array(
63
+ 'settings' => 'my_setting_options',
64
+ 'label' => __( 'My custom control', 'translation_domain' ),
65
+ 'section' => 'my_section',
66
+ 'type' => 'text',
67
+ 'priority' => 10,
68
+ 'default' => 'some-default-value',
69
+ ) );
70
+
71
+ Kirki::add_field( 'my_config_options_serialized', array(
72
+ 'settings' => 'my_setting_options_serialized',
73
+ 'label' => __( 'My custom control', 'translation_domain' ),
74
+ 'section' => 'my_section',
75
+ 'type' => 'text',
76
+ 'priority' => 10,
77
+ 'default' => 'some-default-value',
78
+ ) );
79
+
80
+ }
81
+
82
+ public function add_background_fields() {
83
+ Kirki::add_field( 'my_config_theme_mods', array(
84
+ 'settings' => 'my_settings_test_background_theme_mod',
85
+ 'section' => 'my_section',
86
+ 'type' => 'background',
87
+ 'default' => array(
88
+ 'color' => '#333333',
89
+ 'image' => 'http://foo.com/bar.png',
90
+ 'repeat' => 'no-repeat',
91
+ 'size' => 'cover',
92
+ 'attach' => 'scroll',
93
+ 'position' => 'center-bottom',
94
+ 'opacity' => '.6',
95
+ ),
96
+ ) );
97
+ Kirki::add_field( 'my_config_options', array(
98
+ 'settings' => 'my_settings_test_background_options',
99
+ 'section' => 'my_section',
100
+ 'type' => 'background',
101
+ 'default' => array(
102
+ 'color' => '#333333',
103
+ 'image' => 'http://foo.com/bar.png',
104
+ 'repeat' => 'no-repeat',
105
+ 'size' => 'cover',
106
+ 'attach' => 'scroll',
107
+ 'position' => 'center-bottom',
108
+ 'opacity' => '.6',
109
+ ),
110
+ ) );
111
+ Kirki::add_field( 'my_config_options_serialized', array(
112
+ 'settings' => 'my_settings_test_background_options_serialized',
113
+ 'section' => 'my_section',
114
+ 'type' => 'background',
115
+ 'default' => array(
116
+ 'color' => '#333333',
117
+ 'image' => 'http://foo.com/bar.png',
118
+ 'repeat' => 'no-repeat',
119
+ 'size' => 'cover',
120
+ 'attach' => 'scroll',
121
+ 'position' => 'center-bottom',
122
+ 'opacity' => '.6',
123
+ ),
124
+ ) );
125
+ }
126
+
127
+ function add_controls_via_filter( $fields ) {
128
+
129
+ // Add the controls
130
+ $fields[] = array(
131
+ 'label' => __( 'My custom control', 'translation_domain' ),
132
+ 'section' => 'my_section',
133
+ 'settings' => 'my_setting_3',
134
+ 'type' => 'text',
135
+ 'priority' => 10,
136
+ 'option_type' => 'theme_mod',
137
+ 'capability' => 'edit_posts',
138
+ 'default' => 'some-default-value',
139
+ );
140
+
141
+ $fields[] = array(
142
+ 'label' => __( 'My custom control 2', 'translation_domain' ),
143
+ 'section' => 'my_section',
144
+ 'settings' => 'my_setting_4',
145
+ 'type' => 'checkbox',
146
+ 'priority' => 20,
147
+ 'option_type' => 'theme_mod',
148
+ 'capability' => 'edit_theme_options',
149
+ 'default' => '0',
150
+ );
151
+
152
+ return $fields;
153
+
154
+ }
155
+
156
+ public function test_config() {
157
+ $this->add_config();
158
+ // Default config
159
+ $this->assertArrayHasKey( 'global', Kirki::$config );
160
+ $this->assertEquals( 'edit_theme_options', Kirki::$config['global']['capability'] );
161
+ $this->assertEquals( 'theme_mod', Kirki::$config['global']['option_type'] );
162
+ // Custom config
163
+ $this->assertArrayHasKey( 'my_config_theme_mods', Kirki::$config );
164
+ $this->assertArrayHasKey( 'my_config_options', Kirki::$config );
165
+ $this->assertArrayHasKey( 'my_config_options_serialized', Kirki::$config );
166
+
167
+ $this->assertEquals( 'edit_posts', Kirki::$config['my_config_theme_mods']['capability'] );
168
+ $this->assertEquals( 'option', Kirki::$config['my_config_options']['option_type'] );
169
+ $this->assertEquals( 'my_option', Kirki::$config['my_config_options_serialized']['option_name'] );
170
+ }
171
+
172
+ public function test_panels() {
173
+ $this->add_panel();
174
+ $this->assertArrayHasKey( 'panel_id', Kirki::$panels );
175
+ $this->assertEquals( 'panel_id', Kirki::$panels['panel_id']['id'] );
176
+ $this->assertEquals( 10, Kirki::$panels['panel_id']['priority'] );
177
+ $this->assertEquals( 'My Title', Kirki::$panels['panel_id']['title'] );
178
+ $this->assertEquals( 'My Description', Kirki::$panels['panel_id']['description'] );
179
+ }
180
+
181
+ public function test_sections() {
182
+ $this->add_section();
183
+ $this->assertArrayHasKey( 'section_id', Kirki::$sections );
184
+ $this->assertEquals( 'section_id', Kirki::$sections['section_id']['id'] );
185
+ $this->assertEquals( 160, Kirki::$sections['section_id']['priority'] );
186
+ $this->assertEquals( 'My Title', Kirki::$sections['section_id']['title'] );
187
+ $this->assertEquals( 'My Description', Kirki::$sections['section_id']['description'] );
188
+ }
189
+
190
+ public function test_fields() {
191
+ Kirki::$fields = array();
192
+ $this->add_config();
193
+ $this->add_field();
194
+
195
+ $this->assertArrayHasKey( 'my_setting_theme_mods', Kirki::$fields );
196
+ $this->assertEquals( 'My custom control', Kirki::$fields['my_setting_theme_mods']['label'] );
197
+ $this->assertEquals( 'my_section', Kirki::$fields['my_setting_theme_mods']['section'] );
198
+ $this->assertEquals( 'text', Kirki::$fields['my_setting_theme_mods']['type'] );
199
+ $this->assertEquals( 10, Kirki::$fields['my_setting_theme_mods']['priority'] );
200
+ $this->assertEquals( 'some-default-value', Kirki::$fields['my_setting_theme_mods']['default'] );
201
+ $this->assertEquals( 'edit_posts', Kirki::$fields['my_setting_theme_mods']['capability'] );
202
+ $this->assertEquals( 'theme_mod', Kirki::$fields['my_setting_theme_mods']['option_type'] );
203
+ $this->assertEquals( 'option', Kirki::$fields['my_setting_options']['option_type'] );
204
+ $this->assertEquals( 'option', Kirki::$fields['my_option[my_setting_options_serialized]']['option_type'] );
205
+ }
206
+
207
+ public function test_fields_via_filter() {
208
+ Kirki::$fields = array();
209
+ add_filter( 'kirki/fields', array( $this, 'add_controls_via_filter' ) );
210
+ do_action( 'wp_loaded' );
211
+
212
+ // my_setting
213
+ $this->assertArrayHasKey( 'my_setting_3', Kirki::$fields );
214
+ $this->assertArrayHasKey( 'my_setting_4', Kirki::$fields );
215
+ $this->assertEquals( 'My custom control', Kirki::$fields['my_setting_3']['label'] );
216
+ $this->assertEquals( 'my_section', Kirki::$fields['my_setting_3']['section'] );
217
+ $this->assertEquals( 'text', Kirki::$fields['my_setting_3']['type'] );
218
+ $this->assertEquals( 10, Kirki::$fields['my_setting_3']['priority'] );
219
+ $this->assertEquals( 'some-default-value', Kirki::$fields['my_setting_3']['default'] );
220
+ $this->assertEquals( 'edit_posts', Kirki::$fields['my_setting_3']['capability'] );
221
+
222
+ }
223
+
224
+ public function test_get_option() {
225
+ Kirki::$config = null;
226
+ Kirki::$fields = null;
227
+ $this->add_config();
228
+ $this->add_field();
229
+ $this->assertEquals( 'some-default-value', Kirki::get_option( 'my_config_theme_mods', 'my_setting_theme_mods' ) );
230
+ $this->assertEquals( 'some-default-value', Kirki::get_option( 'my_config_options', 'my_setting_options' ) );
231
+ $this->assertEquals( 'some-default-value', Kirki::get_option( 'my_config_options_serialized', 'my_option[my_setting_options_serialized]' ) );
232
+
233
+ Kirki::$config = null;
234
+ Kirki::$fields = null;
235
+ $this->add_config();
236
+ $this->add_background_fields();
237
+ $this->assertEquals(
238
+ array(
239
+ 'color' => '#333333',
240
+ 'image' => 'http://foo.com/bar.png',
241
+ 'repeat' => 'no-repeat',
242
+ 'size' => 'cover',
243
+ 'attach' => 'scroll',
244
+ 'position' => 'center-bottom',
245
+ 'opacity' => '.6',
246
+ ),
247
+ Kirki::get_option( 'my_config_theme_mods', 'my_settings_test_background_theme_mod' )
248
+ );
249
+ $this->assertEquals(
250
+ array(
251
+ 'color' => '#333333',
252
+ 'image' => 'http://foo.com/bar.png',
253
+ 'repeat' => 'no-repeat',
254
+ 'size' => 'cover',
255
+ 'attach' => 'scroll',
256
+ 'position' => 'center-bottom',
257
+ 'opacity' => '.6',
258
+ ),
259
+ Kirki::get_option( 'my_config_options', 'my_settings_test_background_options' )
260
+ );
261
+ $this->assertEquals(
262
+ array(
263
+ 'color' => '#333333',
264
+ 'image' => 'http://foo.com/bar.png',
265
+ 'repeat' => 'no-repeat',
266
+ 'size' => 'cover',
267
+ 'attach' => 'scroll',
268
+ 'position' => 'center-bottom',
269
+ 'opacity' => '.6',
270
+ ),
271
+ Kirki::get_option( 'my_config_options_serialized', 'my_option[my_settings_test_background_options_serialized]' )
272
+ );
273
+
274
+ Kirki::$config = null;
275
+ Kirki::$fields = null;
276
+ $this->add_config();
277
+ $this->add_background_fields();
278
+
279
+ set_theme_mod( 'my_settings_test_background_theme_mod_color', '#000000' );
280
+ $this->assertEquals(
281
+ array(
282
+ 'color' => '#000000',
283
+ 'image' => 'http://foo.com/bar.png',
284
+ 'repeat' => 'no-repeat',
285
+ 'size' => 'cover',
286
+ 'attach' => 'scroll',
287
+ 'position' => 'center-bottom',
288
+ 'opacity' => '.6',
289
+ ),
290
+ Kirki::get_option( 'my_config_theme_mods', 'my_settings_test_background_theme_mod' )
291
+ );
292
+ update_option( 'my_settings_test_background_options_color', '#222222' );
293
+ $this->assertEquals(
294
+ array(
295
+ 'color' => '#222222',
296
+ 'image' => 'http://foo.com/bar.png',
297
+ 'repeat' => 'no-repeat',
298
+ 'size' => 'cover',
299
+ 'attach' => 'scroll',
300
+ 'position' => 'center-bottom',
301
+ 'opacity' => '.6',
302
+ ),
303
+ Kirki::get_option( 'my_config_options', 'my_settings_test_background_options' )
304
+ );
305
+ update_option( 'my_option', array( 'my_settings_test_background_options_serialized_color' => '#444444' ) );
306
+ $this->assertEquals(
307
+ array(
308
+ 'color' => '#444444',
309
+ 'image' => 'http://foo.com/bar.png',
310
+ 'repeat' => 'no-repeat',
311
+ 'size' => 'cover',
312
+ 'attach' => 'scroll',
313
+ 'position' => 'center-bottom',
314
+ 'opacity' => '.6',
315
+ ),
316
+ Kirki::get_option( 'my_config_options_serialized', 'my_option[my_settings_test_background_options_serialized]' )
317
+ );
318
+ }
319
+
320
+ }
tests/test-textdomain.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Test_Kirki_Textdomain extends WP_UnitTestCase {
4
+
5
+ function test_kirki_load_textdomain() {
6
+ do_action( 'plugins_loaded' );
7
+ $this->assertEquals( 10, has_action( 'plugins_loaded', 'kirki_load_textdomain' ) );
8
+ global $l10n;
9
+ $this->assertEquals( true, isset( $l10n['kirki'] ) );
10
+ }
11
+
12
+ }