SVG Support - Version 2.5.2

Version Description

  • Added some defaults for better security by default.
Download this release

Release Info

Developer Benbodhi
Plugin Icon 128x128 SVG Support
Version 2.5.2
Comparing to
See all releases

Code changes from version 2.5.1 to 2.5.2

admin/admin-init.php CHANGED
@@ -55,8 +55,20 @@ function bodhi_sanitize_fields( $value ) {
55
  global $bodhi_svgs_options;
56
  $bodhi_plugin_version_stored = get_option( 'bodhi_svgs_plugin_version' );
57
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  $value['css_target'] = esc_attr( sanitize_text_field( $value['css_target'] ) );
59
-
60
  if( $value['sanitize_svg_front_end'] !== 'on' ) {
61
 
62
  $value['sanitize_svg_front_end'] = false;
55
  global $bodhi_svgs_options;
56
  $bodhi_plugin_version_stored = get_option( 'bodhi_svgs_plugin_version' );
57
 
58
+ if( !isset($value['sanitize_svg']) ) {
59
+ $value['sanitize_svg'] = "none";
60
+ }
61
+
62
+ if( !isset($value['sanitize_on_upload_roles']) ) {
63
+ $value['sanitize_on_upload_roles'] = "none";
64
+ }
65
+
66
+ if( !isset($value['restrict']) ) {
67
+ $value['restrict'] = "none";
68
+ }
69
+
70
  $value['css_target'] = esc_attr( sanitize_text_field( $value['css_target'] ) );
71
+
72
  if( $value['sanitize_svg_front_end'] !== 'on' ) {
73
 
74
  $value['sanitize_svg_front_end'] = false;
admin/svgs-settings-page.php CHANGED
@@ -33,7 +33,6 @@
33
  <p><?php _e( 'SVG Support has grown to be installed on 800,000+ active websites. That\'s insane! It\'s developed and maintained by one person alone. If you find it useful, please consider donating to help keep it going. I truly appreciate any contribution.', 'svg-support' ); ?></p>
34
  <p><strong>
35
  <?php _e( 'BTC: 1qF8r2HkTLifND7WLGfWmvxfXc9ze55DZ', 'svg-support' ); ?><br/>
36
- <?php _e( 'LTC: LUnQPJrSk6cVFmMqBMv5FAqweJbnzRUz4o', 'svg-support' ); ?><br/>
37
  <?php _e( 'ETH: 0x599695Eb51aFe2e5a0DAD60aD9c89Bc8f10B54f4', 'svg-support' ); ?>
38
  </strong></p>
39
  <p><?php _e( 'You can also', 'svg-support' ); ?> <a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ&source=url"><?php _e( 'Donate using PayPal', 'svg-support' ); ?></a></p>
@@ -65,14 +64,39 @@
65
  <tr valign="top">
66
  <!-- Swap with future feature: Multiselect Roles -->
67
  <th scope="row">
68
- <strong><?php _e( 'Restrict to Administrators?', 'svg-support' ); ?></strong>
69
  </th>
70
  <td>
71
- <label for="bodhi_svgs_settings[restrict]">
72
- <?php printf(
73
- '<input id="bodhi_svgs_settings[restrict]" name="bodhi_svgs_settings[restrict]" type="checkbox" %2$s />', 'bodhi_svgs_settings_restrict', checked( isset( $bodhi_svgs_options['restrict'] ), true, false ) ); ?>
74
- <?php _e( 'Yes', 'svg-support' ); ?><br /><small class="description"><?php _e(' Restricts SVG upload privileges to Administrators.', 'svg-support' ); ?></small>
75
- </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  </td>
77
  </tr>
78
 
@@ -90,16 +114,52 @@
90
  </td>
91
  </tr>
92
 
93
- <tr valign="top">
94
  <!-- Allow sanitization of svg -->
95
  <th scope="row">
96
  <strong><?php _e( 'Sanitize SVG while uploading', 'svg-support' ); ?></strong>
97
  </th>
98
  <td>
99
- <label for="bodhi_svgs_settings[sanitize_svg]">
100
  <?php printf(
101
- '<input id="bodhi_svgs_settings[sanitize_svg]" name="bodhi_svgs_settings[sanitize_svg]" type="checkbox" %2$s />', 'bodhi_svgs_settings_sanitize_svg', checked( isset( $bodhi_svgs_options['sanitize_svg'] ), true, false ) ); ?>
102
- <?php _e( 'Yes', 'svg-support' ); ?><br /><small class="description"><?php _e('Enhance security of SVG uploads by sanitizing all svg images before being uploaded. This is helpful when non-admins are allowed to upload SVG images.<br><em>All external references are automatically removed during sanitization to prevent XSS and Injection attacks.</em>', 'svg-support' ); ?></small>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  </label>
104
  </td>
105
  </tr>
33
  <p><?php _e( 'SVG Support has grown to be installed on 800,000+ active websites. That\'s insane! It\'s developed and maintained by one person alone. If you find it useful, please consider donating to help keep it going. I truly appreciate any contribution.', 'svg-support' ); ?></p>
34
  <p><strong>
35
  <?php _e( 'BTC: 1qF8r2HkTLifND7WLGfWmvxfXc9ze55DZ', 'svg-support' ); ?><br/>
 
36
  <?php _e( 'ETH: 0x599695Eb51aFe2e5a0DAD60aD9c89Bc8f10B54f4', 'svg-support' ); ?>
37
  </strong></p>
38
  <p><?php _e( 'You can also', 'svg-support' ); ?> <a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ&source=url"><?php _e( 'Donate using PayPal', 'svg-support' ); ?></a></p>
64
  <tr valign="top">
65
  <!-- Swap with future feature: Multiselect Roles -->
66
  <th scope="row">
67
+ <strong><?php _e( 'Restrict SVG Uploads to?', 'svg-support' ); ?></strong>
68
  </th>
69
  <td>
70
+
71
+ <div class="upload_allowed_roles">
72
+
73
+ <?php $allowed_roles_array = $bodhi_svgs_options['restrict']; ?>
74
+
75
+ <select style="display:none" name="bodhi_svgs_settings[restrict][]" multiple>
76
+
77
+ <?php
78
+ global $wp_roles;
79
+ $all_roles = $wp_roles->roles;
80
+
81
+ foreach ($all_roles as $role => $details) {
82
+ $user_role_slug = esc_attr($role);
83
+ $user_role_name = translate_user_role($details['name']);
84
+
85
+ $role_selected = "";
86
+
87
+ if( in_array($user_role_slug, $allowed_roles_array) ) {
88
+ $role_selected = "selected";
89
+ }
90
+
91
+ ?>
92
+
93
+ <option value="<?php echo $user_role_slug; ?>" <?php echo $role_selected; ?> ><?php echo $user_role_name; ?></option>
94
+
95
+ <?php } ?>
96
+
97
+ </select>
98
+ </div>
99
+
100
  </td>
101
  </tr>
102
 
114
  </td>
115
  </tr>
116
 
117
+ <tr valign="top" id="sanitize_svg_option">
118
  <!-- Allow sanitization of svg -->
119
  <th scope="row">
120
  <strong><?php _e( 'Sanitize SVG while uploading', 'svg-support' ); ?></strong>
121
  </th>
122
  <td>
123
+ <label style="margin-bottom: 10px;display:block" for="bodhi_svgs_settings[sanitize_svg]">
124
  <?php printf(
125
+ '<input id="bodhi_svgs_settings[sanitize_svg]" name="bodhi_svgs_settings[sanitize_svg]" type="checkbox" %2$s />', 'bodhi_svgs_settings_sanitize_svg', checked( $bodhi_svgs_options['sanitize_svg'], 'on', false ) ); ?>
126
+ <?php _e( 'Yes', 'svg-support' ); ?><br />
127
+ </label>
128
+
129
+ <label id="sanitize_svg_option_sction">
130
+ <div class="sanitize_on_upload_roles">
131
+
132
+ <strong style="margin-bottom: 5px;display: block;"><?php _e( 'Do not sanitize for these roles', 'svg-support' ); ?></strong>
133
+
134
+ <?php $sanitize_roles_array = $bodhi_svgs_options['sanitize_on_upload_roles']; ?>
135
+
136
+ <select style="display:none" name="bodhi_svgs_settings[sanitize_on_upload_roles][]" multiple>
137
+
138
+ <?php
139
+ global $wp_roles;
140
+ $all_roles = $wp_roles->roles;
141
+
142
+ foreach ($all_roles as $role => $details) {
143
+ $user_role_slug = esc_attr($role);
144
+ $user_role_name = translate_user_role($details['name']);
145
+
146
+ $role_selected = "";
147
+
148
+ if( in_array($user_role_slug, $sanitize_roles_array) ) {
149
+ $role_selected = "selected";
150
+ }
151
+
152
+ ?>
153
+
154
+ <option value="<?php echo $user_role_slug; ?>" <?php echo $role_selected; ?> ><?php echo $user_role_name; ?></option>
155
+
156
+ <?php } ?>
157
+
158
+ </select>
159
+ </div>
160
+
161
+
162
+ <small class="description"><?php _e('Enhance security of SVG uploads by sanitizing all svg images before being uploaded. This is helpful when non-admins are allowed to upload SVG images.<br><em>All external references are automatically removed during sanitization to prevent XSS and Injection attacks.</em>', 'svg-support' ); ?></small>
163
  </label>
164
  </td>
165
  </tr>
config.codekit3 CHANGED
@@ -7,7 +7,7 @@
7
  "uuidString" : "FDF09C14-788E-4A4D-A218-DA6A56580A0D"
8
  }
9
  ],
10
- "creatorBuild" : "34418",
11
  "files" : {
12
  "\/admin\/admin-init.php" : {
13
  "cB" : 0,
@@ -54,6 +54,18 @@
54
  "oAP" : "\/admin\/svgs-settings-page.php",
55
  "oF" : 0
56
  },
 
 
 
 
 
 
 
 
 
 
 
 
57
  "\/css\/svgs-admin-edit-post.css" : {
58
  "aP" : 1,
59
  "bl" : 0,
@@ -174,6 +186,17 @@
174
  "oAP" : "\/includes\/svg-tags.php",
175
  "oF" : 0
176
  },
 
 
 
 
 
 
 
 
 
 
 
177
  "\/js\/gutenberg-filters.js" : {
178
  "bF" : 0,
179
  "ft" : 64,
@@ -185,6 +208,28 @@
185
  "sC" : 3,
186
  "tS" : 0
187
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  "\/js\/min\/gutenberg-filters-min.js" : {
189
  "bF" : 0,
190
  "ft" : 64,
@@ -196,6 +241,17 @@
196
  "sC" : 3,
197
  "tS" : 0
198
  },
 
 
 
 
 
 
 
 
 
 
 
199
  "\/js\/min\/svgs-inline-min.js" : {
200
  "bF" : 0,
201
  "ft" : 64,
@@ -288,6 +344,21 @@
288
  "oAP" : "\/readme.txt",
289
  "oF" : 0
290
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  "\/scss\/svgs-admin-edit-post.scss" : {
292
  "aP" : 0,
293
  "bl" : 0,
@@ -979,7 +1050,7 @@
979
  },
980
  "projectAttributes" : {
981
  "creationDate" : 507572464,
982
- "displayValue" : "trunk",
983
  "displayValueWasSetByUser" : 0,
984
  "iconImageName" : "\/svg-support.png",
985
  "iconImageWasSetByUser" : 1
@@ -1689,7 +1760,8 @@
1689
  "active" : 1
1690
  },
1691
  "no-fallthrough" : {
1692
- "active" : 1
 
1693
  },
1694
  "no-floating-decimal" : {
1695
  "active" : 0
7
  "uuidString" : "FDF09C14-788E-4A4D-A218-DA6A56580A0D"
8
  }
9
  ],
10
+ "creatorBuild" : "34434",
11
  "files" : {
12
  "\/admin\/admin-init.php" : {
13
  "cB" : 0,
54
  "oAP" : "\/admin\/svgs-settings-page.php",
55
  "oF" : 0
56
  },
57
+ "\/css\/jquery.dropdown-min.css" : {
58
+ "aP" : 1,
59
+ "bl" : 0,
60
+ "ci" : 0,
61
+ "co" : 0,
62
+ "ft" : 16,
63
+ "ma" : 0,
64
+ "oA" : 0,
65
+ "oAP" : "\/css\/jquery.dropdown-min-min.css",
66
+ "oF" : 0,
67
+ "pg" : 0
68
+ },
69
  "\/css\/svgs-admin-edit-post.css" : {
70
  "aP" : 1,
71
  "bl" : 0,
186
  "oAP" : "\/includes\/svg-tags.php",
187
  "oF" : 0
188
  },
189
+ "\/js\/cstm.js.multiselect.js" : {
190
+ "bF" : 0,
191
+ "ft" : 64,
192
+ "ma" : 0,
193
+ "mi" : 1,
194
+ "oA" : 0,
195
+ "oAP" : "\/js\/min\/cstm.js.multiselect-min.js",
196
+ "oF" : 2,
197
+ "sC" : 3,
198
+ "tS" : 0
199
+ },
200
  "\/js\/gutenberg-filters.js" : {
201
  "bF" : 0,
202
  "ft" : 64,
208
  "sC" : 3,
209
  "tS" : 0
210
  },
211
+ "\/js\/jquery.dropdown.js" : {
212
+ "bF" : 0,
213
+ "ft" : 64,
214
+ "ma" : 0,
215
+ "mi" : 1,
216
+ "oA" : 0,
217
+ "oAP" : "\/js\/min\/jquery.dropdown-min.js",
218
+ "oF" : 2,
219
+ "sC" : 3,
220
+ "tS" : 0
221
+ },
222
+ "\/js\/min\/cstm.js.multiselect-min.js" : {
223
+ "bF" : 0,
224
+ "ft" : 64,
225
+ "ma" : 0,
226
+ "mi" : 1,
227
+ "oA" : 0,
228
+ "oAP" : "\/js\/min\/cstm.js.multiselect-min-min.js",
229
+ "oF" : 0,
230
+ "sC" : 3,
231
+ "tS" : 0
232
+ },
233
  "\/js\/min\/gutenberg-filters-min.js" : {
234
  "bF" : 0,
235
  "ft" : 64,
241
  "sC" : 3,
242
  "tS" : 0
243
  },
244
+ "\/js\/min\/jquery.dropdown-min.js" : {
245
+ "bF" : 0,
246
+ "ft" : 64,
247
+ "ma" : 0,
248
+ "mi" : 1,
249
+ "oA" : 0,
250
+ "oAP" : "\/js\/min\/jquery.dropdown-min-min.js",
251
+ "oF" : 0,
252
+ "sC" : 3,
253
+ "tS" : 0
254
+ },
255
  "\/js\/min\/svgs-inline-min.js" : {
256
  "bF" : 0,
257
  "ft" : 64,
344
  "oAP" : "\/readme.txt",
345
  "oF" : 0
346
  },
347
+ "\/scss\/jquery.dropdown.scss" : {
348
+ "aP" : 1,
349
+ "bl" : 1,
350
+ "co" : 0,
351
+ "dP" : 10,
352
+ "ec" : 1,
353
+ "ft" : 4,
354
+ "ma" : 0,
355
+ "oA" : 0,
356
+ "oAP" : "\/css\/jquery.dropdown-min.css",
357
+ "oF" : 2,
358
+ "oS" : 3,
359
+ "pg" : 0,
360
+ "sct" : 1
361
+ },
362
  "\/scss\/svgs-admin-edit-post.scss" : {
363
  "aP" : 0,
364
  "bl" : 0,
1050
  },
1051
  "projectAttributes" : {
1052
  "creationDate" : 507572464,
1053
+ "displayValue" : "svg-support",
1054
  "displayValueWasSetByUser" : 0,
1055
  "iconImageName" : "\/svg-support.png",
1056
  "iconImageWasSetByUser" : 1
1760
  "active" : 1
1761
  },
1762
  "no-fallthrough" : {
1763
+ "active" : 1,
1764
+ "optionString" : "{'allowEmptyCase': false}"
1765
  },
1766
  "no-floating-decimal" : {
1767
  "active" : 0
css/jquery.dropdown-min.css ADDED
@@ -0,0 +1 @@
 
1
+ @-webkit-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}.dropdown-multiple,.dropdown-multiple-label,.dropdown-single{position:relative}.dropdown-multiple-label.active .dropdown-main,.dropdown-multiple.active .dropdown-main,.dropdown-single.active .dropdown-main{display:block;-webkit-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards}.dropdown-multiple-label.active .dropdown-display-label:after,.dropdown-multiple-label.active .dropdown-display:after,.dropdown-multiple.active .dropdown-display-label:after,.dropdown-multiple.active .dropdown-display:after,.dropdown-single.active .dropdown-display-label:after,.dropdown-single.active .dropdown-display:after{border-top:none;border-bottom:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent}.dropdown-multiple-label.active .dropdown-display,.dropdown-multiple-label.active .dropdown-display-label,.dropdown-multiple.active .dropdown-display,.dropdown-multiple.active .dropdown-display-label,.dropdown-single.active .dropdown-display,.dropdown-single.active .dropdown-display-label{border-bottom-left-radius:0;border-bottom-right-radius:0}.dropdown-display,.dropdown-display-label{position:relative;display:block;margin-bottom:0;font-size:14px;line-height:1.42857143;vertical-align:middle;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-image:none;border:1px solid #ccc;border-radius:4px;color:#333;background-color:#fff}.dropdown-display-label:after,.dropdown-display:after{content:'';position:absolute;border-top:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent;top:15px;right:8px}.dropdown-clear-all{background-color:#fff;border:none;font-size:22px;z-index:999;color:#999;position:absolute;right:2px;top:2px;display:none;width:25px;height:30px;text-align:center;line-height:30px}.dropdown-clear-all:focus{outline:0}.dropdown-clear-all:hover{color:#ccc;text-decoration:none}.dropdown-display{white-space:nowrap;padding:6px 20px 6px 12px}.dropdown-multiple:hover .dropdown-clear-all,.dropdown-single:hover .dropdown-clear-all{display:block}.dropdown-display .dropdown-chose-list{display:inline-block;vertical-align:middle;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dropdown-display .dropdown-chose-list span:before{content:','}.dropdown-display .dropdown-chose-list span:first-child:before{content:''}.dropdown-display .placeholder{display:none}.dropdown-display .placeholder:first-child{position:absolute;height:100%;width:100%;top:0;left:0;color:#999;display:block;text-indent:10px;font-size:13px;line-height:32px}.dropdown-display input{border:0;outline:0}.dropdown-display-label{cursor:text;padding:6px 25px 5px 0}.dropdown-display-label .dropdown-search{display:block;width:100%;border:1px solid #eee}.dropdown-display-label .dropdown-search input{width:100%}.dropdown-option.dropdown-chose{font-weight:bold}.dropdown-display-label input,.dropdown-display-label input:focus{border:none;outline:0}.dropdown-display-label .dropdown-chose-list{width:100%;display:inline-block;padding:0 5px}.dropdown-display-label .dropdown-chose-list .placeholder{display:none}.dropdown-display-label .dropdown-selected{position:relative;margin:0 5px 5px 0;padding:0 20px 0 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-repeat:repeat-x;color:#333;cursor:default;display:inline-block}.dropdown-display-label .dropdown-selected .del{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0;float:right;line-height:1;color:#999;position:absolute;right:3px;top:0}.dropdown-display-label .dropdown-selected .del:after{content:'\D7';font-size:16px}.dropdown-main{position:absolute;top:100%;left:0;z-index:1010;width:100%;color:#444;box-sizing:border-box;background-color:#fff;border:1px solid #ccc;border-radius:0 0 4px 4px;box-shadow:0 6px 12px rgba(0,0,0,0.175);margin-top:-1px;border-top:0;padding:4px 7px;display:none}.dropdown-main ul{overflow-x:hidden;overflow-y:auto;max-height:240px;margin:0;padding:0}.dropdown-main input{margin-top:0;display:block;box-sizing:border-box;height:30px;border:1px solid #ccc;width:100%;text-indent:5px;border-radius:3px}.dropdown-main .dropdown-search{display:block;padding:5px 0}.dropdown-group{font-weight:700}.dropdown-group,.dropdown-option{margin:0;padding-left:12px;list-style:none;line-height:26px;word-wrap:break-word}.dropdown-option{cursor:pointer}.dropdown-option:focus,.dropdown-option:hover{background-color:#efefef;outline:0}.dropdown-option[disabled]{color:#ddd;background-color:#fff;cursor:not-allowed;text-decoration:line-through}.dropdown-option.dropdown-chose:after{content:'';float:right;width:10px;height:10px;background:#4AB1E9;border-radius:100%;margin:8px 5px 0 0}.dropdown-maxItem-alert,.dropdown-minItem-alert{position:absolute;top:0;left:0;background-color:#e4e3e2;width:100%;height:39px;line-height:39px;padding:0 5px;border-radius:5px;color:#999;-webkit-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards}
functions/attachment.php CHANGED
@@ -227,9 +227,25 @@ function bodhi_svgs_sanitize_svg( $file ){
227
  if ( !empty($bodhi_svgs_options['sanitize_svg']) && $bodhi_svgs_options['sanitize_svg'] === 'on' ) {
228
 
229
  if ( $file['type'] === 'image/svg+xml' ) {
230
-
231
- if ( ! bodhi_svgs_sanitize( $file['tmp_name'] ) ) {
232
- $file['error'] = __( "Sorry, this file couldn't be sanitized so for security reasons wasn't uploaded",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  'safe-svg' );
234
  }
235
 
227
  if ( !empty($bodhi_svgs_options['sanitize_svg']) && $bodhi_svgs_options['sanitize_svg'] === 'on' ) {
228
 
229
  if ( $file['type'] === 'image/svg+xml' ) {
230
+
231
+ $sanitize_on_upload_roles_array = array();
232
+
233
+ $should_sanitize_svg = array();
234
+
235
+ $sanitize_on_upload_roles_array = $bodhi_svgs_options['sanitize_on_upload_roles'];
236
+
237
+ $user = wp_get_current_user();
238
+
239
+ $current_user_roles = ( array ) $user->roles;
240
+
241
+ $should_sanitize_svg = array_intersect($sanitize_on_upload_roles_array, $current_user_roles);
242
+
243
+ if( empty($should_sanitize_svg) ) {
244
+ $file['error'] = __( "Sorry, this file couldn't be sanitized so for security reasons and wasn't uploaded.",
245
+ 'safe-svg' );
246
+ }
247
+ elseif ( ! bodhi_svgs_sanitize( $file['tmp_name'] ) ) {
248
+ $file['error'] = __( "Sorry, this file couldn't be sanitized so for security reasons and wasn't uploaded",
249
  'safe-svg' );
250
  }
251
 
functions/enqueue.php CHANGED
@@ -1,208 +1,224 @@
1
- <?php
2
- /**
3
- * Enqueue scripts and styles
4
- * This file is to enqueue the scripts and styles both admin and front end
5
- */
6
- if ( ! defined( 'ABSPATH' ) ) {
7
- exit; // Exit if accessed directly
8
- }
9
-
10
- /**
11
- * Enqueue the admin CSS using screen check functions
12
- */
13
- function bodhi_svgs_admin_css() {
14
-
15
- // check if user is on SVG Support settings page or media library page
16
- if ( bodhi_svgs_specific_pages_settings() || bodhi_svgs_specific_pages_media_library() ) {
17
-
18
- // enqueue the admin CSS
19
- wp_enqueue_style( 'bodhi-svgs-admin', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin.css' );
20
-
21
- }
22
-
23
- // check if user is on SVG Support settings page and not in "Advanced Mode"
24
- if ( bodhi_svgs_specific_pages_settings() && ! bodhi_svgs_advanced_mode() ) {
25
-
26
- // enqueue the simple mode admin CSS
27
- wp_enqueue_style( 'bodhi-svgs-admin-simple-mode', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin-simple-mode.css' );
28
-
29
- }
30
-
31
- // check if user is on an edit post page
32
- if ( bodhi_svgs_is_edit_page() ) {
33
-
34
- // enqueue the edit post CSS
35
- wp_enqueue_style( 'bodhi-svgs-admin-edit-post', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin-edit-post.css' );
36
-
37
- }
38
-
39
- }
40
- add_action( 'admin_enqueue_scripts', 'bodhi_svgs_admin_css' );
41
-
42
- /*
43
- * Enqueue Block editor JS
44
- */
45
-
46
- function bodhi_svgs_block_editor() {
47
-
48
- if ( bodhi_svgs_advanced_mode() ) {
49
- wp_enqueue_script('bodhi-svgs-gutenberg-filters', BODHI_SVGS_PLUGIN_URL . '/js/gutenberg-filters.js', ['wp-edit-post']);
50
- }
51
-
52
- }
53
-
54
- add_action( 'enqueue_block_editor_assets', 'bodhi_svgs_block_editor' );
55
-
56
- /**
57
- * Enqueue front end CSS
58
- */
59
- function bodhi_svgs_frontend_css() {
60
-
61
- // get the settings
62
- global $bodhi_svgs_options;
63
-
64
- if ( ! empty( $bodhi_svgs_options['frontend_css'] ) ) {
65
-
66
- // enqueue attachment CSS
67
- wp_enqueue_style( 'bodhi-svgs-attachment', BODHI_SVGS_PLUGIN_URL . 'css/svgs-attachment.css' );
68
-
69
- }
70
-
71
- }
72
- add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_css' );
73
-
74
- /**
75
- * Enqueue front end JS
76
- */
77
- function bodhi_svgs_frontend_js() {
78
-
79
- // get the settings
80
- global $bodhi_svgs_options;
81
-
82
- if ( !empty( $bodhi_svgs_options['sanitize_svg_front_end'] ) && $bodhi_svgs_options['sanitize_svg_front_end'] == 'on' && bodhi_svgs_advanced_mode() == true ) {
83
-
84
- // check where the JS should be placed, header or footer
85
- if ( ! empty( $bodhi_svgs_options['js_foot_choice'] ) ) {
86
- $bodhi_svgs_js_footer = true;
87
- } else {
88
- $bodhi_svgs_js_footer = false;
89
- }
90
-
91
- // enqueue dompurify library js
92
- wp_enqueue_script( 'bodhi-dompurify-library', BODHI_SVGS_PLUGIN_URL . 'vendor/DOMPurify/DOMPurify.min.js', array(), '1.0.1', $bodhi_svgs_js_footer );
93
-
94
- }
95
-
96
- }
97
-
98
- add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_js', 9 );
99
-
100
- /**
101
- * Enqueue and localize JS for IMG tag replacement
102
- */
103
- function bodhi_svgs_inline() {
104
-
105
- if ( bodhi_svgs_advanced_mode() ) {
106
-
107
- // get the settings
108
- global $bodhi_svgs_options;
109
-
110
- // check if force inline svg is active
111
- if ( ! empty( $bodhi_svgs_options['force_inline_svg'] ) ) {
112
-
113
- // set variable as true to pass to js
114
- $force_inline_svg_active = 'true';
115
-
116
- // set the class for use in JS
117
- if ( ! empty( $bodhi_svgs_options['css_target'] ) ) {
118
-
119
- // use custom class if set
120
- $css_target_array = array(
121
- 'Bodhi' => 'img.'. esc_attr($bodhi_svgs_options['css_target']),
122
- 'ForceInlineSVG' => esc_attr($bodhi_svgs_options['css_target'])
123
- );
124
-
125
- } else {
126
-
127
- // set default class
128
- $css_target_array = array(
129
- 'Bodhi' => 'img.style-svg',
130
- 'ForceInlineSVG' => 'style-svg'
131
- );
132
-
133
- }
134
-
135
- } else {
136
-
137
- // set variable as false to pass to JS
138
- $force_inline_svg_active = 'false';
139
-
140
- // if custom target is set, use that, otherwise use default
141
- if ( ! empty( $bodhi_svgs_options['css_target'] ) ) {
142
- $css_target = 'img.'. esc_attr($bodhi_svgs_options['css_target']);
143
- } else {
144
- $css_target = 'img.style-svg';
145
- }
146
-
147
- // set the array to target for passing to JS
148
- $css_target_array = $css_target;
149
-
150
- }
151
-
152
- // use expanded or minified JS
153
- if ( ! empty( $bodhi_svgs_options['use_expanded_js'] ) ) {
154
-
155
- // set variables to blank so we use the full JS version
156
- $bodhi_svgs_js_folder = '';
157
- $bodhi_svgs_js_file = '';
158
-
159
- } else {
160
-
161
- // set variables to the minified version in the min folder
162
- $bodhi_svgs_js_folder = 'min/'; // min folder
163
- $bodhi_svgs_js_file = '-min'; // min file
164
-
165
- }
166
-
167
- // check where the JS should be placed, header or footer
168
- if ( ! empty( $bodhi_svgs_options['js_foot_choice'] ) ) {
169
-
170
- $bodhi_svgs_js_footer = true;
171
-
172
- } else {
173
-
174
- $bodhi_svgs_js_footer = false;
175
-
176
- }
177
-
178
- // use vanilla js if user has enabled option in settings
179
- if ( ! empty( $bodhi_svgs_options['use_vanilla_js'] ) ) {
180
-
181
- $bodhi_svgs_js_vanilla = '-vanilla';
182
-
183
- }else{
184
-
185
- $bodhi_svgs_js_vanilla = '';
186
-
187
- }
188
-
189
- // create path for the correct js file
190
- $bodhi_svgs_js_path = 'js/' . $bodhi_svgs_js_folder .'svgs-inline' . $bodhi_svgs_js_vanilla . $bodhi_svgs_js_file . '.js' ;
191
-
192
- wp_register_script( 'bodhi_svg_inline', BODHI_SVGS_PLUGIN_URL . $bodhi_svgs_js_path, array( 'jquery' ), '1.0.1', $bodhi_svgs_js_footer );
193
- wp_enqueue_script( 'bodhi_svg_inline' );
194
-
195
- wp_add_inline_script(
196
- 'bodhi_svg_inline',
197
- sprintf(
198
- 'cssTarget=%s;ForceInlineSVGActive=%s;frontSanitizationEnabled=%s;',
199
- json_encode($css_target_array),
200
- json_encode($force_inline_svg_active),
201
- json_encode($bodhi_svgs_options['sanitize_svg_front_end'])
202
- )
203
- );
204
-
205
- }
206
-
207
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  add_action( 'wp_enqueue_scripts', 'bodhi_svgs_inline' );
1
+ <?php
2
+ /**
3
+ * Enqueue scripts and styles
4
+ * This file is to enqueue the scripts and styles both admin and front end
5
+ */
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit; // Exit if accessed directly
8
+ }
9
+
10
+ /**
11
+ * Enqueue the admin CSS using screen check functions
12
+ */
13
+ function bodhi_svgs_admin_css() {
14
+
15
+ // check if user is on SVG Support settings page or media library page
16
+ if ( bodhi_svgs_specific_pages_settings() || bodhi_svgs_specific_pages_media_library() ) {
17
+
18
+ // enqueue the admin CSS
19
+ wp_enqueue_style( 'bodhi-svgs-admin', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin.css' );
20
+
21
+ }
22
+
23
+ // check if user is on SVG Support settings page and not in "Advanced Mode"
24
+ if ( bodhi_svgs_specific_pages_settings() && ! bodhi_svgs_advanced_mode() ) {
25
+
26
+ // enqueue the simple mode admin CSS
27
+ wp_enqueue_style( 'bodhi-svgs-admin-simple-mode', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin-simple-mode.css' );
28
+
29
+ }
30
+
31
+ // check if user is on an edit post page
32
+ if ( bodhi_svgs_is_edit_page() ) {
33
+
34
+ // enqueue the edit post CSS
35
+ wp_enqueue_style( 'bodhi-svgs-admin-edit-post', BODHI_SVGS_PLUGIN_URL . 'css/svgs-admin-edit-post.css' );
36
+
37
+ }
38
+
39
+ }
40
+ add_action( 'admin_enqueue_scripts', 'bodhi_svgs_admin_css' );
41
+
42
+
43
+ function bodhi_svgs_admin_multiselect() {
44
+
45
+ wp_enqueue_style( 'CSS-for-multiselect', BODHI_SVGS_PLUGIN_URL . 'css/jquery.dropdown-min.css' );
46
+
47
+ wp_enqueue_script('js-for-multiselect', BODHI_SVGS_PLUGIN_URL . 'js/min/jquery.dropdown-min.js', array( 'jquery' ));
48
+
49
+ wp_enqueue_script('cstm-js-for-multiselect', BODHI_SVGS_PLUGIN_URL . 'js/min/cstm.js.multiselect-min.js', array( 'jquery' ));
50
+
51
+ wp_add_inline_script( 'js-for-multiselect', 'jQuery(document).ready(function(){jQuery(".upload_allowed_roles").dropdown({multipleMode: "label",input: \'<input type="text" maxLength="20" placeholder="Search">\',searchNoData: \'<li style="color:#ddd">No Results</li>\'});});', "after" );
52
+
53
+ wp_add_inline_script( 'js-for-multiselect', 'jQuery(document).ready(function(){jQuery(".sanitize_on_upload_roles").dropdown({multipleMode: "label",input: \'<input type="text" maxLength="20" placeholder="Search">\',searchNoData: \'<li style="color:#ddd">No Results</li>\'});});', "after" );
54
+ }
55
+
56
+ add_action( 'admin_enqueue_scripts', 'bodhi_svgs_admin_multiselect' );
57
+
58
+ /*
59
+ * Enqueue Block editor JS
60
+ */
61
+
62
+ function bodhi_svgs_block_editor() {
63
+
64
+ if ( bodhi_svgs_advanced_mode() ) {
65
+ wp_enqueue_script('bodhi-svgs-gutenberg-filters', BODHI_SVGS_PLUGIN_URL . '/js/gutenberg-filters.js', ['wp-edit-post']);
66
+ }
67
+
68
+ }
69
+
70
+ add_action( 'enqueue_block_editor_assets', 'bodhi_svgs_block_editor' );
71
+
72
+ /**
73
+ * Enqueue front end CSS
74
+ */
75
+ function bodhi_svgs_frontend_css() {
76
+
77
+ // get the settings
78
+ global $bodhi_svgs_options;
79
+
80
+ if ( ! empty( $bodhi_svgs_options['frontend_css'] ) ) {
81
+
82
+ // enqueue attachment CSS
83
+ wp_enqueue_style( 'bodhi-svgs-attachment', BODHI_SVGS_PLUGIN_URL . 'css/svgs-attachment.css' );
84
+
85
+ }
86
+
87
+ }
88
+ add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_css' );
89
+
90
+ /**
91
+ * Enqueue front end JS
92
+ */
93
+ function bodhi_svgs_frontend_js() {
94
+
95
+ // get the settings
96
+ global $bodhi_svgs_options;
97
+
98
+ if ( !empty( $bodhi_svgs_options['sanitize_svg_front_end'] ) && $bodhi_svgs_options['sanitize_svg_front_end'] == 'on' && bodhi_svgs_advanced_mode() == true ) {
99
+
100
+ // check where the JS should be placed, header or footer
101
+ if ( ! empty( $bodhi_svgs_options['js_foot_choice'] ) ) {
102
+ $bodhi_svgs_js_footer = true;
103
+ } else {
104
+ $bodhi_svgs_js_footer = false;
105
+ }
106
+
107
+ // enqueue dompurify library js
108
+ wp_enqueue_script( 'bodhi-dompurify-library', BODHI_SVGS_PLUGIN_URL . 'vendor/DOMPurify/DOMPurify.min.js', array(), '1.0.1', $bodhi_svgs_js_footer );
109
+
110
+ }
111
+
112
+ }
113
+
114
+ add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_js', 9 );
115
+
116
+ /**
117
+ * Enqueue and localize JS for IMG tag replacement
118
+ */
119
+ function bodhi_svgs_inline() {
120
+
121
+ if ( bodhi_svgs_advanced_mode() ) {
122
+
123
+ // get the settings
124
+ global $bodhi_svgs_options;
125
+
126
+ // check if force inline svg is active
127
+ if ( ! empty( $bodhi_svgs_options['force_inline_svg'] ) ) {
128
+
129
+ // set variable as true to pass to js
130
+ $force_inline_svg_active = 'true';
131
+
132
+ // set the class for use in JS
133
+ if ( ! empty( $bodhi_svgs_options['css_target'] ) ) {
134
+
135
+ // use custom class if set
136
+ $css_target_array = array(
137
+ 'Bodhi' => 'img.'. esc_attr($bodhi_svgs_options['css_target']),
138
+ 'ForceInlineSVG' => esc_attr($bodhi_svgs_options['css_target'])
139
+ );
140
+
141
+ } else {
142
+
143
+ // set default class
144
+ $css_target_array = array(
145
+ 'Bodhi' => 'img.style-svg',
146
+ 'ForceInlineSVG' => 'style-svg'
147
+ );
148
+
149
+ }
150
+
151
+ } else {
152
+
153
+ // set variable as false to pass to JS
154
+ $force_inline_svg_active = 'false';
155
+
156
+ // if custom target is set, use that, otherwise use default
157
+ if ( ! empty( $bodhi_svgs_options['css_target'] ) ) {
158
+ $css_target = 'img.'. esc_attr($bodhi_svgs_options['css_target']);
159
+ } else {
160
+ $css_target = 'img.style-svg';
161
+ }
162
+
163
+ // set the array to target for passing to JS
164
+ $css_target_array = $css_target;
165
+
166
+ }
167
+
168
+ // use expanded or minified JS
169
+ if ( ! empty( $bodhi_svgs_options['use_expanded_js'] ) ) {
170
+
171
+ // set variables to blank so we use the full JS version
172
+ $bodhi_svgs_js_folder = '';
173
+ $bodhi_svgs_js_file = '';
174
+
175
+ } else {
176
+
177
+ // set variables to the minified version in the min folder
178
+ $bodhi_svgs_js_folder = 'min/'; // min folder
179
+ $bodhi_svgs_js_file = '-min'; // min file
180
+
181
+ }
182
+
183
+ // check where the JS should be placed, header or footer
184
+ if ( ! empty( $bodhi_svgs_options['js_foot_choice'] ) ) {
185
+
186
+ $bodhi_svgs_js_footer = true;
187
+
188
+ } else {
189
+
190
+ $bodhi_svgs_js_footer = false;
191
+
192
+ }
193
+
194
+ // use vanilla js if user has enabled option in settings
195
+ if ( ! empty( $bodhi_svgs_options['use_vanilla_js'] ) ) {
196
+
197
+ $bodhi_svgs_js_vanilla = '-vanilla';
198
+
199
+ }else{
200
+
201
+ $bodhi_svgs_js_vanilla = '';
202
+
203
+ }
204
+
205
+ // create path for the correct js file
206
+ $bodhi_svgs_js_path = 'js/' . $bodhi_svgs_js_folder .'svgs-inline' . $bodhi_svgs_js_vanilla . $bodhi_svgs_js_file . '.js' ;
207
+
208
+ wp_register_script( 'bodhi_svg_inline', BODHI_SVGS_PLUGIN_URL . $bodhi_svgs_js_path, array( 'jquery' ), '1.0.1', $bodhi_svgs_js_footer );
209
+ wp_enqueue_script( 'bodhi_svg_inline' );
210
+
211
+ wp_add_inline_script(
212
+ 'bodhi_svg_inline',
213
+ sprintf(
214
+ 'cssTarget=%s;ForceInlineSVGActive=%s;frontSanitizationEnabled=%s;',
215
+ json_encode($css_target_array),
216
+ json_encode($force_inline_svg_active),
217
+ json_encode($bodhi_svgs_options['sanitize_svg_front_end'])
218
+ )
219
+ );
220
+
221
+ }
222
+
223
+ }
224
  add_action( 'wp_enqueue_scripts', 'bodhi_svgs_inline' );
functions/mime-types.php CHANGED
@@ -15,19 +15,26 @@ if ( ! defined( 'ABSPATH' ) ) {
15
  function bodhi_svgs_upload_mimes( $mimes = array() ) {
16
 
17
  global $bodhi_svgs_options;
18
-
19
- if ( empty( $bodhi_svgs_options['restrict'] ) || current_user_can( 'administrator' ) ) {
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  // allow SVG file upload
22
  $mimes['svg'] = 'image/svg+xml';
23
  $mimes['svgz'] = 'image/svg+xml';
24
-
25
  return $mimes;
26
-
27
- } else {
28
-
29
- return $mimes;
30
-
31
  }
32
 
33
  }
15
  function bodhi_svgs_upload_mimes( $mimes = array() ) {
16
 
17
  global $bodhi_svgs_options;
18
+
19
+ $allowed_roles_array = array();
20
+ $is_role_allowed = array();
21
+
22
+ $allowed_roles_array = $bodhi_svgs_options['restrict'];
23
+
24
+ $user = wp_get_current_user();
25
+
26
+ $current_user_roles = ( array ) $user->roles;
27
+
28
+ $is_role_allowed = array_intersect($allowed_roles_array, $current_user_roles);
29
+
30
+ if( empty($is_role_allowed) ) {
31
+ return $mimes;
32
+ }
33
+ else {
34
  // allow SVG file upload
35
  $mimes['svg'] = 'image/svg+xml';
36
  $mimes['svgz'] = 'image/svg+xml';
 
37
  return $mimes;
 
 
 
 
 
38
  }
39
 
40
  }
js/cstm.js.multiselect.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready(function($) {
2
+
3
+ sanitize_svg_option_check();
4
+
5
+ $('#sanitize_svg_option input').change(function(){
6
+ sanitize_svg_option_check();
7
+ });
8
+
9
+ function sanitize_svg_option_check() {
10
+ var sanitize_svg_option = $('#sanitize_svg_option input').is(':checked');
11
+
12
+ if(sanitize_svg_option) {
13
+ $('#sanitize_svg_option_sction').slideDown("slow");
14
+ }
15
+ else {
16
+ $('#sanitize_svg_option_sction').slideUp("slow");
17
+ }
18
+
19
+ }
20
+
21
+ });
js/jquery.dropdown.js ADDED
@@ -0,0 +1,643 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;
2
+ (function ($) {
3
+ 'use strict';
4
+
5
+ function noop() { }
6
+
7
+ function throttle(func, wait, options) {
8
+ var context, args, result;
9
+ var timeout = null;
10
+ // 上次执行时间点
11
+ var previous = 0;
12
+ if (!options) options = {};
13
+ // 延迟执行函数
14
+ var later = function () {
15
+ // 若设定了开始边界不执行选项,上次执行时间始终为0
16
+ previous = options.leading === false ? 0 : new Date().getTime();
17
+ timeout = null;
18
+ result = func.apply(context, args);
19
+ if (!timeout) context = args = null;
20
+ };
21
+ return function () {
22
+ var now = new Date().getTime();
23
+ // 首次执行时,如果设定了开始边界不执行选项,将上次执行时间设定为当前时间。
24
+ if (!previous && options.leading === false) previous = now;
25
+ // 延迟执行时间间隔
26
+ var remaining = wait - (now - previous);
27
+ context = this;
28
+ args = arguments;
29
+ // 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口
30
+ // remaining大于时间窗口wait,表示客户端系统时间被调整过
31
+ if (remaining <= 0 || remaining > wait) {
32
+ clearTimeout(timeout);
33
+ timeout = null;
34
+ previous = now;
35
+ result = func.apply(context, args);
36
+ if (!timeout) context = args = null;
37
+ //如果延迟执行不存在,且没有设定结尾边界不执行选项
38
+ } else if (!timeout && options.trailing !== false) {
39
+ timeout = setTimeout(later, remaining);
40
+ }
41
+ return result;
42
+ };
43
+ }
44
+
45
+ var isSafari = function () {
46
+ var ua = navigator.userAgent.toLowerCase();
47
+ if (ua.indexOf('safari') !== -1) {
48
+ return ua.indexOf('chrome') > -1 ? false : true;
49
+ }
50
+ }();
51
+
52
+ var settings = {
53
+ readonly: false,
54
+ minCount: 0,
55
+ minCountErrorMessage: '',
56
+ limitCount: Infinity,
57
+ limitCountErrorMessage: '',
58
+ input: '<input type="text" maxLength="20" placeholder="Search...">',
59
+ data: [],
60
+ searchable: true,
61
+ searchNoData: '<li style="color:#ddd">No Results.</li>',
62
+ init: noop,
63
+ choice: noop,
64
+ extendProps: []
65
+ };
66
+
67
+ var KEY_CODE = {
68
+ up: 38,
69
+ down: 40,
70
+ enter: 13
71
+ };
72
+
73
+ var EVENT_SPACE = {
74
+ click: 'click.iui-dropdown',
75
+ focus: 'focus.iui-dropdown',
76
+ keydown: 'keydown.iui-dropdown',
77
+ keyup: 'keyup.iui-dropdown'
78
+ };
79
+
80
+ var ALERT_TIMEOUT_PERIOD = 1000;
81
+
82
+ // 创建模板
83
+ function createTemplate() {
84
+ var isLabelMode = this.isLabelMode;
85
+ var searchable = this.config.searchable;
86
+ var templateSearch = searchable ? '<span class="dropdown-search">' + this.config.input + '</span>' : '';
87
+
88
+ return isLabelMode ? '<div class="dropdown-display-label"><div class="dropdown-chose-list">' + templateSearch + '</div></div><div class="dropdown-main">{{ul}}</div>' : '<a href="javascript:;" class="dropdown-display" tabindex="0"><span class="dropdown-chose-list"></span><a href="javascript:;" class="dropdown-clear-all" tabindex="0">\xD7</a></a><div class="dropdown-main">' + templateSearch + '{{ul}}</div>';
89
+ }
90
+
91
+ // 小于minCount提示的元素
92
+ function minItemsAlert() {
93
+ var _dropdown = this;
94
+ var _config = _dropdown.config;
95
+ var $el = _dropdown.$el;
96
+ var $alert = $el.find('.dropdown-minItem-alert');
97
+ var alertMessage = _config.minCountErrorMessage;
98
+ clearTimeout(_dropdown.itemCountAlertTimer);
99
+
100
+ if ($alert.length === 0) {
101
+ if (!alertMessage) {
102
+ alertMessage = '\u6700\u4f4e\u9009\u62e9' + _config.minCount + '\u4E2A';
103
+ }
104
+ $alert = $('<div class="dropdown-minItem-alert">' + alertMessage + '</div>');
105
+ }
106
+
107
+ $el.append($alert);
108
+ _dropdown.itemCountAlertTimer = setTimeout(function () {
109
+ $el.find('.dropdown-minItem-alert').remove();
110
+ }, ALERT_TIMEOUT_PERIOD);
111
+ }
112
+
113
+ // 超出限制提示
114
+ function maxItemAlert() {
115
+ var _dropdown = this;
116
+ var _config = _dropdown.config;
117
+ var $el = _dropdown.$el;
118
+ var $alert = $el.find('.dropdown-maxItem-alert');
119
+ var alertMessage = _config.limitCountErrorMessage;
120
+ clearTimeout(_dropdown.itemLimitAlertTimer);
121
+
122
+ if ($alert.length === 0) {
123
+ if (!alertMessage) {
124
+ alertMessage = '\u6700\u591A\u53EF\u9009\u62E9' + _config.limitCount + '\u4E2A';
125
+ }
126
+ $alert = $('<div class="dropdown-maxItem-alert">' + alertMessage + '</div>');
127
+ }
128
+
129
+ $el.append($alert);
130
+ _dropdown.itemLimitAlertTimer = setTimeout(function () {
131
+ $el.find('.dropdown-maxItem-alert').remove();
132
+ }, ALERT_TIMEOUT_PERIOD);
133
+ }
134
+
135
+ // select-option 转 ul-li
136
+ function selectToDiv(str) {
137
+ var result = str || '';
138
+ // 移除select标签
139
+ result = result.replace(/<select[^>]*>/gi, '').replace('</select>', '');
140
+ // 移除 optgroup 结束标签
141
+ result = result.replace(/<\/optgroup>/gi, '');
142
+ result = result.replace(/<optgroup[^>]*>/gi, function (matcher) {
143
+ var groupName = /label="(.[^"]*)"(\s|>)/.exec(matcher);
144
+ var groupId = /data\-group\-id="(.[^"]*)"(\s|>)/.exec(matcher);
145
+ return '<li class="dropdown-group" data-group-id="' + (groupId ? groupId[1] : '') + '">' + (groupName ? groupName[1] : '') + '</li>';
146
+ });
147
+ result = result.replace(/<option(.*?)<\/option>/gi, function (matcher) {
148
+ // var value = /value="?([\w\u4E00-\u9FA5\uF900-\uFA2D]+)"?/.exec(matcher);
149
+ var value = $(matcher).val();
150
+ var name = />(.*)<\//.exec(matcher);
151
+ // 强制要求html中使用selected/disabled,而不是selected="selected","disabled="disabled"
152
+ var isSelected = matcher.indexOf('selected') > -1 ? true : false;
153
+ var isDisabled = matcher.indexOf('disabled') > -1 ? true : false;
154
+ var extendAttr = ''
155
+ var extendProps = matcher.replace(/data-(\w+)="?(.[^"]+)"?/g, function ($1) {
156
+ extendAttr += $1 + ' '
157
+ });
158
+ return '<li ' + (isDisabled ? ' disabled' : ' tabindex="0"') + ' data-value="' + (value || '') + '" class="dropdown-option ' + (isSelected ? 'dropdown-chose' : '') + '" ' + extendAttr + '>' + (name ? name[1] : '') + '</li>';
159
+ });
160
+
161
+ return result;
162
+ }
163
+
164
+ // object-data 转 select-option
165
+ function objectToSelect(data) {
166
+ var dropdown = this;
167
+ var map = {};
168
+ var result = '';
169
+ var name = [];
170
+ var selectAmount = 0;
171
+ var extendProps = dropdown.config.extendProps;
172
+
173
+ if (!data || !data.length) {
174
+ return false;
175
+ }
176
+
177
+ $.each(data, function (index, val) {
178
+ // disable 权重高于 selected
179
+ var hasGroup = val.groupId;
180
+ var isDisabled = val.disabled ? ' disabled' : '';
181
+ var isSelected = val.selected && !isDisabled ? ' selected' : '';
182
+ var extendAttr = ''
183
+ $.each(extendProps, function (index, value) {
184
+ if (val[value]) {
185
+ extendAttr += 'data-' + value + '="' + val[value] + '" '
186
+ }
187
+ })
188
+ var temp = '<option' + isDisabled + isSelected + ' value="' + val.id + '" ' + extendAttr + '>' + val.name + '</option>';
189
+ if (isSelected) {
190
+ name.push('<span class="dropdown-selected">' + val.name + '<i class="del" data-id="' + val.id + '"></i></span>');
191
+ selectAmount++;
192
+ }
193
+ // 判断是否有分组
194
+ if (hasGroup) {
195
+ if (map[val.groupId]) {
196
+ map[val.groupId] += temp;
197
+ } else {
198
+ // &janking& just a separator
199
+ map[val.groupId] = val.groupName + '&janking&' + temp;
200
+ }
201
+ } else {
202
+ map[index] = temp;
203
+ }
204
+ });
205
+
206
+ $.each(map, function (index, val) {
207
+ var option = val.split('&janking&');
208
+ // 判断是否有分组
209
+ if (option.length === 2) {
210
+ var groupName = option[0];
211
+ var items = option[1];
212
+ result += '<optgroup label="' + groupName + '" data-group-id="' + index + '">' + items + '</optgroup>';
213
+ } else {
214
+ result += val;
215
+ }
216
+ });
217
+
218
+ return [result, name, selectAmount];
219
+ }
220
+
221
+ // select-option 转 object-data
222
+ //
223
+ function selectToObject(el) {
224
+ var $select = el;
225
+ var result = [];
226
+
227
+ function readOption(key, el) {
228
+ var $option = $(el);
229
+ this.id = $option.prop('value');
230
+ this.name = $option.text();
231
+ this.disabled = $option.prop('disabled');
232
+ this.selected = $option.prop('selected');
233
+ }
234
+
235
+ $.each($select.children(), function (key, el) {
236
+ var tmp = {};
237
+ var tmpGroup = {};
238
+ var $el = $(el);
239
+ if (el.nodeName === 'OPTGROUP') {
240
+ tmpGroup.groupId = $el.data('groupId');
241
+ tmpGroup.groupName = $el.attr('label');
242
+ $.each($el.children(), $.proxy(readOption, tmp));
243
+ $.extend(tmp, tmpGroup);
244
+ } else {
245
+ $.each($el, $.proxy(readOption, tmp));
246
+ }
247
+ result.push(tmp);
248
+ });
249
+
250
+ return result;
251
+ }
252
+
253
+ var action = {
254
+ show: function (event) {
255
+ event.stopPropagation();
256
+ var _dropdown = this;
257
+ $(document).trigger('click.dropdown');
258
+ _dropdown.$el.addClass('active');
259
+ },
260
+ search: throttle(function (event) {
261
+ var _dropdown = this;
262
+ var _config = _dropdown.config;
263
+ var $el = _dropdown.$el;
264
+ var $input = $(event.target);
265
+ var intputValue = $input.val();
266
+ var data = _dropdown.config.data;
267
+ var result = [];
268
+ if (event.keyCode > 36 && event.keyCode < 41) {
269
+ return;
270
+ }
271
+ $.each(data, function (key, value) {
272
+ if ((value.groupName && value.groupName.toLowerCase().indexOf(intputValue.toLowerCase()) > -1) || value.name.toLowerCase().indexOf(intputValue.toLowerCase()) > -1 || '' + value.id === '' + intputValue) {
273
+ result.push(value);
274
+ }
275
+ });
276
+ $el.find('ul').html(selectToDiv(objectToSelect.call(_dropdown, result)[0]) || _config.searchNoData);
277
+ }, 300),
278
+ control: function (event) {
279
+ var keyCode = event.keyCode;
280
+ var KC = KEY_CODE;
281
+ var index = 0;
282
+ var direct;
283
+ var itemIndex;
284
+ var $items;
285
+ if (keyCode === KC.down || keyCode === KC.up) {
286
+ // 方向
287
+ direct = keyCode === KC.up ? -1 : 1;
288
+ $items = this.$el.find('[tabindex]');
289
+ itemIndex = $items.index($(document.activeElement));
290
+ // 初始
291
+ if (itemIndex === -1) {
292
+ index = direct + 1 ? -1 : 0;
293
+ } else {
294
+ index = itemIndex;
295
+ }
296
+ // 确认位序
297
+ index = index + direct;
298
+ // 最后位循环
299
+ if (index === $items.length) {
300
+ index = 0;
301
+ }
302
+ $items.eq(index).focus();
303
+ event.preventDefault();
304
+ }
305
+ },
306
+ multiChoose: function (event, status) {
307
+ var _dropdown = this;
308
+ var _config = _dropdown.config;
309
+ var $select = _dropdown.$select;
310
+ var $target = $(event.target);
311
+ var value = $target.attr('data-value');
312
+ var hasSelected = $target.hasClass('dropdown-chose');
313
+ var selectedName = [];
314
+ var selectedProp;
315
+
316
+ if ($target.hasClass('dropdown-display')) {
317
+ return false;
318
+ }
319
+
320
+ if (hasSelected) {
321
+ $target.removeClass('dropdown-chose');
322
+ _dropdown.selectAmount--;
323
+ } else {
324
+ if (_dropdown.selectAmount < _config.limitCount) {
325
+ $target.addClass('dropdown-chose');
326
+ _dropdown.selectAmount++;
327
+ } else {
328
+ maxItemAlert.call(_dropdown);
329
+ return false;
330
+ }
331
+ }
332
+
333
+ _dropdown.name = [];
334
+
335
+ $.each(_config.data, function (key, item) {
336
+ if ('' + item.id === '' + value) {
337
+ selectedProp = item;
338
+ item.selected = hasSelected ? false : true;
339
+ }
340
+ if (item.selected) {
341
+ selectedName.push(item.name);
342
+ _dropdown.name.push('<span class="dropdown-selected">' + item.name + '<i class="del" data-id="' + item.id + '"></i></span>');
343
+ }
344
+ });
345
+
346
+ $select.find('option[value="' + value + '"]').prop('selected', hasSelected ? false : true);
347
+
348
+ if (hasSelected && _dropdown.selectAmount < _config.minCount) {
349
+ minItemsAlert.call(_dropdown);
350
+ }
351
+
352
+ _dropdown.$choseList.find('.dropdown-selected').remove();
353
+ _dropdown.$choseList.prepend(_dropdown.name.join(''));
354
+ _dropdown.$el.find('.dropdown-display').attr('title', selectedName.join(','));
355
+ _config.choice.call(_dropdown, event, selectedProp);
356
+ },
357
+ singleChoose: function (event) {
358
+ var _dropdown = this;
359
+ var _config = _dropdown.config;
360
+ var $el = _dropdown.$el;
361
+ var $select = _dropdown.$select;
362
+ var $target = $(event.target);
363
+ var value = $target.attr('data-value');
364
+ var hasSelected = $target.hasClass('dropdown-chose');
365
+
366
+ if ($target.hasClass('dropdown-chose') || $target.hasClass('dropdown-display')) {
367
+ return false;
368
+ }
369
+
370
+ _dropdown.name = [];
371
+
372
+
373
+ $el.removeClass('active').find('li').not($target).removeClass('dropdown-chose');
374
+
375
+ $target.toggleClass('dropdown-chose');
376
+ $.each(_config.data, function (key, item) {
377
+ // id 有可能是数字也有可能是字符串,强制全等有弊端 2017-03-20 22:19:21
378
+ item.selected = false;
379
+ if ('' + item.id === '' + value) {
380
+ item.selected = hasSelected ? 0 : 1;
381
+ if (item.selected) {
382
+ _dropdown.name.push('<span class="dropdown-selected">' + item.name + '<i class="del" data-id="' + item.id + '"></i></span>');
383
+ }
384
+ }
385
+ });
386
+
387
+ $select.find('option[value="' + value + '"]').prop('selected', true);
388
+
389
+ _dropdown.name.push('<span class="placeholder">' + _dropdown.placeholder + '</span>');
390
+ _dropdown.$choseList.html(_dropdown.name.join(''));
391
+ _config.choice.call(_dropdown, event);
392
+ },
393
+ del: function (event) {
394
+ var _dropdown = this;
395
+ var _config = _dropdown.config;
396
+ var $target = $(event.target);
397
+ var id = $target.data('id');
398
+ // 2017-03-23 15:58:50 测试
399
+ // 10000条数据测试删除,耗时 ~3ms
400
+ $.each(_dropdown.name, function (key, value) {
401
+ if (value.indexOf('data-id="' + id + '"') !== -1) {
402
+ _dropdown.name.splice(key, 1);
403
+ return false;
404
+ }
405
+ });
406
+
407
+ $.each(_dropdown.config.data, function (key, item) {
408
+ if ('' + item.id == '' + id) {
409
+ item.selected = false;
410
+ return false;
411
+ }
412
+ });
413
+
414
+ _dropdown.selectAmount--;
415
+ _dropdown.$el.find('[data-value="' + id + '"]').removeClass('dropdown-chose');
416
+ _dropdown.$el.find('[value="' + id + '"]').prop('selected', false).removeAttr('selected');
417
+ $target.closest('.dropdown-selected').remove();
418
+ _config.choice.call(_dropdown, event);
419
+
420
+ return false;
421
+ },
422
+ clearAll: function (event) {
423
+ var _dropdown = this;
424
+ var _config = _dropdown.config;
425
+ event && event.preventDefault();
426
+ console.log(this)
427
+ this.$choseList.find('.del').each(function (index, el) {
428
+ $(el).trigger('click');
429
+ });
430
+
431
+ if (_config.minCount > 0) {
432
+ minItemsAlert.call(_dropdown);
433
+ }
434
+
435
+ this.$el.find('.dropdown-display').removeAttr('title');
436
+ return false;
437
+ }
438
+ };
439
+
440
+ function Dropdown(options, el) {
441
+ this.$el = $(el);
442
+ this.$select = this.$el.find('select');
443
+ this.placeholder = this.$select.attr('placeholder');
444
+ this.config = options;
445
+ this.name = [];
446
+ this.isSingleSelect = !this.$select.prop('multiple');
447
+ this.selectAmount = 0;
448
+ this.itemLimitAlertTimer = null;
449
+ this.isLabelMode = this.config.multipleMode === 'label';
450
+ this.init();
451
+ }
452
+
453
+ Dropdown.prototype = {
454
+ init: function () {
455
+ var _this = this;
456
+ var _config = _this.config;
457
+ var $el = _this.$el;
458
+ _this.$select.hide();
459
+ // 判断dropdown是否单选,是否token模式
460
+ $el.addClass(_this.isSingleSelect ? 'dropdown-single' : _this.isLabelMode ? 'dropdown-multiple-label' : 'dropdown-multiple');
461
+
462
+ if (_config.data.length === 0) {
463
+ _config.data = selectToObject(_this.$select);
464
+ }
465
+
466
+ var processResult = objectToSelect.call(_this, _config.data);
467
+
468
+ _this.name = processResult[1];
469
+ _this.selectAmount = processResult[2];
470
+ _this.$select.html(processResult[0]);
471
+ _this.renderSelect();
472
+ // disabled权重高于readonly
473
+ _this.changeStatus(_config.disabled ? 'disabled' : _config.readonly ? 'readonly' : false);
474
+
475
+ _this.config.init();
476
+ },
477
+ // 渲染 select 为 dropdown
478
+ renderSelect: function (isUpdate, isCover) {
479
+ var _this = this;
480
+ var $el = _this.$el;
481
+ var $select = _this.$select;
482
+ var elemLi = selectToDiv($select.prop('outerHTML'));
483
+ var template;
484
+
485
+ if (isUpdate) {
486
+ $el.find('ul')[isCover ? 'html' : 'append'](elemLi);
487
+ } else {
488
+ template = createTemplate.call(_this).replace('{{ul}}', '<ul>' + elemLi + '</ul>');
489
+ $el.append(template).find('ul').removeAttr('style class');
490
+ }
491
+
492
+ if (isCover) {
493
+ _this.name = [];
494
+ _this.$el.find('.dropdown-selected').remove();
495
+ _this.$select.val('');
496
+ }
497
+
498
+ _this.$choseList = $el.find('.dropdown-chose-list');
499
+
500
+ if (!_this.isLabelMode) {
501
+ _this.$choseList.html($('<span class="placeholder"></span>').text(_this.placeholder));
502
+ }
503
+
504
+ _this.$choseList.prepend(_this.name ? _this.name.join('') : []);
505
+ },
506
+ bindEvent: function () {
507
+ var _this = this;
508
+ var $el = _this.$el;
509
+ var openHandle = isSafari ? EVENT_SPACE.click : EVENT_SPACE.focus;
510
+
511
+ $el.on(EVENT_SPACE.click, function (event) {
512
+ event.stopPropagation();
513
+ });
514
+
515
+ $el.on(EVENT_SPACE.click, '.del', $.proxy(action.del, _this));
516
+
517
+ // show
518
+ if (_this.isLabelMode) {
519
+ $el.on(EVENT_SPACE.click, '.dropdown-display-label', function () {
520
+ $el.find('input').focus();
521
+ });
522
+ if (_this.config.searchable) {
523
+ $el.on(EVENT_SPACE.focus, 'input', $.proxy(action.show, _this));
524
+ } else {
525
+ $el.on(EVENT_SPACE.click, $.proxy(action.show, _this));
526
+ }
527
+ $el.on(EVENT_SPACE.keydown, 'input', function (event) {
528
+ if (event.keyCode === 8 && this.value === '' && _this.name.length) {
529
+ $el.find('.del').eq(-1).trigger('click');
530
+ }
531
+ });
532
+ } else {
533
+ $el.on(openHandle, '.dropdown-display', $.proxy(action.show, _this));
534
+ $el.on(openHandle, '.dropdown-clear-all', $.proxy(action.clearAll, _this));
535
+ }
536
+
537
+ // 搜索
538
+ $el.on(EVENT_SPACE.keyup, 'input', $.proxy(action.search, _this));
539
+
540
+ // 按下enter键设置token
541
+ $el.on(EVENT_SPACE.keyup, function (event) {
542
+ var keyCode = event.keyCode;
543
+ var KC = KEY_CODE;
544
+ if (keyCode === KC.enter) {
545
+ $.proxy(_this.isSingleSelect ? action.singleChoose : action.multiChoose, _this, event)();
546
+ }
547
+ });
548
+
549
+ // 按下上下键切换token
550
+ $el.on(EVENT_SPACE.keydown, $.proxy(action.control, _this));
551
+
552
+ $el.on(EVENT_SPACE.click, 'li[tabindex]', $.proxy(_this.isSingleSelect ? action.singleChoose : action.multiChoose, _this));
553
+ },
554
+ unbindEvent: function () {
555
+ var _this = this;
556
+ var $el = _this.$el;
557
+ var openHandle = isSafari ? EVENT_SPACE.click : EVENT_SPACE.focus;
558
+
559
+ $el.off(EVENT_SPACE.click);
560
+ $el.off(EVENT_SPACE.click, '.del');
561
+
562
+ // show
563
+ if (_this.isLabelMode) {
564
+ $el.off(EVENT_SPACE.click, '.dropdown-display-label');
565
+ $el.off(EVENT_SPACE.focus, 'input');
566
+ $el.off(EVENT_SPACE.keydown, 'input');
567
+ } else {
568
+ $el.off(openHandle, '.dropdown-display');
569
+ $el.off(openHandle, '.dropdown-clear-all');
570
+ }
571
+ // 搜索
572
+ $el.off(EVENT_SPACE.keyup, 'input');
573
+ // 按下enter键设置token
574
+ $el.off(EVENT_SPACE.keyup);
575
+ // 按下上下键切换token
576
+ $el.off(EVENT_SPACE.keydown);
577
+ $el.off(EVENT_SPACE.click, '[tabindex]');
578
+ },
579
+ changeStatus: function (status) {
580
+ var _this = this;
581
+ if (status === 'readonly') {
582
+ _this.unbindEvent();
583
+ } else if (status === 'disabled') {
584
+ _this.$select.prop('disabled', true);
585
+ _this.unbindEvent();
586
+ } else {
587
+ _this.$select.prop('disabled', false);
588
+ _this.bindEvent();
589
+ }
590
+ },
591
+ update: function (data, isCover) {
592
+ var _this = this;
593
+ var _config = _this.config;
594
+ var $el = _this.$el;
595
+ var _isCover = isCover || false;
596
+
597
+ if (Object.prototype.toString.call(data) !== '[object Array]') {
598
+ return;
599
+ }
600
+
601
+ _config.data = _isCover ? data.slice(0) : _config.data.concat(data);
602
+
603
+ var processResult = objectToSelect.call(_this, _config.data);
604
+
605
+ _this.name = processResult[1];
606
+ _this.selectAmount = processResult[2];
607
+ _this.$select.html(processResult[0]);
608
+ _this.renderSelect(true, _isCover);
609
+ },
610
+ destroy: function () {
611
+ this.unbindEvent();
612
+ this.$el.children().not('select').remove();
613
+ this.$el.removeClass('dropdown-single dropdown-multiple-label dropdown-multiple');
614
+ this.$select.show();
615
+ },
616
+ choose: function (values, status) {
617
+ var valArr = Object.prototype.toString.call(values) === '[object Array]' ? values : [values];
618
+ var _this = this;
619
+ var _status = status !== void 0 ? !!status : true
620
+ $.each(valArr, function (index, value) {
621
+ var $target = _this.$el.find('[data-value="' + value + '"]');
622
+ var targetStatus = $target.hasClass('dropdown-chose');
623
+ if (targetStatus !== _status) {
624
+ $target.trigger(EVENT_SPACE.click, status || true)
625
+ }
626
+ });
627
+ },
628
+ reset: function () {
629
+ action.clearAll.call(this)
630
+ }
631
+ };
632
+
633
+ $(document).on('click.dropdown', function () {
634
+ $('.dropdown-single,.dropdown-multiple,.dropdown-multiple-label').removeClass('active');
635
+ });
636
+
637
+ $.fn.dropdown = function (options) {
638
+ this.each(function (index, el) {
639
+ $(el).data('dropdown', new Dropdown($.extend(true, {}, settings, options), el));
640
+ });
641
+ return this;
642
+ }
643
+ })(jQuery);
js/min/cstm.js.multiselect-min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready((function($){function i(){var i;$("#sanitize_svg_option input").is(":checked")?$("#sanitize_svg_option_sction").slideDown("slow"):$("#sanitize_svg_option_sction").slideUp("slow")}i(),$("#sanitize_svg_option input").change((function(){i()}))}));
js/min/jquery.dropdown-min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function(e){"use strict";function o(){}function n(e,o,n){var t,i,l,a=null,d=0;n||(n={});var s=function(){d=n.leading===!1?0:(new Date).getTime(),a=null,l=e.apply(t,i),a||(t=i=null)};return function(){var r=(new Date).getTime();d||n.leading!==!1||(d=r);var c=o-(r-d);return t=this,i=arguments,c<=0||c>o?(clearTimeout(a),a=null,d=r,l=e.apply(t,i),a||(t=i=null)):a||n.trailing===!1||(a=setTimeout(s,c)),l}}function t(){var e=this.isLabelMode,o=this.config.searchable,n=o?'<span class="dropdown-search">'+this.config.input+"</span>":"";return e?'<div class="dropdown-display-label"><div class="dropdown-chose-list">'+n+'</div></div><div class="dropdown-main">{{ul}}</div>':'<a href="javascript:;" class="dropdown-display" tabindex="0"><span class="dropdown-chose-list"></span><a href="javascript:;" class="dropdown-clear-all" tabindex="0">×</a></a><div class="dropdown-main">'+n+"{{ul}}</div>"}function i(){var o=this,n=o.config,t=o.$el,i=t.find(".dropdown-minItem-alert"),l=n.minCountErrorMessage;clearTimeout(o.itemCountAlertTimer),0===i.length&&(l||(l="最低选择"+n.minCount+"个"),i=e('<div class="dropdown-minItem-alert">'+l+"</div>")),t.append(i),o.itemCountAlertTimer=setTimeout(function(){t.find(".dropdown-minItem-alert").remove()},f)}function l(){var o=this,n=o.config,t=o.$el,i=t.find(".dropdown-maxItem-alert"),l=n.limitCountErrorMessage;clearTimeout(o.itemLimitAlertTimer),0===i.length&&(l||(l="最多可选择"+n.limitCount+"个"),i=e('<div class="dropdown-maxItem-alert">'+l+"</div>")),t.append(i),o.itemLimitAlertTimer=setTimeout(function(){t.find(".dropdown-maxItem-alert").remove()},f)}function a(o){var n=o||"";return n=n.replace(/<select[^>]*>/gi,"").replace("</select>",""),n=n.replace(/<\/optgroup>/gi,""),n=n.replace(/<optgroup[^>]*>/gi,function(e){var o=/label="(.[^"]*)"(\s|>)/.exec(e),n=/data\-group\-id="(.[^"]*)"(\s|>)/.exec(e);return'<li class="dropdown-group" data-group-id="'+(n?n[1]:"")+'">'+(o?o[1]:"")+"</li>"}),n=n.replace(/<option(.*?)<\/option>/gi,function(o){var n=e(o).val(),t=/>(.*)<\//.exec(o),i=o.indexOf("selected")>-1,l=o.indexOf("disabled")>-1,a="";o.replace(/data-(\w+)="?(.[^"]+)"?/g,function(e){a+=e+" "});return"<li "+(l?" disabled":' tabindex="0"')+' data-value="'+(n||"")+'" class="dropdown-option '+(i?"dropdown-chose":"")+'" '+a+">"+(t?t[1]:"")+"</li>"})}function d(o){var n=this,t={},i="",l=[],a=0,d=n.config.extendProps;return!(!o||!o.length)&&(e.each(o,function(o,n){var i=n.groupId,s=n.disabled?" disabled":"",r=n.selected&&!s?" selected":"",c="";e.each(d,function(e,o){n[o]&&(c+="data-"+o+'="'+n[o]+'" ')});var p="<option"+s+r+' value="'+n.id+'" '+c+">"+n.name+"</option>";r&&(l.push('<span class="dropdown-selected">'+n.name+'<i class="del" data-id="'+n.id+'"></i></span>'),a++),i?t[n.groupId]?t[n.groupId]+=p:t[n.groupId]=n.groupName+"&janking&"+p:t[o]=p}),e.each(t,function(e,o){var n=o.split("&janking&");if(2===n.length){var t=n[0],l=n[1];i+='<optgroup label="'+t+'" data-group-id="'+e+'">'+l+"</optgroup>"}else i+=o}),[i,l,a])}function s(o){function n(o,n){var t=e(n);this.id=t.prop("value"),this.name=t.text(),this.disabled=t.prop("disabled"),this.selected=t.prop("selected")}var t=o,i=[];return e.each(t.children(),function(o,t){var l={},a={},d=e(t);"OPTGROUP"===t.nodeName?(a.groupId=d.data("groupId"),a.groupName=d.attr("label"),e.each(d.children(),e.proxy(n,l)),e.extend(l,a)):e.each(d,e.proxy(n,l)),i.push(l)}),i}function r(o,n){this.$el=e(n),this.$select=this.$el.find("select"),this.placeholder=this.$select.attr("placeholder"),this.config=o,this.name=[],this.isSingleSelect=!this.$select.prop("multiple"),this.selectAmount=0,this.itemLimitAlertTimer=null,this.isLabelMode="label"===this.config.multipleMode,this.init()}var c=function(){var e=navigator.userAgent.toLowerCase();if(e.indexOf("safari")!==-1)return!(e.indexOf("chrome")>-1)}(),p={readonly:!1,minCount:0,minCountErrorMessage:"",limitCount:1/0,limitCountErrorMessage:"",input:'<input type="text" maxLength="20" placeholder="搜索关键词或ID">',data:[],searchable:!0,searchNoData:'<li style="color:#ddd">查无数据,换个词儿试试 /(ㄒoㄒ)/~~</li>',init:o,choice:o,extendProps:[]},u={up:38,down:40,enter:13},h={click:"click.iui-dropdown",focus:"focus.iui-dropdown",keydown:"keydown.iui-dropdown",keyup:"keyup.iui-dropdown"},f=1e3,m={show:function(o){o.stopPropagation();var n=this;e(document).trigger("click.dropdown"),n.$el.addClass("active")},search:n(function(o){var n=this,t=n.config,i=n.$el,l=e(o.target),s=l.val(),r=n.config.data,c=[];o.keyCode>36&&o.keyCode<41||(e.each(r,function(e,o){(o.groupName&&o.groupName.toLowerCase().indexOf(s.toLowerCase())>-1||o.name.toLowerCase().indexOf(s.toLowerCase())>-1||""+o.id==""+s)&&c.push(o)}),i.find("ul").html(a(d.call(n,c)[0])||t.searchNoData))},300),control:function(o){var n,t,i,l=o.keyCode,a=u,d=0;l!==a.down&&l!==a.up||(n=l===a.up?-1:1,i=this.$el.find("[tabindex]"),t=i.index(e(document.activeElement)),d=t===-1?n+1?-1:0:t,d+=n,d===i.length&&(d=0),i.eq(d).focus(),o.preventDefault())},multiChoose:function(o,n){var t,a=this,d=a.config,s=a.$select,r=e(o.target),c=r.attr("data-value"),p=r.hasClass("dropdown-chose"),u=[];if(r.hasClass("dropdown-display"))return!1;if(p)r.removeClass("dropdown-chose"),a.selectAmount--;else{if(!(a.selectAmount<d.limitCount))return l.call(a),!1;r.addClass("dropdown-chose"),a.selectAmount++}a.name=[],e.each(d.data,function(e,o){""+o.id==""+c&&(t=o,o.selected=!p),o.selected&&(u.push(o.name),a.name.push('<span class="dropdown-selected">'+o.name+'<i class="del" data-id="'+o.id+'"></i></span>'))}),s.find('option[value="'+c+'"]').prop("selected",!p),p&&a.selectAmount<d.minCount&&i.call(a),a.$choseList.find(".dropdown-selected").remove(),a.$choseList.prepend(a.name.join("")),a.$el.find(".dropdown-display").attr("title",u.join(",")),d.choice.call(a,o,t)},singleChoose:function(o){var n=this,t=n.config,i=n.$el,l=n.$select,a=e(o.target),d=a.attr("data-value"),s=a.hasClass("dropdown-chose");return!a.hasClass("dropdown-chose")&&!a.hasClass("dropdown-display")&&(n.name=[],i.removeClass("active").find("li").not(a).removeClass("dropdown-chose"),a.toggleClass("dropdown-chose"),e.each(t.data,function(e,o){o.selected=!1,""+o.id==""+d&&(o.selected=s?0:1,o.selected&&n.name.push('<span class="dropdown-selected">'+o.name+'<i class="del" data-id="'+o.id+'"></i></span>'))}),l.find('option[value="'+d+'"]').prop("selected",!0),n.name.push('<span class="placeholder">'+n.placeholder+"</span>"),n.$choseList.html(n.name.join("")),void t.choice.call(n,o))},del:function(o){var n=this,t=n.config,i=e(o.target),l=i.data("id");return e.each(n.name,function(e,o){if(o.indexOf('data-id="'+l+'"')!==-1)return n.name.splice(e,1),!1}),e.each(n.config.data,function(e,o){if(""+o.id==""+l)return o.selected=!1,!1}),n.selectAmount--,n.$el.find('[data-value="'+l+'"]').removeClass("dropdown-chose"),n.$el.find('[value="'+l+'"]').prop("selected",!1).removeAttr("selected"),i.closest(".dropdown-selected").remove(),t.choice.call(n,o),!1},clearAll:function(o){var n=this,t=n.config;return o&&o.preventDefault(),console.log(this),this.$choseList.find(".del").each(function(o,n){e(n).trigger("click")}),t.minCount>0&&i.call(n),this.$el.find(".dropdown-display").removeAttr("title"),!1}};r.prototype={init:function(){var e=this,o=e.config,n=e.$el;e.$select.hide(),n.addClass(e.isSingleSelect?"dropdown-single":e.isLabelMode?"dropdown-multiple-label":"dropdown-multiple"),0===o.data.length&&(o.data=s(e.$select));var t=d.call(e,o.data);e.name=t[1],e.selectAmount=t[2],e.$select.html(t[0]),e.renderSelect(),e.changeStatus(o.disabled?"disabled":!!o.readonly&&"readonly"),e.config.init()},renderSelect:function(o,n){var i,l=this,d=l.$el,s=l.$select,r=a(s.prop("outerHTML"));o?d.find("ul")[n?"html":"append"](r):(i=t.call(l).replace("{{ul}}","<ul>"+r+"</ul>"),d.append(i).find("ul").removeAttr("style class")),n&&(l.name=[],l.$el.find(".dropdown-selected").remove(),l.$select.val("")),l.$choseList=d.find(".dropdown-chose-list"),l.isLabelMode||l.$choseList.html(e('<span class="placeholder"></span>').text(l.placeholder)),l.$choseList.prepend(l.name?l.name.join(""):[])},bindEvent:function(){var o=this,n=o.$el,t=c?h.click:h.focus;n.on(h.click,function(e){e.stopPropagation()}),n.on(h.click,".del",e.proxy(m.del,o)),o.isLabelMode?(n.on(h.click,".dropdown-display-label",function(){n.find("input").focus()}),o.config.searchable?n.on(h.focus,"input",e.proxy(m.show,o)):n.on(h.click,e.proxy(m.show,o)),n.on(h.keydown,"input",function(e){8===e.keyCode&&""===this.value&&o.name.length&&n.find(".del").eq(-1).trigger("click")})):(n.on(t,".dropdown-display",e.proxy(m.show,o)),n.on(t,".dropdown-clear-all",e.proxy(m.clearAll,o))),n.on(h.keyup,"input",e.proxy(m.search,o)),n.on(h.keyup,function(n){var t=n.keyCode,i=u;t===i.enter&&e.proxy(o.isSingleSelect?m.singleChoose:m.multiChoose,o,n)()}),n.on(h.keydown,e.proxy(m.control,o)),n.on(h.click,"li[tabindex]",e.proxy(o.isSingleSelect?m.singleChoose:m.multiChoose,o))},unbindEvent:function(){var e=this,o=e.$el,n=c?h.click:h.focus;o.off(h.click),o.off(h.click,".del"),e.isLabelMode?(o.off(h.click,".dropdown-display-label"),o.off(h.focus,"input"),o.off(h.keydown,"input")):(o.off(n,".dropdown-display"),o.off(n,".dropdown-clear-all")),o.off(h.keyup,"input"),o.off(h.keyup),o.off(h.keydown),o.off(h.click,"[tabindex]")},changeStatus:function(e){var o=this;"readonly"===e?o.unbindEvent():"disabled"===e?(o.$select.prop("disabled",!0),o.unbindEvent()):(o.$select.prop("disabled",!1),o.bindEvent())},update:function(e,o){var n=this,t=n.config,i=(n.$el,o||!1);if("[object Array]"===Object.prototype.toString.call(e)){t.data=i?e.slice(0):t.data.concat(e);var l=d.call(n,t.data);n.name=l[1],n.selectAmount=l[2],n.$select.html(l[0]),n.renderSelect(!0,i)}},destroy:function(){this.unbindEvent(),this.$el.children().not("select").remove(),this.$el.removeClass("dropdown-single dropdown-multiple-label dropdown-multiple"),this.$select.show()},choose:function(o,n){var t="[object Array]"===Object.prototype.toString.call(o)?o:[o],i=this,l=void 0===n||!!n;e.each(t,function(e,o){var t=i.$el.find('[data-value="'+o+'"]'),a=t.hasClass("dropdown-chose");a!==l&&t.trigger(h.click,n||!0)})},reset:function(){m.clearAll.call(this)}},e(document).on("click.dropdown",function(){e(".dropdown-single,.dropdown-multiple,.dropdown-multiple-label").removeClass("active")}),e.fn.dropdown=function(o){return this.each(function(n,t){e(t).data("dropdown",new r(e.extend(!0,{},p,o),t))}),this}})(jQuery);
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: Benbodhi
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ
4
  Tags: svg, vector, safesvg, safe svg, sanitization, sanitisation, sanitizer, sanitiser, sanitized, sanitised, sanitize, sanitise, css, style, mime, mime type, embed, img, render, inline, animation, animation, animate, js
5
  Requires at least: 4.8
6
- Tested up to: 6.0
7
  Requires PHP: 7.2
8
- Stable tag: 2.5.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -161,6 +161,9 @@ You need to add the mime type for svg and svgz to: "MLA Settings > Media Library
161
 
162
  == Changelog ==
163
 
 
 
 
164
  = 2.5.1 =
165
  * Added missing quotes in uninstall.php.
166
 
@@ -381,6 +384,10 @@ You need to add the mime type for svg and svgz to: "MLA Settings > Media Library
381
 
382
  == Upgrade Notice ==
383
 
 
 
 
 
384
  = 2.5.1 =
385
  2.5 Adds new features and addresses a number of recent issues raised. Please take a backup before updating!
386
  2.5.1 fixes the uninstall file.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ
4
  Tags: svg, vector, safesvg, safe svg, sanitization, sanitisation, sanitizer, sanitiser, sanitized, sanitised, sanitize, sanitise, css, style, mime, mime type, embed, img, render, inline, animation, animation, animate, js
5
  Requires at least: 4.8
6
+ Tested up to: 6.1.1
7
  Requires PHP: 7.2
8
+ Stable tag: 2.5.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
161
 
162
  == Changelog ==
163
 
164
+ = 2.5.2 =
165
+ * Added some defaults for better security by default.
166
+
167
  = 2.5.1 =
168
  * Added missing quotes in uninstall.php.
169
 
384
 
385
  == Upgrade Notice ==
386
 
387
+ = 2.5.2 =
388
+ Updating to 2.5+ Adds new features and addresses a number of earlier issues raised. Please take a backup before updating!
389
+ 2.5.2 introduces some defaults for better security.
390
+
391
  = 2.5.1 =
392
  2.5 Adds new features and addresses a number of recent issues raised. Please take a backup before updating!
393
  2.5.1 fixes the uninstall file.
scss/jquery.dropdown.scss ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @-webkit-keyframes iui-fadeIn {
2
+ 0% {
3
+ opacity: 0
4
+ }
5
+ 100% {
6
+ opacity: 1
7
+ }
8
+ }
9
+
10
+ @-moz-keyframes iui-fadeIn {
11
+ 0% {
12
+ opacity: 0
13
+ }
14
+ 100% {
15
+ opacity: 1
16
+ }
17
+ }
18
+
19
+ @-ms-keyframes iui-fadeIn {
20
+ 0% {
21
+ opacity: 0
22
+ }
23
+ 100% {
24
+ opacity: 1
25
+ }
26
+ }
27
+
28
+ @-o-keyframes iui-fadeIn {
29
+ 0% {
30
+ opacity: 0
31
+ }
32
+ 100% {
33
+ opacity: 1
34
+ }
35
+ }
36
+
37
+ @keyframes iui-fadeIn {
38
+ 0% {
39
+ opacity: 0
40
+ }
41
+ 100% {
42
+ opacity: 1
43
+ }
44
+ }
45
+
46
+ @-webkit-keyframes iui-fadeOut {
47
+ 0% {
48
+ opacity: 1
49
+ }
50
+ 100% {
51
+ opacity: 0
52
+ }
53
+ }
54
+
55
+ @-moz-keyframes iui-fadeOut {
56
+ 0% {
57
+ opacity: 1
58
+ }
59
+ 100% {
60
+ opacity: 0
61
+ }
62
+ }
63
+
64
+ @-ms-keyframes iui-fadeOut {
65
+ 0% {
66
+ opacity: 1
67
+ }
68
+ 100% {
69
+ opacity: 0
70
+ }
71
+ }
72
+
73
+ @-o-keyframes iui-fadeOut {
74
+ 0% {
75
+ opacity: 1
76
+ }
77
+ 100% {
78
+ opacity: 0
79
+ }
80
+ }
81
+
82
+ @keyframes iui-fadeOut {
83
+ 0% {
84
+ opacity: 1
85
+ }
86
+ 100% {
87
+ opacity: 0
88
+ }
89
+ }
90
+
91
+ .dropdown-multiple,
92
+ .dropdown-multiple-label,
93
+ .dropdown-single {
94
+ position: relative
95
+ }
96
+
97
+ .dropdown-multiple-label.active .dropdown-main,
98
+ .dropdown-multiple.active .dropdown-main,
99
+ .dropdown-single.active .dropdown-main {
100
+ display: block;
101
+ -webkit-animation: iui-fadeIn .2s ease-in forwards;
102
+ -moz-animation: iui-fadeIn .2s ease-in forwards;
103
+ -ms-animation: iui-fadeIn .2s ease-in forwards;
104
+ -o-animation: iui-fadeIn .2s ease-in forwards;
105
+ animation: iui-fadeIn .2s ease-in forwards
106
+ }
107
+
108
+ .dropdown-multiple-label.active .dropdown-display-label:after,
109
+ .dropdown-multiple-label.active .dropdown-display:after,
110
+ .dropdown-multiple.active .dropdown-display-label:after,
111
+ .dropdown-multiple.active .dropdown-display:after,
112
+ .dropdown-single.active .dropdown-display-label:after,
113
+ .dropdown-single.active .dropdown-display:after {
114
+ border-top: none;
115
+ border-bottom: 10px solid #999;
116
+ border-left: 5px solid transparent;
117
+ border-right: 5px solid transparent
118
+ }
119
+
120
+ .dropdown-multiple-label.active .dropdown-display,
121
+ .dropdown-multiple-label.active .dropdown-display-label,
122
+ .dropdown-multiple.active .dropdown-display,
123
+ .dropdown-multiple.active .dropdown-display-label,
124
+ .dropdown-single.active .dropdown-display,
125
+ .dropdown-single.active .dropdown-display-label {
126
+ border-bottom-left-radius: 0;
127
+ border-bottom-right-radius: 0
128
+ }
129
+
130
+ .dropdown-display,
131
+ .dropdown-display-label {
132
+ position: relative;
133
+ display: block;
134
+ margin-bottom: 0;
135
+ font-size: 14px;
136
+ line-height: 1.42857143;
137
+ vertical-align: middle;
138
+ touch-action: manipulation;
139
+ cursor: pointer;
140
+ user-select: none;
141
+ background-image: none;
142
+ border: 1px solid #ccc;
143
+ border-radius: 4px;
144
+ color: #333;
145
+ background-color: #fff
146
+ }
147
+
148
+ .dropdown-display-label:after,
149
+ .dropdown-display:after {
150
+ content: '';
151
+ position: absolute;
152
+ border-top: 10px solid #999;
153
+ border-left: 5px solid transparent;
154
+ border-right: 5px solid transparent;
155
+ top: 15px;
156
+ right: 8px
157
+ }
158
+
159
+ .dropdown-clear-all {
160
+ background-color: #fff;
161
+ border: none;
162
+ font-size: 22px;
163
+ z-index: 999;
164
+ color: #999;
165
+ position: absolute;
166
+ right: 2px;
167
+ top: 2px;
168
+ display: none;
169
+ width: 25px;
170
+ height: 30px;
171
+ text-align: center;
172
+ line-height: 30px;
173
+ }
174
+
175
+ .dropdown-clear-all:focus {
176
+ outline: 0
177
+ }
178
+
179
+ .dropdown-clear-all:hover {
180
+ color: #ccc;
181
+ text-decoration: none;
182
+ }
183
+
184
+ .dropdown-display {
185
+ white-space: nowrap;
186
+ padding: 6px 20px 6px 12px
187
+ }
188
+
189
+ .dropdown-multiple:hover .dropdown-clear-all,
190
+ .dropdown-single:hover .dropdown-clear-all {
191
+ display: block
192
+ }
193
+
194
+ .dropdown-display .dropdown-chose-list {
195
+ display: inline-block;
196
+ vertical-align: middle;
197
+ width: 100%;
198
+ overflow: hidden;
199
+ text-overflow: ellipsis;
200
+ white-space: nowrap
201
+ }
202
+
203
+ .dropdown-display .dropdown-chose-list span:before {
204
+ content: ','
205
+ }
206
+
207
+ .dropdown-display .dropdown-chose-list span:first-child:before {
208
+ content: ''
209
+ }
210
+
211
+ .dropdown-display .placeholder {
212
+ display: none
213
+ }
214
+
215
+ .dropdown-display .placeholder:first-child {
216
+ position: absolute;
217
+ height: 100%;
218
+ width: 100%;
219
+ top: 0;
220
+ left: 0;
221
+ color: #999;
222
+ display: block;
223
+ text-indent: 10px;
224
+ font-size: 13px;
225
+ line-height: 32px
226
+ }
227
+
228
+ .dropdown-display input {
229
+ border: 0;
230
+ outline: 0
231
+ }
232
+
233
+ .dropdown-display-label {
234
+ cursor: text;
235
+ padding: 6px 25px 5px 0
236
+ }
237
+
238
+ .dropdown-display-label .dropdown-search {
239
+ display: block;
240
+ width: 100%;
241
+ border: 1px solid #eee;
242
+ }
243
+
244
+ .dropdown-display-label .dropdown-search input {
245
+ width: 100%;
246
+ }
247
+
248
+ .dropdown-option.dropdown-chose {
249
+ font-weight: bold;
250
+ }
251
+
252
+ .dropdown-display-label input,
253
+ .dropdown-display-label input:focus {
254
+ border: none;
255
+ outline: 0
256
+ }
257
+
258
+ .dropdown-display-label .dropdown-chose-list {
259
+ width: 100%;
260
+ display: inline-block;
261
+ padding: 0 5px
262
+ }
263
+
264
+ .dropdown-display-label .dropdown-chose-list .placeholder {
265
+ display: none
266
+ }
267
+
268
+ .dropdown-display-label .dropdown-selected {
269
+ position: relative;
270
+ margin: 0 5px 5px 0;
271
+ padding: 0 20px 0 5px;
272
+ border: 1px solid #aaa;
273
+ max-width: 100%;
274
+ border-radius: 3px;
275
+ background-repeat: repeat-x;
276
+ color: #333;
277
+ cursor: default;
278
+ display: inline-block
279
+ }
280
+
281
+ .dropdown-display-label .dropdown-selected .del {
282
+ -webkit-appearance: none;
283
+ padding: 0;
284
+ cursor: pointer;
285
+ background: 0 0;
286
+ border: 0;
287
+ float: right;
288
+ line-height: 1;
289
+ color: #999;
290
+ position: absolute;
291
+ right: 3px;
292
+ top: 0
293
+ }
294
+
295
+ .dropdown-display-label .dropdown-selected .del:after {
296
+ content: '\D7';
297
+ font-size: 16px
298
+ }
299
+
300
+ .dropdown-main {
301
+ position: absolute;
302
+ top: 100%;
303
+ left: 0;
304
+ z-index: 1010;
305
+ width: 100%;
306
+ color: #444;
307
+ box-sizing: border-box;
308
+ background-color: #fff;
309
+ border: 1px solid #ccc;
310
+ border-radius: 0 0 4px 4px;
311
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
312
+ margin-top: -1px;
313
+ border-top: 0;
314
+ padding: 4px 7px;
315
+ display: none
316
+ }
317
+
318
+ .dropdown-main ul {
319
+ overflow-x: hidden;
320
+ overflow-y: auto;
321
+ max-height: 240px;
322
+ margin: 0;
323
+ padding: 0
324
+ }
325
+
326
+ .dropdown-main input {
327
+ margin-top: 0;
328
+ display: block;
329
+ box-sizing: border-box;
330
+ height: 30px;
331
+ border: 1px solid #ccc;
332
+ width: 100%;
333
+ text-indent: 5px;
334
+ border-radius: 3px
335
+ }
336
+
337
+ .dropdown-main .dropdown-search {
338
+ display: block;
339
+ padding: 5px 0
340
+ }
341
+
342
+ .dropdown-group {
343
+ font-weight: 700
344
+ }
345
+
346
+ .dropdown-group,
347
+ .dropdown-option {
348
+ margin: 0;
349
+ padding-left: 12px;
350
+ list-style: none;
351
+ line-height: 26px;
352
+ word-wrap: break-word
353
+ }
354
+
355
+ .dropdown-option {
356
+ cursor: pointer
357
+ }
358
+
359
+ .dropdown-option:focus,
360
+ .dropdown-option:hover {
361
+ background-color: #efefef;
362
+ outline: 0
363
+ }
364
+
365
+ .dropdown-option[disabled] {
366
+ color: #ddd;
367
+ background-color: #fff;
368
+ cursor: not-allowed;
369
+ text-decoration: line-through
370
+ }
371
+
372
+ .dropdown-option.dropdown-chose:after {
373
+ content: '';
374
+ float: right;
375
+ width: 10px;
376
+ height: 10px;
377
+ background: #4AB1E9;
378
+ border-radius: 100%;
379
+ margin: 8px 5px 0 0
380
+ }
381
+
382
+ .dropdown-maxItem-alert, .dropdown-minItem-alert {
383
+ position: absolute;
384
+ top: 0;
385
+ left: 0;
386
+ background-color: #e4e3e2;
387
+ width: 100%;
388
+ height: 39px;
389
+ line-height: 39px;
390
+ padding: 0 5px;
391
+ border-radius: 5px;
392
+ color: #999;
393
+ -webkit-animation: iui-fadeIn .2s ease-in forwards;
394
+ -moz-animation: iui-fadeIn .2s ease-in forwards;
395
+ -ms-animation: iui-fadeIn .2s ease-in forwards;
396
+ -o-animation: iui-fadeIn .2s ease-in forwards;
397
+ animation: iui-fadeIn .2s ease-in forwards
398
+ }
svg-support.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: SVG Support
4
  Plugin URI: http://wordpress.org/plugins/svg-support/
5
  Description: Upload SVG files to the Media Library and render SVG files inline for direct styling/animation of an SVG's internal elements using CSS/JS.
6
- Version: 2.5.1
7
  Author: Benbodhi
8
  Author URI: https://benbodhi.com
9
  Text Domain: svg-support
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
22
  /**
23
  * Global variables
24
  */
25
- $svgs_plugin_version = '2.5.1'; // for use on admin pages
26
  $plugin_file = plugin_basename(__FILE__); // plugin file for reference
27
  define( 'BODHI_SVGS_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); // define the absolute plugin path for includes
28
  define( 'BODHI_SVGS_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); // define the plugin url for use in enqueue
@@ -80,9 +80,29 @@ if ( empty( $svgs_plugin_version_stored ) ) {
80
 
81
  }
82
 
 
 
 
83
  // For version >= 2.5. | Enable 'sanitize_svg_front_end' by default
84
  if ( !isset($bodhi_svgs_options['sanitize_svg_front_end']) ) {
85
  $bodhi_svgs_options['sanitize_svg_front_end'] = 'on';
86
  update_option( 'bodhi_svgs_settings', $bodhi_svgs_options );
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  Plugin Name: SVG Support
4
  Plugin URI: http://wordpress.org/plugins/svg-support/
5
  Description: Upload SVG files to the Media Library and render SVG files inline for direct styling/animation of an SVG's internal elements using CSS/JS.
6
+ Version: 2.5.2
7
  Author: Benbodhi
8
  Author URI: https://benbodhi.com
9
  Text Domain: svg-support
22
  /**
23
  * Global variables
24
  */
25
+ $svgs_plugin_version = '2.5.2'; // for use on admin pages
26
  $plugin_file = plugin_basename(__FILE__); // plugin file for reference
27
  define( 'BODHI_SVGS_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); // define the absolute plugin path for includes
28
  define( 'BODHI_SVGS_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); // define the plugin url for use in enqueue
80
 
81
  }
82
 
83
+ /**
84
+ * Defaults for better security
85
+ */
86
  // For version >= 2.5. | Enable 'sanitize_svg_front_end' by default
87
  if ( !isset($bodhi_svgs_options['sanitize_svg_front_end']) ) {
88
  $bodhi_svgs_options['sanitize_svg_front_end'] = 'on';
89
  update_option( 'bodhi_svgs_settings', $bodhi_svgs_options );
90
  }
91
 
92
+ // For version >= 2.5. | Allow only admins to upload SVGs by default
93
+ if ( !isset($bodhi_svgs_options['restrict']) || $bodhi_svgs_options['restrict'] == "on" ) {
94
+ $bodhi_svgs_options['restrict'] = array('administrator');
95
+ update_option( 'bodhi_svgs_settings', $bodhi_svgs_options );
96
+ }
97
+
98
+ // For version >= 2.5. | By default turn on "Sanitize SVG while uploading" option
99
+ if ( !isset($bodhi_svgs_options['sanitize_svg']) ) {
100
+ $bodhi_svgs_options['sanitize_svg'] = "on";
101
+ update_option( 'bodhi_svgs_settings', $bodhi_svgs_options );
102
+ }
103
+
104
+ // For version >= 2.5. | By default sanitize on upload for everyone expet for administrator and editor roles
105
+ if ( !isset($bodhi_svgs_options['sanitize_on_upload_roles']) ) {
106
+ $bodhi_svgs_options['sanitize_on_upload_roles'] = array('administrator', 'editor');
107
+ update_option( 'bodhi_svgs_settings', $bodhi_svgs_options );
108
+ }