Changeset 1536575
- Timestamp:
- 11/18/2016 09:21:24 PM (9 years ago)
- Location:
- shortcode-ui/trunk
- Files:
-
- 72 added
- 7 deleted
- 29 edited
-
Gruntfile.js (modified) (3 diffs)
-
composer.json (modified) (1 diff)
-
css/sass/_field-image.scss (modified) (1 diff)
-
css/sass/_select2-fields.scss (added)
-
css/sass/shortcode-ui.scss (modified) (1 diff)
-
css/shortcode-ui-editor-styles.css (modified) (1 diff)
-
css/shortcode-ui-editor-styles.css.map (modified) (1 diff)
-
css/shortcode-ui.css (modified) (12 diffs)
-
css/shortcode-ui.css.map (modified) (1 diff)
-
inc/class-shortcode-ui.php (modified) (5 diffs)
-
inc/fields/class-field-attachment.php (modified) (1 diff)
-
inc/fields/class-field-color.php (modified) (1 diff)
-
inc/fields/class-field-post-select.php (modified) (5 diffs)
-
inc/fields/class-field-term-select.php (added)
-
inc/fields/class-field-user-select.php (added)
-
inc/templates/edit-form.tpl.php (modified) (12 diffs)
-
js/build/shortcode-ui.js (modified) (34 diffs)
-
js/src/controllers/media-controller.js (modified) (1 diff)
-
js/src/models/shortcode.js (modified) (2 diffs)
-
js/src/shortcode-ui.js (modified) (1 diff)
-
js/src/utils/fetcher.js (modified) (1 diff)
-
js/src/utils/shortcode-view-constructor.js (modified) (5 diffs)
-
js/src/views/edit-attribute-field-attachment.js (modified) (9 diffs)
-
js/src/views/edit-attribute-field-post-select.js (modified) (1 diff)
-
js/src/views/edit-attribute-field-term-select.js (added)
-
js/src/views/edit-attribute-field-user-select.js (added)
-
js/src/views/edit-attribute-field.js (modified) (2 diffs)
-
js/src/views/edit-shortcode-form.js (modified) (1 diff)
-
js/src/views/media-frame.js (modified) (1 diff)
-
js/src/views/select2-field.js (added)
-
js/src/views/shortcode-preview.js (deleted)
-
js/src/views/shortcode-ui.js (modified) (2 diffs)
-
languages/shortcode-ui-fi.mo (added)
-
languages/shortcode-ui-fi.po (added)
-
languages/shortcode-ui-hu_HU.mo (added)
-
languages/shortcode-ui-hu_HU.po (added)
-
languages/shortcode-ui-ja.mo (added)
-
languages/shortcode-ui-ja.po (added)
-
languages/shortcode-ui-sv_SE.mo (added)
-
languages/shortcode-ui-sv_SE.po (added)
-
languages/shortcode-ui-tr_TR.mo (added)
-
languages/shortcode-ui-tr_TR.po (added)
-
languages/shortcode-ui.pot (modified) (3 diffs)
-
lib/select2/css (added)
-
lib/select2/css/select2.css (added)
-
lib/select2/css/select2.min.css (added)
-
lib/select2/js (added)
-
lib/select2/js/i18n (added)
-
lib/select2/js/i18n/ar.js (added)
-
lib/select2/js/i18n/az.js (added)
-
lib/select2/js/i18n/bg.js (added)
-
lib/select2/js/i18n/ca.js (added)
-
lib/select2/js/i18n/cs.js (added)
-
lib/select2/js/i18n/da.js (added)
-
lib/select2/js/i18n/de.js (added)
-
lib/select2/js/i18n/el.js (added)
-
lib/select2/js/i18n/en.js (added)
-
lib/select2/js/i18n/es.js (added)
-
lib/select2/js/i18n/et.js (added)
-
lib/select2/js/i18n/eu.js (added)
-
lib/select2/js/i18n/fa.js (added)
-
lib/select2/js/i18n/fi.js (added)
-
lib/select2/js/i18n/fr.js (added)
-
lib/select2/js/i18n/gl.js (added)
-
lib/select2/js/i18n/he.js (added)
-
lib/select2/js/i18n/hi.js (added)
-
lib/select2/js/i18n/hr.js (added)
-
lib/select2/js/i18n/hu.js (added)
-
lib/select2/js/i18n/id.js (added)
-
lib/select2/js/i18n/is.js (added)
-
lib/select2/js/i18n/it.js (added)
-
lib/select2/js/i18n/ja.js (added)
-
lib/select2/js/i18n/km.js (added)
-
lib/select2/js/i18n/ko.js (added)
-
lib/select2/js/i18n/lt.js (added)
-
lib/select2/js/i18n/lv.js (added)
-
lib/select2/js/i18n/mk.js (added)
-
lib/select2/js/i18n/ms.js (added)
-
lib/select2/js/i18n/nb.js (added)
-
lib/select2/js/i18n/nl.js (added)
-
lib/select2/js/i18n/pl.js (added)
-
lib/select2/js/i18n/pt-BR.js (added)
-
lib/select2/js/i18n/pt.js (added)
-
lib/select2/js/i18n/ro.js (added)
-
lib/select2/js/i18n/ru.js (added)
-
lib/select2/js/i18n/sk.js (added)
-
lib/select2/js/i18n/sr-Cyrl.js (added)
-
lib/select2/js/i18n/sr.js (added)
-
lib/select2/js/i18n/sv.js (added)
-
lib/select2/js/i18n/th.js (added)
-
lib/select2/js/i18n/tr.js (added)
-
lib/select2/js/i18n/uk.js (added)
-
lib/select2/js/i18n/vi.js (added)
-
lib/select2/js/i18n/zh-CN.js (added)
-
lib/select2/js/i18n/zh-TW.js (added)
-
lib/select2/js/select2.full.js (added)
-
lib/select2/js/select2.full.min.js (added)
-
lib/select2/js/select2.js (added)
-
lib/select2/js/select2.min.js (added)
-
lib/select2/select2-spinner.gif (deleted)
-
lib/select2/select2.css (deleted)
-
lib/select2/select2.js (deleted)
-
lib/select2/select2.min.js (deleted)
-
lib/select2/select2.png (deleted)
-
lib/select2/select2x2.png (deleted)
-
package.json (modified) (1 diff)
-
readme.txt (modified) (3 diffs)
-
shortcode-ui.php (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
shortcode-ui/trunk/Gruntfile.js
r1278066 r1536575 3 3 'use strict'; 4 4 var remapify = require('remapify'); 5 var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; 5 var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; 6 7 // Scripts from WP Core required by Jasmine tests. 8 var jasmineCoreScripts = [ 9 'wp-includes/js/jquery/jquery.js', 10 'wp-includes/js/underscore.min.js', 11 'wp-includes/js/backbone.min.js', 12 'wp-includes/js/wp-util.js', 13 'wp-includes/js/shortcode.js', 14 'wp-admin/js/editor.js', 15 ]; 16 6 17 // Project configuration 7 18 grunt.initConfig( { … … 136 147 helpers: 'js-tests/build/helpers.js', 137 148 vendor: [ 138 'js-tests/vendor/jquery.js', 139 'js-tests/vendor/underscore.js', 140 'js-tests/vendor/backbone.js', 141 'js-tests/vendor/wp-shortcode.js', 142 'js-tests/vendor/wp-util.js', 143 'js-tests/vendor/wp-editors.js', 144 'js-tests/vendor/mock-ajax.js', 145 ], 149 'js-tests/vendor/mock-ajax.js' 150 ].concat( jasmineCoreScripts.map( function( script ) { 151 return 'js-tests/vendor/' + script 152 } ) ), 146 153 } 147 154 } … … 187 194 } ); 188 195 196 /** 197 * Helper task to keep all the scripts from WordPress core that are required by the Jasmine tests up to date. 198 * 199 * Note the list of scripts needs to be kept up to date. 200 * 201 * Pass the location of your WordPress installation using --abspath. 202 */ 203 grunt.registerTask( 'updateJasmineCoreScripts', function() { 204 205 var abspath = grunt.option( "abspath" ); 206 207 if ( ! grunt.file.exists( abspath + '/wp-includes' ) ) { 208 grunt.fail.fatal( 'WordPress install not found. Currently looking here: ' + abspath ); 209 } 210 211 for ( var i = 0; i < jasmineCoreScripts.length; i++ ) { 212 if ( grunt.file.exists( abspath + '/' + jasmineCoreScripts[ i ] ) ) { 213 grunt.file.copy( 214 abspath + '/' + jasmineCoreScripts[ i ] , 215 'js-tests/vendor/' + jasmineCoreScripts[ i ] 216 ); 217 } else { 218 grunt.log.error( 'File not found: ' + abspath + '/' + jasmineCoreScripts[i] ); 219 } 220 } 221 222 }); 223 189 224 grunt.loadNpmTasks( 'grunt-sass' ); 190 225 grunt.loadNpmTasks( 'grunt-postcss' ); -
shortcode-ui/trunk/composer.json
r1147525 r1536575 12 12 ], 13 13 "require-dev": { 14 "squizlabs/php_codesniffer": "2.x-dev", 14 15 "wp-coding-standards/wpcs": "dev-develop" 15 16 }, -
shortcode-ui/trunk/css/sass/_field-image.scss
r1231560 r1536575 1 .edit-shortcode-form .shortcake-attachment-preview{1 .edit-shortcode-form { 2 2 3 width: 150px; 4 height: 150px; 5 margin: 0 10px 10px 0; 6 line-height: 150px; 7 text-align: center; 8 padding: 0; 9 10 &:before { 11 display: none; 3 .button.shortcake-attachment-select { 4 display: block; 5 clear: both; 6 margin-bottom: 15px; 12 7 } 13 8 14 .thumbnail:hover:after { 15 background: rgba(0,0,0,0.1); 16 transition: all .3s linear; 17 } 18 19 &:not( .has-attachment ) { 20 border: 2px dashed #DDD; 21 border-radius: 2px; 22 background: transparent; 23 box-shadow: none; 9 .shortcake-attachment-preview { 10 float: left; 11 margin: 0 20px 20px 0; 12 width: 150px; 24 13 } 25 14 26 .button.add { 27 vertical-align: middle; 28 z-index: 1; 15 .shortcode-ui-field-attachment .description { 16 margin: 10px 0; 29 17 } 30 18 31 . button.remove{19 .shortcake-attachment-preview-container { 32 20 33 z-index: 1; 34 display: none; 35 position: absolute; 36 top: 5px; 37 right: 5px; 38 border: 1px solid #aaa; 39 box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.15 ); 40 text-indent: 100%; 41 whitespace: nowrap; 42 width: 24px; 43 height: 24px; 21 width: 150px !important; 22 height: 150px !important; 23 margin: 0 10px 10px 0; 24 line-height: 150px; 25 text-align: center; 44 26 padding: 0; 45 overflow:hidden;46 27 47 &:after { 48 content: "\00d7"; 28 &:before { 29 display: none; 30 } 31 32 .button.remove { 33 34 z-index: 1; 35 display: block; 49 36 position: absolute; 50 top: -1px; 51 left: 5px; 52 font-size: 22px; 53 text-indent: 0; 37 top: 5px; 38 right: 5px; 39 border: 1px solid #aaa; 40 box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.15 ); 41 text-indent: 100%; 42 whitespace: nowrap; 43 width: 24px; 44 height: 24px; 45 padding: 0; 46 overflow:hidden; 47 48 &:after { 49 content: "\00d7"; 50 position: absolute; 51 top: -1px; 52 left: 5px; 53 font-size: 22px; 54 text-indent: 0; 55 } 54 56 } 55 }56 57 57 .loading-indicator, 58 &.loading .button.add { 59 display: none; 60 } 58 .thumbnail img { 59 max-width: 100%; 60 max-height: 100%; 61 width: auto; 62 height: auto; 63 } 61 64 62 &.loading .loading-indicator { 63 display: block; 64 position: relative; 65 width: 100%; 66 height: 100%; 67 } 65 .loading-indicator, 66 &.loading .button.add { 67 display: none; 68 } 68 69 69 .loading-indicator { 70 .dashicons { 71 font-size: 80px; 72 height: 100px; 73 line-height: 100px; 70 &.loading .loading-indicator { 71 display: block; 72 position: relative; 74 73 width: 100%; 75 text-align: center; 76 vertical-align: middle; 74 height: 100%; 77 75 } 78 .attachment-preview-loading {79 width: 60px;80 height: 5px;81 overflow: hidden;82 background-color: transparent;83 margin: -30px auto 0;84 76 85 ins { 86 background-color: #464646; 87 margin: 0 0 0 -60px; 77 .loading-indicator { 78 .dashicons { 79 font-size: 80px; 80 height: 100px; 81 line-height: 100px; 82 width: 100%; 83 text-align: center; 84 vertical-align: middle; 85 } 86 .attachment-preview-loading { 88 87 width: 60px; 89 88 height: 5px; 90 display: block; 91 -webkit-animation: attachment-preview-loading 1.3s infinite 1s linear; 92 animation: attachment-preview-loading 1.3s infinite 1s linear; 89 overflow: hidden; 90 background-color: transparent; 91 margin: -30px auto 0; 92 93 ins { 94 background-color: #464646; 95 margin: 0 0 0 -60px; 96 width: 60px; 97 height: 5px; 98 display: block; 99 -webkit-animation: attachment-preview-loading 1.3s infinite 1s linear; 100 animation: attachment-preview-loading 1.3s infinite 1s linear; 101 } 93 102 } 94 103 } 95 }96 104 97 .filename {98 line-height: 1.4em99 }105 .filename { 106 line-height: 1.4em 107 } 100 108 101 &.has-attachment {102 .button.add {103 display: none;104 }105 .button.remove {106 display: block;107 }108 109 } 109 110 -
shortcode-ui/trunk/css/sass/shortcode-ui.scss
r1278066 r1536575 160 160 161 161 @import 'field-image'; 162 @import 'select2-fields'; -
shortcode-ui/trunk/css/shortcode-ui-editor-styles.css
r1278066 r1536575 1 1 .wpview-wrap.wp-mce-view-show-toolbar .toolbar { 2 2 display: block; } 3 3 4 .wpview-wrap .shortcake-error { 4 5 color: red; 5 6 font-weight: bold; } 7 6 8 .wpview-wrap .shortcake-empty { 7 9 font-family: Consolas, Monaco, monospace; -
shortcode-ui/trunk/css/shortcode-ui-editor-styles.css.map
r1278066 r1536575 1 {"version":3,"sources":[" ../shortcode-ui-editor-styles.scss"],"names":[],"mappings":"AAGA;EACG,eAAA,EAAA;AAIH;EACE,WAAA;EACA,kBAAA,EAAA;AAGF;EACE,yCAAA;EACA,YAAA;EACA,gBAAA,EAAA;;AAIF;EACC,sBAAA;EACA,YAAA;EACA,iBAAA,EAAA","file":"shortcode-ui-editor-styles.css"}1 {"version":3,"sources":["sass/shortcode-ui-editor-styles.scss"],"names":[],"mappings":"AAAA;EAIG,eAAe,EACf;;AALH;EASE,WAAW;EACX,kBAAkB,EAClB;;AAXF;EAcE,yCAAyC;EACzC,YAAY;EACZ,gBAAgB,EAChB;;AAGF;EACC,sBAAsB;EACtB,YAAY;EACZ,iBAAiB,EACjB","file":"shortcode-ui-editor-styles.css"} -
shortcode-ui/trunk/css/shortcode-ui.css
r1278066 r1536575 6 6 max-height: 800px; 7 7 margin: auto; } 8 8 9 .shortcode-ui-insert-modal .media-frame-content { 9 10 top: 54px; } … … 25 26 height: 120px; 26 27 font-size: 64px; } 27 .add-shortcode-list .shortcode-list-item .add-shortcode-list-item-icon .dashicons, .add-shortcode-list .shortcode-list-item .add-shortcode-list-item-icon img { 28 .add-shortcode-list .shortcode-list-item .add-shortcode-list-item-icon .dashicons, 29 .add-shortcode-list .shortcode-list-item .add-shortcode-list-item-icon img { 28 30 position: absolute; 29 31 top: 50%; 30 32 left: 50%; 31 33 -webkit-transform: translate(-50%, -50%); 32 -ms-transform: translate(-50%, -50%);33 34 transform: translate(-50%, -50%); 34 35 font-size: inherit; … … 58 59 height: 34px; 59 60 padding: 10px 10px 0; } 61 60 62 .shortcode-ui-content .edit-shortcode-tabs-content { 61 63 padding: 10px; 62 64 border-top: 1px solid #ddd; } 65 63 66 .shortcode-ui-content a.wp-color-result { 64 67 border-bottom: 1px solid #ccc; } 68 65 69 .shortcode-ui-content .media-toolbar { 66 70 position: relative; … … 72 76 display: block; 73 77 clear: both; } 74 .edit-shortcode-form input, .edit-shortcode-form textarea { 78 .edit-shortcode-form input, 79 .edit-shortcode-form textarea { 75 80 border: 1px solid #ddd; 76 81 box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.07); … … 105 110 clear: both; } 106 111 112 .edit-shortcode-form .button.shortcake-attachment-select { 113 display: block; 114 clear: both; 115 margin-bottom: 15px; } 116 107 117 .edit-shortcode-form .shortcake-attachment-preview { 108 width: 150px; 109 height: 150px; 118 float: left; 119 margin: 0 20px 20px 0; 120 width: 150px; } 121 122 .edit-shortcode-form .shortcode-ui-field-attachment .description { 123 margin: 10px 0; } 124 125 .edit-shortcode-form .shortcake-attachment-preview-container { 126 width: 150px !important; 127 height: 150px !important; 110 128 margin: 0 10px 10px 0; 111 129 line-height: 150px; 112 130 text-align: center; 113 131 padding: 0; } 114 .edit-shortcode-form .shortcake-attachment-preview :before {132 .edit-shortcode-form .shortcake-attachment-preview-container:before { 115 133 display: none; } 116 .edit-shortcode-form .shortcake-attachment-preview .thumbnail:hover:after { 117 background: rgba(0, 0, 0, 0.1); 118 -webkit-transition: all .3s linear; 119 transition: all .3s linear; } 120 .edit-shortcode-form .shortcake-attachment-preview:not(.has-attachment) { 121 border: 2px dashed #DDD; 122 border-radius: 2px; 123 background: transparent; 124 box-shadow: none; } 125 .edit-shortcode-form .shortcake-attachment-preview .button.add { 126 vertical-align: middle; 127 z-index: 1; } 128 .edit-shortcode-form .shortcake-attachment-preview .button.remove { 134 .edit-shortcode-form .shortcake-attachment-preview-container .button.remove { 129 135 z-index: 1; 130 display: none;136 display: block; 131 137 position: absolute; 132 138 top: 5px; … … 140 146 padding: 0; 141 147 overflow: hidden; } 142 .edit-shortcode-form .shortcake-attachment-preview .button.remove:after {148 .edit-shortcode-form .shortcake-attachment-preview-container .button.remove:after { 143 149 content: "\00d7"; 144 150 position: absolute; … … 147 153 font-size: 22px; 148 154 text-indent: 0; } 149 .edit-shortcode-form .shortcake-attachment-preview .loading-indicator, .edit-shortcode-form .shortcake-attachment-preview.loading .button.add { 155 .edit-shortcode-form .shortcake-attachment-preview-container .thumbnail img { 156 max-width: 100%; 157 max-height: 100%; 158 width: auto; 159 height: auto; } 160 .edit-shortcode-form .shortcake-attachment-preview-container .loading-indicator, 161 .edit-shortcode-form .shortcake-attachment-preview-container.loading .button.add { 150 162 display: none; } 151 .edit-shortcode-form .shortcake-attachment-preview .loading .loading-indicator {163 .edit-shortcode-form .shortcake-attachment-preview-container.loading .loading-indicator { 152 164 display: block; 153 165 position: relative; 154 166 width: 100%; 155 167 height: 100%; } 156 .edit-shortcode-form .shortcake-attachment-preview .loading-indicator .dashicons {168 .edit-shortcode-form .shortcake-attachment-preview-container .loading-indicator .dashicons { 157 169 font-size: 80px; 158 170 height: 100px; … … 161 173 text-align: center; 162 174 vertical-align: middle; } 163 .edit-shortcode-form .shortcake-attachment-preview .loading-indicator .attachment-preview-loading {175 .edit-shortcode-form .shortcake-attachment-preview-container .loading-indicator .attachment-preview-loading { 164 176 width: 60px; 165 177 height: 5px; … … 167 179 background-color: transparent; 168 180 margin: -30px auto 0; } 169 .edit-shortcode-form .shortcake-attachment-preview .loading-indicator .attachment-preview-loading ins {181 .edit-shortcode-form .shortcake-attachment-preview-container .loading-indicator .attachment-preview-loading ins { 170 182 background-color: #464646; 171 183 margin: 0 0 0 -60px; … … 175 187 -webkit-animation: attachment-preview-loading 1.3s infinite 1s linear; 176 188 animation: attachment-preview-loading 1.3s infinite 1s linear; } 177 .edit-shortcode-form .shortcake-attachment-preview .filename {189 .edit-shortcode-form .shortcake-attachment-preview-container .filename { 178 190 line-height: 1.4em; } 179 .edit-shortcode-form .shortcake-attachment-preview.has-attachment .button.add {180 display: none; }181 .edit-shortcode-form .shortcake-attachment-preview.has-attachment .button.remove {182 display: block; }183 191 184 192 .edit-shortcode-form .thumbnail-details-container { … … 190 198 0% { 191 199 margin-left: -60px; } 192 193 200 100% { 194 201 margin-left: 60px; } } … … 197 204 0% { 198 205 margin-left: -60px; } 199 200 206 100% { 201 207 margin-left: 60px; } } 208 209 .edit-shortcode-form .select2-container { 210 min-width: 300px; } 211 212 .edit-shortcode-form .select2-container a { 213 transition: none; 214 -webkit-transition: none; } 215 216 .edit-shortcode-form .select2-drop { 217 z-index: 160001; } 218 219 .edit-shortcode-form .select2 li { 220 margin: 0; } 221 222 .edit-shortcode-form .select2-selection__rendered { 223 vertical-align: top; } 224 225 .edit-shortcode-form .select2-container .select2-search--inline .select2-search__field { 226 margin-top: 7px; } 227 228 .edit-shortcode-form .select2-container--default .select2-selection--multiple { 229 border-radius: 0; 230 border-color: #ddd; 231 box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.07); 232 background-color: #fff; 233 color: #333; 234 outline: none; } 235 236 .edit-shortcode-form .select2-container--default.select2-container--focus .select2-selection--multiple { 237 border-color: #5b9dd9; 238 box-shadow: 0 0 2px rgba(30, 140, 190, 0.8); } 239 240 .select2-container { 241 z-index: 160000; 242 max-width: 300px; } 243 244 .select2-results li { 245 margin: 0; } 202 246 /*# sourceMappingURL=shortcode-ui.css.map */ -
shortcode-ui/trunk/css/shortcode-ui.css.map
r1278066 r1536575 1 {"version":3,"sources":[" ../shortcode-ui.scss","../_field-image.scss","shortcode-ui.css"],"names":[],"mappings":"AAAA;EACC,mBAAA,EAAA;;AAKD;EACE,iBAAA;EACA,kBAAA;EACA,aAAA,EAAA;AAGF;EACE,UAAA,EAAA;;AAKF;EACC,gBAAA,EAAA;EAED;IACE,aAAA;IACA,YAAA;IAEA,kFAAA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;IACA,mBAAA;IACA,aAAA;IACA,cAAA,EAAA;IAEF;MACG,mBAAA;MACA,cAAA;MACA,gBAAA,EAAA;MAEH;QAEI,mBAAA;QACA,SAAA;QACA,UAAA;QACA,yCAAA;YAAA,qCAAA;gBAAA,iCAAA;QACA,mBAAA;QACA,qBAAA;QACA,YAAA;QACA,aAAA;QACA,eAAA;QACA,gBAAA,EAAA;IAKJ;MACG,uBAAA;MACA,mBAAA;MACA,UAAA;MACA,QAAA;MACA,YAAA;MACA,UAAA;MACA,iBAAA;MACA,aAAA;MACA,iBAAA;MACA,iBAAA;MACA,sBAAA;MACA,mBAAA;MACA,kBAAA;MACA,qCAAA;MAEA,gDAAA,EAAA;;AAOH;EACE,aAAA;EACA,qBAAA,EAAA;AAGF;EACE,cAAA;EACA,2BAAA,EAAA;AAGF;EACE,8BAAA,EAAA;AAGF;EACE,mBAAA;EACA,aAAA,EAAA;;AAIF;EAEC,kBAAA,EAAA;EAED;IACE,eAAA;IACA,YAAA,EAAA;EAGF;IAEE,uBAAA;IAEA,gDAAA;IACA,uBAAA;IACA,YAAA;IACA,cAAA;IACA,mDAAA;IACA,2CAAA;IACA,gBAAA,EAAA;EAGF;IAEE,iBAAA,EAAA;EAGF;IACE,sBAAA;IACA,iBAAA;IACA,oBAAA,EAAA;EAGF;IACE,YAAA;IACA,gBAAA;IACA,kBAAA,EAAA;EAIF;IAAU,oBAAA,EAAA;EAGV;IACE,eAAA,EAAA;IACF;MACG,eAAA;MACA,oBAAA,EAAA;EAIH;IAIE,kBAAA,EAAA;IAHF;MACG,sBAAA,EAAA;EAKH;IACE,YAAA,EAAA;;AC5JF;EAEC,aAAA;EACA,cAAA;EACA,sBAAA;EACA,mBAAA;EACA,mBAAA;EACA,WAAA,EAAA;EAED;IACE,cAAA,EAAA;EAGF;IACE,+BAAA;IACA,mCAAA;YAAA,2BAAA,EAAA;EAGF;IACE,wBAAA;IACA,mBAAA;IACA,wBAAA;IACA,iBAAA,EAAA;EAGF;IACE,uBAAA;IACA,WAAA,EAAA;EAGF;IAEE,WAAA;IACA,cAAA;IACA,mBAAA;IACA,SAAA;IACA,WAAA;IACA,uBAAA;IACA,0CAAA;IACA,kBAAA;IACA,mBAAA;IACA,YAAA;IACA,aAAA;IACA,WAAA;IACA,iBAAA,EAAA;IAEF;MACG,iBAAA;MACA,mBAAA;MACA,UAAA;MACA,UAAA;MACA,gBAAA;MACA,eAAA,EAAA;EAIH;IAEE,cAAA,EAAA;EAGF;IACE,eAAA;IACA,mBAAA;IACA,YAAA;IACA,aAAA,EAAA;EAIF;IACG,gBAAA;IACA,cAAA;IACA,mBAAA;IACA,YAAA;IACA,mBAAA;IACA,uBAAA,EAAA;EAEH;IACG,YAAA;IACA,YAAA;IACA,iBAAA;IACA,8BAAA;IACA,qBAAA,EAAA;IAEH;MACI,0BAAA;MACA,oBAAA;MACA,YAAA;MACA,YAAA;MACA,eAAA;MACA,sEAAA;MACA,8DAAA,EAAA;EAKJ;IACE,mBAAA,EAAA;EAIF;IACG,cAAA,EAAA;EAEH;IACG,eAAA,EAAA;;AAMH;EACC,cAAA,EAAA;EAED;IACE,eAAA,EAAA;;AC0EF;EDrEA;IACE,mBAAA,EAAA;;EAEF;IACE,kBAAA,EAAA,EAAA;;ACwEF;EDnEA;IACE,mBAAA,EAAA;;EAEF;IACE,kBAAA,EAAA,EAAA","file":"shortcode-ui.css"}1 {"version":3,"sources":["sass/shortcode-ui.scss","sass/_field-image.scss","sass/_select2-fields.scss"],"names":[],"mappings":"AAAA;EACC,mBAAmB,EACnB;;AAED;EAGE,iBAAiB;EACjB,kBAAkB;EAClB,aAAa,EACb;;AANF;EASE,UAAU,EACV;;AAIF;EACC,gBAAgB,EAuDhB;EAxDD;IAIE,aAAa;IACb,YAAY;IAEZ,kFAAqE;IACrE,iBAAiB;IACjB,gBAAgB;IAChB,mBAAmB;IACnB,mBAAmB;IACnB,aAAa;IACb,cAAc,EAyCd;IAtDF;MAgBG,mBAAmB;MACnB,cAAc;MACd,gBAAgB,EAgBhB;MAlCH;;QAsBI,mBAAmB;QACnB,SAAS;QACT,UAAU;QACV,yCAAoB;gBAApB,iCAAoB;QACpB,mBAAmB;QACnB,qBAAqB;QACrB,YAAY;QACZ,aAAa;QACb,eAAe;QACf,gBAAgB,EAChB;IAhCJ;MAqCG,uBAAuB;MACvB,mBAAmB;MACnB,UAAU;MACV,QAAQ;MACR,YAAY;MACZ,UAAU;MACV,iBAAiB;MACjB,aAAa;MACb,iBAAiB;MACjB,iBAAiB;MACjB,sBAAsB;MACtB,mBAAmB;MACnB,kBAAkB;MAClB,qCAAgB;MAEhB,gDAAgC,EAChC;;AAKH;EAEE,aAAa;EACb,qBAAqB,EACrB;;AAJF;EAOE,cAAc;EACd,2BAA2B,EAC3B;;AATF;EAYE,8BAA8B,EAC9B;;AAbF;EAgBE,mBAAmB;EACnB,aAAa,EACb;;AAGF;EAEC,kBAAkB,EA2DlB;EA7DD;IAKE,eAAe;IACf,YAAY,EACZ;EAPF;;IAWE,uBAAuB;IAEvB,gDAAgC;IAChC,uBAAuB;IACvB,YAAY;IACZ,cAAc;IACd,mDAAmD;IACnD,2CAA2C;IAC3C,gBAAgB,EAChB;EApBF;IAwBE,iBAAiB,EACjB;EAzBF;IA4BE,sBAAsB;IACtB,iBAAiB;IACjB,oBAAoB,EACpB;EA/BF;IAkCE,YAAY;IACZ,gBAAgB;IAChB,kBAAkB,EAClB;EArCF;IAwCU,oBAAoB,EAAI;EAxClC;IA4CE,eAAe,EAKf;IAjDF;MA8CG,eAAe;MACf,oBAAoB,EACpB;EAhDH;IAuDE,kBAAkB,EAClB;IAxDF;MAqDG,sBAAsB,EACtB;EAtDH;IA2DE,YAAY,EACZ;;AC7JF;EAGE,eAAe;EACf,YAAY;EACZ,oBAAoB,EACpB;;AANF;EASE,YAAY;EACZ,sBAAsB;EACtB,aAAa,EACb;;AAZF;EAeE,eAAe,EACf;;AAhBF;EAoBE,wBAAwB;EACxB,yBAAyB;EACzB,sBAAsB;EACtB,mBAAmB;EACnB,mBAAmB;EACnB,WAAW,EAmFX;EA5GF;IA4BG,cAAc,EACd;EA7BH;IAiCG,WAAW;IACX,eAAe;IACf,mBAAmB;IACnB,SAAS;IACT,WAAW;IACX,uBAAuB;IACvB,0CAA0B;IAC1B,kBAAkB;IAClB,mBAAmB;IACnB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,iBAAgB,EAUhB;IAvDH;MAgDI,iBAAiB;MACjB,mBAAmB;MACnB,UAAU;MACV,UAAU;MACV,gBAAgB;MAChB,eAAe,EACf;EAtDJ;IA0DG,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;IACZ,aAAa,EACb;EA9DH;;IAkEG,cAAc,EACd;EAnEH;IAsEG,eAAe;IACf,mBAAmB;IACnB,YAAY;IACZ,aAAa,EACb;EA1EH;IA8EI,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,YAAY;IACZ,mBAAmB;IACnB,uBAAuB,EACvB;EApFJ;IAsFI,YAAY;IACZ,YAAY;IACZ,iBAAiB;IACjB,8BAA8B;IAC9B,qBAAqB,EAWrB;IArGJ;MA6FK,0BAA0B;MAC1B,oBAAoB;MACpB,YAAY;MACZ,YAAY;MACZ,eAAe;MACf,sEAAsE;MACtE,8DAA8D,EAC9D;EApGL;IAyGG,mBACA,EAAC;;AAMJ;EACC,cAAc,EAKd;EAND;IAIE,eAAe,EACf;;AAGF;EACC;IACC,mBAAmB,EAAA;EAEpB;IACC,kBAAkB,EAAA,EAAA;;AAIpB;EACC;IACC,mBAAmB,EAAA;EAEpB;IACC,kBAAkB,EAAA,EAAA;;ACtIpB;EAEE,iBAAiB,EACjB;;AAHF;EAME,iBAAiB;EACjB,yBAAyB,EACzB;;AARF;EAWE,gBAAgB,EAChB;;AAZF;EAeE,UAAU,EACV;;AAhBF;EAmBE,oBAAoB,EACpB;;AApBF;EAuBE,gBAAgB,EAChB;;AAxBF;EA2BE,iBAAiB;EACjB,mBAAmB;EACnB,gDAAgC;EAChC,uBAAuB;EACvB,YAAY;EACZ,cAAc,EACd;;AAjCF;EAoCE,sBAAsB;EACtB,4CAAwB,EACxB;;AAIF;EACC,gBAAgB;EAChB,iBAAiB,EACjB;;AAED;EACC,UAAU,EACV","file":"shortcode-ui.css"} -
shortcode-ui/trunk/inc/class-shortcode-ui.php
r1284972 r1536575 68 68 add_action( 'admin_enqueue_scripts', array( $this, 'action_admin_enqueue_scripts' ) ); 69 69 add_action( 'wp_enqueue_editor', array( $this, 'action_wp_enqueue_editor' ) ); 70 add_action( 'media_buttons', array( $this, 'action_media_buttons' ) ); 70 71 add_action( 'wp_ajax_bulk_do_shortcode', array( $this, 'handle_ajax_bulk_do_shortcode' ) ); 71 72 add_filter( 'wp_editor_settings', array( $this, 'filter_wp_editor_settings' ), 10, 2 ); … … 196 197 public function action_admin_enqueue_scripts( $editor_supports ) { 197 198 add_editor_style( trailingslashit( $this->plugin_url ) . 'css/shortcode-ui-editor-styles.css' ); 199 200 $min = ''; 201 202 wp_register_script( 'select2', 203 trailingslashit( $this->plugin_url ) . "lib/select2/js/select2{$min}.js", 204 array( 'jquery', 'jquery-ui-sortable' ), '4.0.3' 205 ); 206 wp_register_style( 'select2', 207 trailingslashit( $this->plugin_url ) . 'lib/select2/css/select2.css', 208 null, '4.0.3' 209 ); 198 210 } 199 211 … … 213 225 if ( $current_post_type ) { 214 226 foreach ( $shortcodes as $key => $args ) { 215 if ( ! empty( $args['post_type'] ) && ! in_array( $current_post_type, $args['post_type'] ) ) {227 if ( ! empty( $args['post_type'] ) && ! in_array( $current_post_type, $args['post_type'], true ) ) { 216 228 unset( $shortcodes[ $key ] ); 217 229 } … … 226 238 227 239 // Load minified version of wp-js-hooks if not debugging. 228 $wp_js_hooks_file = 'wp-js-hooks' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? ' .min' : '' ) . '.js';240 $wp_js_hooks_file = 'wp-js-hooks' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js'; 229 241 230 242 wp_enqueue_script( 'shortcode-ui-js-hooks', $this->plugin_url . 'lib/wp-js-hooks/' . $wp_js_hooks_file, array(), '2015-03-19' ); … … 275 287 276 288 /** 289 * Output an "Add Post Element" button with the media buttons. 290 */ 291 public function action_media_buttons( $editor_id ) { 292 printf( '<button type="button" class="button shortcake-add-post-element" data-editor="%s">' . 293 '<span class="wp-media-buttons-icon dashicons dashicons-migrate"></span> %s' . 294 '</button>', 295 esc_attr( $editor_id ), 296 esc_html__( 'Add Post Element', 'shortcode-ui' ) 297 ); 298 } 299 300 /** 277 301 * Output required underscore.js templates in the footer 278 302 */ 279 303 public function action_admin_print_footer_scripts() { 304 280 305 echo $this->get_view( 'media-frame' ); // WPCS: xss ok 281 306 echo $this->get_view( 'list-item' ); // WPCS: xss ok -
shortcode-ui/trunk/inc/fields/class-field-attachment.php
r1278066 r1536575 93 93 <div class="field-block shortcode-ui-field-attachment shortcode-ui-attribute-{{ data.attr }}"> 94 94 <label for="{{ data.attr }}">{{{ data.label }}}</label> 95 <div class="shortcake-attachment-preview attachment-preview attachment">96 <button id="{{ data.attr }}" class="button button-small add">{{ data.addButton }}</button>97 <button class="button button-small remove">×</button>98 <div class="loading-indicator">99 <span class="dashicons dashicons-format-image"></span>100 <div class="attachment-preview-loading"><ins></ins></div>101 </div>102 </div>103 <div class="thumbnail-details-container">104 <strong><?php esc_html_e( 'Thumbnail Details', 'shortcode-ui' ); ?></strong>105 <div class="filename"></div>106 <div class="date-formatted"></div>107 <div class="size"></div>108 <div class="dimensions"></div>109 <div class="edit-link"><a href="#"><?php esc_html_e( 'Edit Attachment', 'shortcode-ui' ); ?></a></div>110 </div>111 95 <# if ( typeof data.description == 'string' ) { #> 112 96 <p class="description">{{{ data.description }}}</p> 113 97 <# } #> 98 <button id="{{ data.attr }}" class="shortcake-attachment-select button button-small add">{{ data.addButton }}</button> 99 <div class="attachment-previews"></div> 100 </div> 101 </script> 102 103 <script type="text/html" id="tmpl-shortcake-image-preview"> 104 <div class="shortcake-attachment-preview"> 105 <div class="shortcake-attachment-preview-container attachment-preview attachment <# if ( data.type === 'image' && ! data.sizes ) { #>loading<# } #>"> 106 107 <button class="button button-small remove" data-id="{{ data.id }}">×</button> 108 109 <# if ( data.type === 'image' && data.sizes && data.sizes.thumbnail ) { #> 110 <div class="thumbnail"> 111 <div class="centered"> 112 <img src="{{ data.sizes.thumbnail.url }}" alt="" width="{{ data.sizes.thumbnail.width }}" height="{{ data.sizes.thumbnail.height }}" /> 113 </div> 114 </div> 115 <# } else if ( data.type === 'image' && ( ! data.sizes || ! data.sizes.thumbnail ) ) { #> 116 <div class="thumbnail"> 117 <div class="centered"> 118 <img src="{{ data.url }}" alt="" width="{{ data.width }}" height="{{ data.height }}" /> 119 </div> 120 </div> 121 <# } else if ( data.type !== 'image' ) { #> 122 <div class="thumbnail"> 123 <div class="centered"> 124 <img src="{{ data.icon }}" /> 125 </div> 126 <div class="filename"><div>{{ data.filename }}</div></div> 127 </div> 128 <# } else { #> 129 <div class="loading-indicator"> 130 <span class="dashicons dashicons-format-image"></span> 131 <div class="attachment-preview-loading"><ins></ins></div> 132 </div> 133 <# } #> 134 135 </div> 136 137 <div class="thumbnail-details-container has-attachment"> 138 <strong>Thumbnail Details</strong> 139 <div class="filename">{{ data.filename }}</div> 140 <div class="date-formatted">{{ data.dateFormatted }}</div> 141 <div class="size">{{ data.filesizeHumanReadable }}</div> 142 <# if ( data.type === 'image' ) { #> 143 <div class="dimensions">{{ data.width }} × {{ data.height }}</div> 144 <# } #> 145 <div class="edit-link"><a href="{{ data.editLink }}">Edit Attachment</a></div> 146 </div> 114 147 </div> 115 148 </script> -
shortcode-ui/trunk/inc/fields/class-field-color.php
r1278066 r1536575 113 113 <label for="{{ data.attr }}">{{{ data.label }}}</label> 114 114 <input type="text" name="{{ data.attr }}" id="{{ data.attr }}" value="{{ data.value }}" data-default-color="{{ data.value }}" {{{ data.meta }}}/> 115 <# if ( typeof data.description == 'string' ) { #>115 <# if ( typeof data.description == 'string' && data.description.length ) { #> 116 116 <p class="description">{{{ data.description }}}</p> 117 117 <# } #> -
shortcode-ui/trunk/inc/fields/class-field-post-select.php
r1281670 r1536575 39 39 public function action_enqueue_shortcode_ui() { 40 40 41 $plugin_dir = dirname( dirname( __FILE__ ) ); 42 43 wp_enqueue_script( 'select2', plugins_url( 'lib/select2/select2.min.js', $plugin_dir ) , array( 'jquery', 'jquery-ui-sortable' ), '3.5.2' ); 44 wp_enqueue_style( 'select2', plugins_url( 'lib/select2/select2.css', $plugin_dir ), null, '3.5.2' ); 41 wp_enqueue_script( 'select2' ); 42 wp_enqueue_style( 'select2' ); 45 43 46 44 wp_localize_script( 'shortcode-ui', 'shortcodeUiPostFieldData', array( … … 57 55 ?> 58 56 59 <style>60 61 .edit-shortcode-form .select2-container {62 min-width: 300px;63 }64 65 .edit-shortcode-form .select2-container a {66 transition: none;67 -webkit-transition: none;68 }69 70 .wp-admin .select2-drop {71 z-index: 160001;72 }73 74 </style>75 76 57 <script type="text/html" id="tmpl-shortcode-ui-field-post-select"> 77 58 <div class="field-block shortcode-ui-field-post-select shortcode-ui-attribute-{{ data.attr }}"> 78 59 <label for="{{ data.id }}">{{{ data.label }}}</label> 79 < input type="text" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value }}" class="shortcode-ui-post-select" />80 <# if ( typeof data.description == 'string' ) { #>60 <select id="{{ data.id }}" name="{{ data.name }}" class="shortcode-ui-post-select" ></select> 61 <# if ( typeof data.description == 'string' && data.description.length ) { #> 81 62 <p class="description">{{{ data.description }}}</p> 82 63 <# } #> … … 101 82 $requested_shortcode = isset( $_GET['shortcode'] ) ? sanitize_text_field( $_GET['shortcode'] ) : null; 102 83 $requested_attr = isset( $_GET['attr'] ) ? sanitize_text_field( $_GET['attr'] ) : null; 103 $response = array( ' posts' => array(), 'found_posts' => 0, 'posts_per_page' => 0 );84 $response = array( 'items' => array(), 'found_items' => 0, 'items_per_page' => 0 ); 104 85 105 86 $shortcodes = Shortcode_UI::get_instance()->get_shortcodes(); … … 139 120 } 140 121 141 if ( ! empty( $_GET[' post__in'] ) ) {142 $post__in = is_array( $_GET[' post__in'] ) ? $_GET['post__in'] : explode( ',', $_GET['post__in'] );122 if ( ! empty( $_GET['include'] ) ) { 123 $post__in = is_array( $_GET['include'] ) ? $_GET['include'] : explode( ',', $_GET['include'] ); 143 124 $query_args['post__in'] = array_map( 'intval', $post__in ); 144 125 $query_args['orderby'] = 'post__in'; … … 149 130 150 131 foreach ( $query->posts as $post_id ) { 151 array_push( $response[' posts'], array( 'id' => $post_id, 'text' => html_entity_decode( get_the_title( $post_id ) ) ) );132 array_push( $response['items'], array( 'id' => $post_id, 'text' => html_entity_decode( get_the_title( $post_id ) ) ) ); 152 133 } 153 134 154 $response['found_ posts'] = $query->found_posts;155 $response[' posts_per_page'] = $query->query_vars['posts_per_page'];135 $response['found_items'] = $query->found_posts; 136 $response['items_per_page'] = $query->query_vars['posts_per_page']; 156 137 157 138 wp_send_json_success( $response ); -
shortcode-ui/trunk/inc/templates/edit-form.tpl.php
r1278066 r1536575 20 20 <label for="{{ data.id }}">{{{ data.label }}}</label> 21 21 <input type="text" class="regular-text" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value }}" {{{ data.meta }}}/> 22 <# if ( typeof data.description == 'string' ) { #>22 <# if ( typeof data.description == 'string' && data.description.length ) { #> 23 23 <p class="description">{{{ data.description }}}</p> 24 24 <# } #> … … 30 30 <label for="{{ data.id }}">{{{ data.label }}}</label> 31 31 <input type="url" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value }}" class="code" {{{ data.meta }}}/> 32 <# if ( typeof data.description == 'string' ) { #>32 <# if ( typeof data.description == 'string' && data.description.length ) { #> 33 33 <p class="description">{{{ data.description }}}</p> 34 34 <# } #> … … 40 40 <label for="{{ data.id }}">{{{ data.label }}}</label> 41 41 <textarea name="{{ data.attr }}" id="{{ data.id }}" {{{ data.meta }}}>{{ data.value }}</textarea> 42 <# if ( typeof data.description == 'string' ) { #>42 <# if ( typeof data.description == 'string' && data.description.length ) { #> 43 43 <p class="description">{{{ data.description }}}</p> 44 44 <# } #> … … 50 50 <label for="{{ data.id }}">{{{ data.label }}}</label> 51 51 <select name="{{ data.attr }}" id="{{ data.id }}" {{{ data.meta }}}> 52 <# _.each( data.options, function( label, value ) { #> 53 <option value="{{ value }}" <# if ( value == data.value ){ print('selected'); } #>>{{ label }}</option> 52 <# _.each( data.options, function( option ) { #> 53 54 <# if ( 'options' in option && 'label' in option ) { #> 55 <optgroup label="{{ option.label }}"> 56 <# _.each( option.options, function( optgroupOption ) { #> 57 <option value="{{ optgroupOption.value }}" <# if ( optgroupOption.value === data.value ){ print('selected'); } #>>{{ optgroupOption.label }}</option> 58 <# }); #> 59 </optgroup> 60 <# } else { #> 61 <option value="{{ option.value }}" <# if ( option.value === data.value ){ print('selected'); } #>>{{ option.label }}</option> 62 <# } #> 63 54 64 <# }); #> 55 65 </select> 56 <# if ( typeof data.description == 'string' ) { #>66 <# if ( typeof data.description == 'string' && data.description.length ) { #> 57 67 <p class="description">{{{ data.description }}}</p> 58 68 <# } #> … … 63 73 <div class="field-block shortcode-ui-field-radio shortcode-ui-attribute-{{ data.attr }}"> 64 74 <label>{{{ data.label }}}</label> 65 <# _.each( data.options, function( label, value) { #>75 <# _.each( data.options, function( option ) { #> 66 76 <label> 67 <input type="radio" name="{{ data.attr }}" value="{{ value }}" <# if (value == data.value ) { print('checked'); } #> />68 {{ label }}77 <input type="radio" name="{{ data.attr }}" value="{{ option.value }}" <# if ( option.value == data.value ) { print('checked'); } #> /> 78 {{ option.label }} 69 79 </label> 70 80 <# }); #> 71 <# if ( typeof data.description == 'string' ) { #>81 <# if ( typeof data.description == 'string' && data.description.length ) { #> 72 82 <p class="description">{{{ data.description }}}</p> 73 83 <# } #> … … 81 91 {{{ data.label }}} 82 92 </label> 83 <# if ( typeof data.description == 'string' ) { #>93 <# if ( typeof data.description == 'string' && data.description.length ) { #> 84 94 <p class="description">{{{ data.description }}}</p> 85 95 <# } #> … … 91 101 <label for="{{ data.id }}">{{{ data.label }}}</label> 92 102 <input type="email" class="regular-text" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value}}" {{{ data.meta }}}/> 93 <# if ( typeof data.description == 'string' ) { #>103 <# if ( typeof data.description == 'string' && data.description.length ) { #> 94 104 <p class="description">{{{ data.description }}}</p> 95 105 <# } #> … … 101 111 <label for="{{ data.id }}">{{{ data.label }}}</label> 102 112 <input type="number" class="regular-text" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value}}" {{{ data.meta }}}/> 103 <# if ( typeof data.description == 'string' ) { #>113 <# if ( typeof data.description == 'string' && data.description.length ) { #> 104 114 <p class="description">{{{ data.description }}}</p> 105 115 <# } #> … … 111 121 <label for="{{ data.id }}">{{{ data.label }}}</label> 112 122 <input type="hidden" name="{{ data.attr }}" id="{{ data.id }}" value="true" {{{ data.meta }}}/> 113 <# if ( typeof data.description == 'string' ) { #>123 <# if ( typeof data.description == 'string' && data.description.length ) { #> 114 124 <p class="description">{{{ data.description }}}</p> 115 125 <# } #> … … 121 131 <label for="{{ data.id }}">{{{ data.label }}}</label> 122 132 <input type="date" name="{{ data.attr }}" id="{{ data.id }}" value="{{ data.value }}" {{{ data.meta }}}/> 123 <# if ( typeof data.description == 'string' ) { #>133 <# if ( typeof data.description == 'string' && data.description.length ) { #> 124 134 <p class="description">{{{ data.description }}}</p> 125 135 <# } #> … … 131 141 <label for="inner_content">{{{ data.label }}}</label> 132 142 <textarea id="inner_content" name="inner_content" class="content-edit" {{{ data.meta }}}>{{ data.value }}</textarea> 133 <# if ( typeof data.description == 'string' ) { #>143 <# if ( typeof data.description == 'string' && data.description.length ) { #> 134 144 <p class="description">{{{ data.description }}}</p> 135 145 <# } #> … … 144 154 <output class="range" for="{{ data.id }}" id="{{ data.id }}_indicator">{{ data.value }}</output> 145 155 </div> 146 <# if ( typeof data.description == 'string' ) { #>156 <# if ( typeof data.description == 'string' && data.description.length ) { #> 147 157 <p class="description">{{{ data.description }}}</p> 148 158 <# } #> -
shortcode-ui/trunk/js/build/shortcode-ui.js
r1284972 r1536575 64 64 var pattern = new RegExp( searchTerm, "gi" ); 65 65 var filteredModels = sui.shortcodes.filter( function( model ) { 66 pattern.lastIndex = 0; 66 67 return pattern.test( model.get( "label" ) ); 67 68 }); … … 211 212 // Encode textareas incase HTML 212 213 if ( attr.get( 'encode' ) ) { 213 attr.set( 'value', encodeURIComponent( decodeURIComponent( attr.get( 'value' ) ) ), { silent: true } );214 attr.set( 'value', encodeURIComponent( decodeURIComponent( attr.get( 'value' ).replace( "%", "%" ) ) ), { silent: true } ); 214 215 } 215 216 … … 229 230 230 231 if ( attrs.length > 0 ) { 231 template = "[{{ shortcode }} {{ attributes }} ]";232 template = "[{{ shortcode }} {{ attributes }}"; 232 233 } else { 233 template = "[{{ shortcode }} ]";234 template = "[{{ shortcode }}"; 234 235 } 235 236 236 237 if ( content && content.length > 0 ) { 237 template += "{{ content }}[/{{ shortcode }}]"; 238 template += "]{{ content }}[/{{ shortcode }}]"; 239 } else { 240 // add closing slash to shortcodes without content 241 template += "/]"; 238 242 } 239 243 … … 271 275 wp.mce.views.register( 272 276 shortcode.get('shortcode_tag'), 273 // Must extend for 4.1. 274 // This is handled by wp.mce.views.register in 4.2. 275 $.extend( true, {}, shortcodeViewConstructor ) 277 shortcodeViewConstructor 276 278 ); 277 279 } 278 280 } ); 279 281 282 $(document.body).on( 'click', '.shortcake-add-post-element', function( event ) { 283 var elem = $( event.currentTarget ), 284 editor = elem.data('editor'), 285 options = { 286 frame: 'post', 287 state: 'shortcode-ui', 288 title: shortcodeUIData.strings.media_frame_title 289 }; 290 291 event.preventDefault(); 292 293 // Remove focus from the `.shortcake-add-post-element` button. 294 // Prevents Opera from showing the outline of the button above the modal. 295 // 296 // See: https://core.trac.wordpress.org/ticket/22445 297 elem.blur(); 298 299 wp.media.editor.remove( editor ); 300 wp.media.editor.open( editor, options ); 301 } ); 302 280 303 }); 281 304 282 305 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 283 },{"./collections/shortcodes.js":2,"./utils/shortcode-view-constructor.js":9,"./utils/sui.js":10,"./views/media-frame.js": 18}],8:[function(require,module,exports){306 },{"./collections/shortcodes.js":2,"./utils/shortcode-view-constructor.js":9,"./utils/sui.js":10,"./views/media-frame.js":20}],8:[function(require,module,exports){ 284 307 (function (global){ 285 308 var $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); … … 366 389 } 367 390 368 var request = $.post( ajaxurl + '?action=bulk_do_shortcode', { 369 queries: _.pluck( fetcher.queries, 'query' ) 370 } 371 ); 372 373 request.done( function( response ) { 374 _.each( response.data, function( result, index ) { 391 var request = wp.ajax.post( 'bulk_do_shortcode', { 392 queries: _.pluck( fetcher.queries, 'query' ) 393 }); 394 395 request.done( function( responseData ) { 396 _.each( responseData, function( result, index ) { 375 397 var matchedQuery = _.findWhere( fetcher.queries, { 376 398 counter: parseInt( index ), … … 484 506 if ( attr && attr.get('encode') ) { 485 507 value = decodeURIComponent( value ); 508 value = value.replace( "%", "%" ); 486 509 } 487 510 … … 560 583 */ 561 584 edit: function( shortcodeString ) { 562 var currentShortcode; 563 564 // Backwards compatability for WP pre-4.2 565 if ( 'object' === typeof( shortcodeString ) ) { 566 shortcodeString = decodeURIComponent( $(shortcodeString).attr('data-wpview-text') ); 567 } 568 569 currentShortcode = this.parseShortcodeString( shortcodeString ); 585 586 var currentShortcode = this.parseShortcodeString( shortcodeString ); 570 587 571 588 if ( currentShortcode ) { … … 579 596 wp_media_frame.open(); 580 597 598 /* Trigger render_edit */ 599 /* 600 * Action run after an edit shortcode overlay is rendered. 601 * 602 * Called as `shortcode-ui.render_edit`. 603 * 604 * @param shortcodeModel (object) 605 * Reference to the shortcode model used in this overlay. 606 */ 607 var hookName = 'shortcode-ui.render_edit'; 608 var shortcodeModel = this.shortcodeModel; 609 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 610 581 611 } 582 612 … … 599 629 var shortcode_tags = _.map( sui.shortcodes.pluck( 'shortcode_tag' ), this.pregQuote ).join( '|' ); 600 630 var regexp = wp.shortcode.regexp( shortcode_tags ); 631 regexp.lastIndex = 0; 601 632 var matches = regexp.exec( shortcodeString ); 602 633 … … 651 682 }, 652 683 653 // Backwards compatability for Pre WP 4.2.654 View: {655 656 overlay: true,657 658 initialize: function( options ) {659 this.shortcode = this.getShortcode( options );660 this.fetch();661 },662 663 getShortcode: function( options ) {664 665 var shortcodeModel, shortcode;666 667 shortcodeModel = sui.shortcodes.findWhere( { shortcode_tag: options.shortcode.tag } );668 669 if (!shortcodeModel) {670 return;671 }672 673 shortcode = shortcodeModel.clone();674 675 shortcode.get('attrs').each(676 function(attr) {677 678 if (attr.get('attr') in options.shortcode.attrs.named) {679 attr.set('value',680 options.shortcode.attrs.named[attr681 .get('attr')]);682 }683 684 });685 686 if ('content' in options.shortcode) {687 var inner_content = shortcode.get('inner_content');688 if ( inner_content ) {689 inner_content.set('value', options.shortcode.content);690 }691 }692 693 return shortcode;694 695 },696 697 fetch : function() {698 699 var self = this;700 701 if ( ! this.parsed ) {702 703 wp.ajax.post( 'do_shortcode', {704 post_id: $( '#post_ID' ).val(),705 shortcode: this.shortcode.formatShortcode(),706 nonce: shortcodeUIData.nonces.preview,707 }).done( function( response ) {708 if ( response.indexOf( '<script' ) !== -1 ) {709 self.setIframes( self.getEditorStyles(), response );710 } else {711 self.parsed = response;712 self.render( true );713 }714 }).fail( function() {715 self.parsed = '<span class="shortcake-error">' + shortcodeUIData.strings.mce_view_error + '</span>';716 self.render( true );717 } );718 719 }720 721 },722 723 /**724 * Render the shortcode725 *726 * To ensure consistent rendering - this makes an ajax request to the727 * admin and displays.728 *729 * @return string html730 */731 getHtml : function() {732 return this.parsed;733 },734 735 /**736 * Returns an array of <link> tags for stylesheets applied to the TinyMCE editor.737 *738 * @method getEditorStyles739 * @returns {Array}740 */741 getEditorStyles: function() {742 743 var styles = '';744 745 this.getNodes( function ( editor, node, content ) {746 var dom = editor.dom,747 bodyClasses = editor.getBody().className || '',748 iframe, iframeDoc, i, resize;749 750 tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) {751 if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&752 link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {753 754 styles += dom.getOuterHTML( link ) + '\n';755 }756 757 });758 759 } );760 761 return styles;762 },763 764 },765 684 }; 766 685 … … 781 700 782 701 },{"./../collections/shortcodes.js":2}],11:[function(require,module,exports){ 702 (function (global){ 783 703 var sui = require('./../utils/sui.js'); 704 var $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 784 705 785 706 var editAttributeFieldAttachment = sui.views.editAttributeField.extend( { 707 708 previewTemplate: wp.template( 'shortcake-image-preview' ), 786 709 787 710 events: { … … 792 715 }, 793 716 717 currentSelection: [], 718 719 initialize: function() { 720 721 var self = this; 722 723 _.bindAll( self, 'updateValue', 'initSelection', '_renderPreview', '_renderAll', '_removeAttachment' ); 724 725 self.initSelection(); 726 727 self.currentSelection.on( 'all', this.updateValue ); 728 self.currentSelection.on( 'add', this._renderPreview ); 729 self.currentSelection.on( 'reset', this._renderAll ); 730 731 }, 732 733 /** 734 * Initialize Selection. 735 * 736 * Selection is an Attachment collection containing full models for the current value. 737 * 738 * @return null 739 */ 740 initSelection: function() { 741 742 this.currentSelection = new wp.media.model.Selection( [], { 743 multiple: this.model.get( 'multiple' ) ? true : false, 744 } ); 745 746 // Initialize selection. 747 _.each( this.getValue(), function( item ) { 748 749 var model; 750 751 // Legacy. Handle storing full objects. 752 item = ( 'object' === typeof( item ) ) ? item.id : item; 753 model = new wp.media.attachment( item ); 754 755 this.currentSelection.add( model ); 756 757 // Re-render after attachments have synced. 758 model.fetch(); 759 model.on( 'sync', this._renderAll ); 760 761 }.bind(this) ); 762 763 }, 764 794 765 /** 795 766 * Update the field attachment. … … 799 770 * @param {int} id Attachment ID 800 771 */ 801 updateValue: function( id ) { 802 803 if ( ! id ) { 804 return; 805 } 806 807 this.setValue( id ); 808 809 var self = this; 810 811 if ( editAttributeFieldAttachment.getFromCache( id ) ) { 812 self._renderPreview( editAttributeFieldAttachment.getFromCache( id ) ); 813 814 // Call the updateValue() function, to trigger any listeners 815 // hooked on it. 816 self.triggerCallbacks(); 817 return; 818 } 819 820 this.$container.addClass( 'loading' ); 821 822 wp.ajax.post( 'get-attachment', { 823 'id': id 824 } ).done( function( attachment ) { 825 // Cache for later. 826 editAttributeFieldAttachment.setInCache( id, attachment ); 827 self._renderPreview( attachment ); 828 829 // Call the updateValue() function, to trigger any listeners 830 // hooked on it. 831 self.triggerCallbacks(); 832 } ).always( function( attachment ) { 833 self.$container.removeClass( 'loading' ); 834 }); 772 updateValue: function() { 773 var value = this.currentSelection.pluck( 'id' ); 774 this.setValue( value ); 775 this.triggerCallbacks(); 835 776 }, 836 777 … … 846 787 this.$el.html( this.template( this.model.toJSON() ) ); 847 788 848 this.$container = this.$el.find( '.shortcake-attachment-preview' );789 this.$container = this.$el.find( '.attachment-previews' ); 849 790 this.$thumbnailDetailsContainer = this.$el.find( '.thumbnail-details-container' ); 850 var $addButton = this.$container.find( 'button.add' );791 var $addButton = this.$container.find( 'button.add' ); 851 792 852 793 this.frame = wp.media( { 853 multiple: false,854 title: this.model.get( 'frameTitle' ),794 multiple: this.model.get( 'multiple' ) ? true : false, 795 title: this.model.get( 'frameTitle' ), 855 796 library: { 856 797 type: this.model.get( 'libraryType' ), … … 858 799 } ); 859 800 860 // Add initial Attachment if available. 861 this.updateValue( this.model.get( 'value' ) ); 801 this.frame.on( 'select', function() { 802 this.$el.trigger( 'selectAttachment' ); 803 }.bind( this ) ); 804 805 this._renderAll(); 806 807 }, 808 809 _renderAll: function() { 810 811 // Empty container. 812 this.$container.html(''); 813 814 // Render each attachment in current selection. 815 this.currentSelection.each( function( attachment ) { 816 this._renderPreview( attachment ); 817 }.bind(this) ); 862 818 863 819 }, … … 870 826 _renderPreview: function( attachment ) { 871 827 872 var $thumbnail = jQuery('<div class="thumbnail"></div>'); 873 874 if ( 'image' !== attachment.type ) { 875 876 jQuery( '<img/>', { 877 src: attachment.icon, 878 alt: attachment.title, 879 } ).appendTo( $thumbnail ); 880 881 jQuery( '<div/>', { 882 class: 'filename', 883 html: '<div>' + attachment.title + '</div>', 884 } ).appendTo( $thumbnail ); 885 886 } else { 887 888 attachmentThumb = (typeof attachment.sizes.thumbnail !== 'undefined') ? 889 attachment.sizes.thumbnail : 890 _.first( _.sortBy( attachment.sizes, 'width' ) ); 891 892 jQuery( '<img/>', { 893 src: attachmentThumb.url, 894 width: attachmentThumb.width, 895 height: attachmentThumb.height, 896 alt: attachment.alt, 897 } ) .appendTo( $thumbnail ); 898 899 } 900 901 $thumbnail.find( 'img' ).wrap( '<div class="centered"></div>' ); 902 this.$container.append( $thumbnail ); 903 this.$container.toggleClass( 'has-attachment', true ); 904 905 this.$thumbnailDetailsContainer.find( '.filename' ).text( attachment.filename ); 906 this.$thumbnailDetailsContainer.find( '.date-formatted' ).text( attachment.dateFormatted ); 907 this.$thumbnailDetailsContainer.find( '.size' ).text( attachment.filesizeHumanReadable ); 908 this.$thumbnailDetailsContainer.find( '.dimensions' ).text( attachment.height + ' × ' + attachment.width ); 909 this.$thumbnailDetailsContainer.find( '.edit-link a' ).attr( "href", attachment.editLink ); 910 this.$thumbnailDetailsContainer.toggleClass( 'has-attachment', true ); 828 var $thumbnail = $( this.previewTemplate( attachment.toJSON() ) ); 829 830 $thumbnail.appendTo( this.$container ); 831 832 attachment.on( 'remove', function() { 833 $thumbnail.remove(); 834 } ); 835 836 }, 837 838 getValue: function() { 839 840 var value = this.model.get( 'value' ); 841 842 if ( ! ( value instanceof Array ) ) { 843 value = value.split( ',' ); 844 } 845 846 value = value.map( function( id ) { 847 return parseInt( id, 10 ); 848 } ); 849 850 value = value.filter( function( id ) { 851 return id > 0; 852 } ); 853 854 value.sort( function( a, b ) { 855 return a < b; 856 } ); 857 858 return value; 911 859 912 860 }, … … 917 865 */ 918 866 _openMediaFrame: function(e) { 867 919 868 e.preventDefault(); 920 869 this.frame.open(); 921 if ( this.model.get( 'value' ) ) { 922 var selection = this.frame.state().get('selection'); 923 attachment = wp.media.attachment( this.model.get( 'value' ) ); 924 attachment.fetch(); 925 selection.reset( attachment ? [ attachment ] : [] ); 926 this.frame.state().set('selection', selection); 927 } 928 929 var self = this; 930 this.frame.on( 'select', function() { 931 self.$el.trigger( 'selectAttachment' ); 932 } ); 870 871 var selection = this.frame.state().get('selection'); 872 selection.reset( this.currentSelection.models ); 873 this.frame.state('library').set( 'selection', selection ); 933 874 934 875 }, … … 939 880 */ 940 881 _selectAttachment: function(e) { 882 941 883 var selection = this.frame.state().get('selection'); 942 attachment = selection.first(); 943 if ( attachment.id != this.model.get( 'value' ) ){ 944 this.model.set( 'value', null ); 945 this.$container.toggleClass( 'has-attachment', false ); 946 this.$container.find( '.thumbnail' ).remove(); 947 this.updateValue( attachment.id ); 948 } 884 this.currentSelection.reset( selection.toJSON() ); 885 949 886 this.frame.close(); 887 950 888 }, 951 889 … … 955 893 */ 956 894 _removeAttachment: function(e) { 895 957 896 e.preventDefault(); 958 897 959 this.model.set( 'value', null ); 960 961 this.$container.toggleClass( 'has-attachment', false ); 962 this.$container.find( '.thumbnail' ).remove(); 963 this.$thumbnailDetailsContainer.toggleClass( 'has-attachment', false ); 964 }, 965 966 }, { 967 968 _idCache: {}, 969 970 /** 971 * Store attachments in a cache for quicker loading. 972 */ 973 setInCache: function( id, attachment ) { 974 this._idCache[ id ] = attachment; 975 }, 976 977 /** 978 * Retrieve an attachment from the cache. 979 */ 980 getFromCache: function( id ){ 981 if ( 'undefined' === typeof this._idCache[ id ] ) { 982 return false; 983 } 984 return this._idCache[ id ]; 898 var id = $( e.target ).attr( 'data-id' ); 899 900 if ( ! id ) { 901 return; 902 } 903 904 var target = this.currentSelection.get( id ); 905 906 if ( target ) { 907 this.currentSelection.remove( target ); 908 } 909 985 910 }, 986 911 … … 990 915 991 916 917 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 992 918 },{"./../utils/sui.js":10}],12:[function(require,module,exports){ 993 919 (function (global){ … … 1048 974 1049 975 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1050 },{"./../utils/sui.js":10,"./edit-attribute-field.js":14}],13:[function(require,module,exports){ 1051 ( function( $ ) { 1052 1053 var sui = window.Shortcode_UI; 1054 1055 // Cached Data. 1056 var postSelectCache = {}; 1057 1058 sui.views.editAttributeFieldPostSelect = sui.views.editAttributeField.extend( { 1059 1060 events: { 1061 'change .shortcode-ui-post-select': 'inputChanged', 1062 }, 1063 1064 inputChanged: function(e) { 1065 this.setValue( e.val ); 1066 this.triggerCallbacks(); 1067 }, 1068 1069 render: function() { 1070 1071 var self = this, 1072 defaults = { multiple: false }; 1073 1074 for ( var arg in defaults ) { 1075 if ( ! this.model.get( arg ) ) { 1076 this.model.set( arg, defaults[ arg ] ); 1077 } 1078 } 1079 1080 var data = this.model.toJSON(); 1081 data.id = 'shortcode-ui-' + this.model.get( 'attr' ) + '-' + this.model.cid; 1082 1083 this.$el.html( this.template( data ) ); 1084 1085 var ajaxData = { 1086 action : 'shortcode_ui_post_field', 1087 nonce : shortcodeUiPostFieldData.nonce, 1088 shortcode : this.shortcode.get( 'shortcode_tag'), 1089 attr : this.model.get( 'attr' ) 1090 }; 1091 1092 var $field = this.$el.find( '.shortcode-ui-post-select' ); 1093 1094 $field.select2({ 1095 1096 placeholder: "Search", 1097 multiple: this.model.get( 'multiple' ), 1098 ajax: { 1099 url: ajaxurl, 1100 dataType: 'json', 1101 quietMillis: 250, 1102 data: function (term, page) { 1103 ajaxData.s = term; 1104 ajaxData.page = page; 1105 return ajaxData; 1106 }, 1107 results: function ( response, page ) { 1108 1109 if ( ! response.success ) { 1110 return { results: {}, more: false }; 1111 } 1112 1113 // Cache data for quicker rendering later. 1114 postSelectCache = $.extend( postSelectCache, response.data.posts ); 1115 1116 var more = ( page * response.data.posts_per_page ) < response.data.found_posts; // whether or not there are more results available 1117 return { results: response.data.posts, more: more }; 1118 1119 }, 1120 }, 1121 1122 /** 1123 * Initialize Callback 1124 * Used to set render the initial value. 1125 * Has to make a request to get the title for the current ID. 1126 */ 1127 initSelection: function(element, callback) { 1128 1129 var ids, parsedData = [], cached; 1130 1131 // Convert stored value to array of IDs (int). 1132 ids = $(element) 1133 .val() 1134 .split(',') 1135 .map( function (str) { return str.trim(); } ) 1136 .map( function (str) { return parseInt( str ); } ); 1137 1138 if ( ids.length < 1 ) { 1139 return; 1140 } 1141 1142 // Check if there is already cached data. 1143 for ( var i = 0; i < ids.length; i++ ) { 1144 cached = _.find( postSelectCache, _.matches( { id: ids[i] } ) ); 1145 if ( cached ) { 1146 parsedData.push( cached ); 1147 } 1148 } 1149 1150 // If not multiple - return single value if we have one. 1151 if ( parsedData.length && ! self.model.get( 'multiple' ) ) { 1152 callback( parsedData[0] ); 1153 return; 1154 } 1155 1156 var uncachedIds = _.difference( ids, _.pluck( parsedData, 'id' ) ); 1157 1158 if ( ! uncachedIds.length ) { 1159 1160 callback( parsedData ); 1161 1162 } else { 1163 1164 var initAjaxData = jQuery.extend( true, {}, ajaxData ); 1165 initAjaxData.action = 'shortcode_ui_post_field'; 1166 initAjaxData.post__in = uncachedIds; 1167 1168 $.get( ajaxurl, initAjaxData ).done( function( response ) { 1169 1170 if ( ! response.success ) { 1171 return { results: {}, more: false }; 1172 } 1173 1174 postSelectCache = $.extend( postSelectCache, response.data.posts ); 1175 1176 // If not multi-select, expects single object, not array of objects. 1177 if ( ! self.model.get( 'multiple' ) ) { 1178 callback( response.data.posts[0] ); 1179 return; 1180 } 1181 1182 // Append new data to cached data. 1183 // Sort by original order. 1184 parsedData = parsedData 1185 .concat( response.data.posts ) 1186 .sort(function (a, b) { 1187 if ( ids.indexOf( a.id ) > ids.indexOf( b.id ) ) return 1; 1188 if ( ids.indexOf( a.id ) < ids.indexOf( b.id ) ) return -1; 1189 return 0; 1190 }); 1191 1192 callback( parsedData ); 1193 return; 1194 1195 } ); 1196 1197 } 1198 1199 }, 1200 1201 } ); 1202 1203 // Make multiple values sortable. 1204 if ( this.model.get( 'multiple' ) ) { 1205 $field.select2('container').find('ul.select2-choices').sortable({ 1206 containment: 'parent', 1207 start: function() { $('.shortcode-ui-post-select').select2('onSortStart'); }, 1208 update: function() { $('.shortcode-ui-post-select').select2('onSortEnd'); } 1209 }); 1210 } 1211 1212 return this; 1213 1214 } 1215 1216 } ); 1217 1218 /** 1219 * Extending SUI Media Controller to hide Select2 UI Drop-Down when menu 1220 * changes in Meida modal 1221 * 1. going back/forth between different shortcakes (refresh) 1222 * 2. changing the menu in left column (deactivate) 1223 * 3. @TODO closing the modal. 1224 */ 1225 var mediaController = sui.controllers.MediaController; 1226 sui.controllers.MediaController = mediaController.extend({ 1227 1228 refresh: function(){ 1229 mediaController.prototype.refresh.apply( this, arguments ); 1230 this.destroySelect2UI(); 1231 }, 1232 1233 //doesn't need to call parent as it already an "abstract" method in parent to provide callback 1234 deactivate: function() { 1235 this.destroySelect2UI(); 1236 }, 1237 1238 destroySelect2UI: function() { 1239 $('.shortcode-ui-post-select.select2-container').select2( "close" ); 1240 } 1241 1242 }); 1243 1244 } )( jQuery ); 1245 1246 },{}],14:[function(require,module,exports){ 976 },{"./../utils/sui.js":10,"./edit-attribute-field.js":16}],13:[function(require,module,exports){ 977 (function (global){ 978 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 979 sui = require('./../utils/sui.js'), 980 select2Field = require('./select2-field.js'), 981 $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 982 983 sui.views.editAttributeFieldPostSelect = sui.views.editAttributeSelect2Field.extend( { 984 985 selector: '.shortcode-ui-post-select', 986 987 ajaxData: { 988 action : 'shortcode_ui_post_field', 989 nonce : shortcodeUiPostFieldData.nonce, 990 }, 991 992 events: { 993 'change .shortcode-ui-post-select': 'inputChanged', 994 }, 995 996 templateResult: function( post ) { 997 if ( post.loading ) { 998 return post.text; 999 } 1000 1001 var markup = '<div class="clearfix select2-result-selectable">' + 1002 post.text + 1003 '</div>'; 1004 1005 return markup; 1006 }, 1007 1008 templateSelection: function( post, container ) { 1009 return post.text; 1010 }, 1011 1012 1013 } ); 1014 1015 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1016 },{"./../utils/sui.js":10,"./select2-field.js":23}],14:[function(require,module,exports){ 1017 (function (global){ 1018 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 1019 sui = require('./../utils/sui.js'), 1020 select2Field = require('./select2-field.js'), 1021 $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 1022 1023 sui.views.editAttributeFieldTermSelect = sui.views.editAttributeSelect2Field.extend( { 1024 1025 selector: '.shortcode-ui-term-select', 1026 1027 ajaxData: { 1028 action : 'shortcode_ui_term_field', 1029 nonce : shortcodeUiTermFieldData.nonce, 1030 }, 1031 1032 events: { 1033 'change .shortcode-ui-term-select': 'inputChanged', 1034 }, 1035 1036 templateResult: function( post ) { 1037 if ( post.loading ) { 1038 return post.text; 1039 } 1040 1041 var markup = '<div class="clearfix select2-result-selectable">' + 1042 post.text + 1043 '</div>'; 1044 1045 return markup; 1046 }, 1047 1048 templateSelection: function( post, container ) { 1049 return post.text; 1050 }, 1051 1052 } ); 1053 1054 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1055 },{"./../utils/sui.js":10,"./select2-field.js":23}],15:[function(require,module,exports){ 1056 (function (global){ 1057 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 1058 sui = require('./../utils/sui.js'), 1059 select2Field = require('./select2-field.js'), 1060 $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 1061 1062 sui.views.editAttributeFieldUserSelect = sui.views.editAttributeSelect2Field.extend( { 1063 1064 selector: '.shortcode-ui-user-select', 1065 1066 ajaxData: { 1067 action : 'shortcode_ui_user_field', 1068 nonce : shortcodeUiUserFieldData.nonce, 1069 }, 1070 1071 events: { 1072 'change .shortcode-ui-user-select': 'inputChanged', 1073 }, 1074 1075 templateResult: function( user ) { 1076 if ( user.loading ) { 1077 return user.text; 1078 } 1079 1080 var markup = '<div class="clearfix select2-result-selectable">' + 1081 user.text + 1082 '</div>'; 1083 1084 return markup; 1085 }, 1086 1087 templateSelection: function( user, container ) { 1088 return user.text; 1089 }, 1090 1091 1092 } ); 1093 1094 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1095 },{"./../utils/sui.js":10,"./select2-field.js":23}],16:[function(require,module,exports){ 1247 1096 (function (global){ 1248 1097 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), … … 1289 1138 1290 1139 data.meta = _meta.join( ' ' ); 1140 1141 // Ensure options are formatted correctly. 1142 if ( 'options' in data ) { 1143 data.options = this.parseOptions( data.options ); 1144 } 1291 1145 1292 1146 this.$el.html( this.template( data ) ); … … 1361 1215 wp.shortcake.hooks.doAction( hookName, changed, collection, shortcode ); 1362 1216 1217 }, 1218 1219 /** 1220 * Parse Options to ensure they use the correct format. 1221 * 1222 * Backwards compatability for non-array options. 1223 * Using objects was sub-optimal because properties don't have an order. 1224 */ 1225 parseOptions: function( options ) { 1226 1227 if ( ! Array.isArray( options ) ) { 1228 var _options = []; 1229 _.each( Object.keys( options ), function( key ) { 1230 _options.push( { value: key, label: options[ key ] } ); 1231 } ); 1232 options = _options; 1233 } else { 1234 options = options.map( function( option ) { 1235 if ( 'object' !== typeof option ) { 1236 option = { value: option, label: option }; 1237 } 1238 return option; 1239 } ); 1240 } 1241 1242 return options; 1243 1363 1244 } 1364 1245 … … 1387 1268 1388 1269 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1389 },{"./../utils/sui.js":10}],1 5:[function(require,module,exports){1270 },{"./../utils/sui.js":10}],17:[function(require,module,exports){ 1390 1271 (function (global){ 1391 1272 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null), … … 1398 1279 editAttributeFieldAttachment = require('./edit-attribute-field-attachment.js'), 1399 1280 editAttributeFieldPostSelect = require('./edit-attribute-field-post-select.js'), 1400 editAttributeFieldColor = require('./edit-attribute-field-color.js'); 1281 editAttributeFieldTermSelect = require('./edit-attribute-field-term-select.js'), 1282 editAttributeFieldUserSelect = require('./edit-attribute-field-user-select.js'), 1283 editAttributeFieldColor = require('./edit-attribute-field-color.js'); 1401 1284 1402 1285 … … 1471 1354 1472 1355 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1473 },{"./../utils/sui.js":10,"./edit-attribute-field-attachment.js":11,"./edit-attribute-field-color.js":12,"./edit-attribute-field-post-select.js":13,"./edit-attribute-field .js":14}],16:[function(require,module,exports){1356 },{"./../utils/sui.js":10,"./edit-attribute-field-attachment.js":11,"./edit-attribute-field-color.js":12,"./edit-attribute-field-post-select.js":13,"./edit-attribute-field-term-select.js":14,"./edit-attribute-field-user-select.js":15,"./edit-attribute-field.js":16}],18:[function(require,module,exports){ 1474 1357 (function (global){ 1475 1358 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null), … … 1505 1388 1506 1389 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1507 },{}],1 7:[function(require,module,exports){1390 },{}],19:[function(require,module,exports){ 1508 1391 (function (global){ 1509 1392 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null); … … 1552 1435 1553 1436 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1554 },{"./../collections/shortcodes.js":2,"./insert-shortcode-list-item.js":1 6}],18:[function(require,module,exports){1437 },{"./../collections/shortcodes.js":2,"./insert-shortcode-list-item.js":18}],20:[function(require,module,exports){ 1555 1438 (function (global){ 1556 1439 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null), … … 1668 1551 1669 1552 insertAction: function() { 1553 /* Trigger render_destroy */ 1554 /* 1555 * Action run before the shortcode overlay is destroyed. 1556 * 1557 * Called as `shortcode-ui.render_destroy`. 1558 * 1559 * @param shortcodeModel (object) 1560 * Reference to the shortcode model used in this overlay. 1561 */ 1562 var hookName = 'shortcode-ui.render_destroy'; 1563 var shortcodeModel = this.controller.state().props.get( 'currentShortcode' ); 1564 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 1565 1670 1566 this.controller.state().insert(); 1567 1671 1568 }, 1672 1569 … … 1676 1573 1677 1574 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1678 },{"./../controllers/media-controller.js":3,"./media-toolbar": 19,"./shortcode-ui":22}],19:[function(require,module,exports){1575 },{"./../controllers/media-controller.js":3,"./media-toolbar":21,"./shortcode-ui":24}],21:[function(require,module,exports){ 1679 1576 (function (global){ 1680 1577 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null); … … 1708 1605 1709 1606 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1710 },{}],2 0:[function(require,module,exports){1607 },{}],22:[function(require,module,exports){ 1711 1608 (function (global){ 1712 1609 var wp = (typeof window !== "undefined" ? window['wp'] : typeof global !== "undefined" ? global['wp'] : null); … … 1756 1653 1757 1654 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1758 },{"./../utils/sui.js":10}],21:[function(require,module,exports){ 1759 (function (global){ 1760 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 1761 $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 1655 },{"./../utils/sui.js":10}],23:[function(require,module,exports){ 1656 (function (global){ 1657 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 1658 sui = require('./../utils/sui.js'), 1659 $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); 1762 1660 1763 1661 /** 1764 * Preview of rendered shortcode. 1765 * Asynchronously fetches rendered shortcode content from WordPress. 1766 * Displayed in an iframe to isolate editor styles. 1662 * Abstract field for all ajax Select2-powered field views 1767 1663 * 1768 * @class ShortcodePreview 1769 * @constructor 1770 * @params options 1771 * @params options.model {Shortcode} Requires a valid shortcode. 1664 * Adds useful helpers that are shared between all of the fields which use 1665 * Select2 as their UI. 1666 * 1772 1667 */ 1773 var ShortcodePreview = Backbone.View.extend({ 1774 initialize: function( options ) { 1775 this.head = this.getEditorStyles().join( "\n" ); 1776 }, 1777 1778 getLoading: function() { 1779 return '<div class="loading-placeholder">' + 1780 '<div class="dashicons dashicons-admin-media"></div>' + 1781 '<div class="wpview-loading"><ins></ins></div>' + 1782 '</div>'; 1783 }, 1784 1785 /** 1786 * @method render 1787 * @chainable 1788 * @returns {ShortcodePreview} 1789 */ 1668 sui.views.editAttributeSelect2Field = sui.views.editAttributeField.extend( { 1669 1670 /** 1671 * Store selection on model as a string. If this is a multiple selection, 1672 * we'll be storing the value as a comma-separated list. 1673 * 1674 * @param jQuery.Event Change event triggered. 1675 */ 1676 inputChanged: function(e) { 1677 var _selected = $( e.currentTarget ).val(); 1678 1679 // Store multiple selections as comma-delimited list 1680 if ( Array.isArray( _selected ) ) { 1681 _selected = _selected.join( ',' ); 1682 } 1683 1684 this.setValue( String( _selected ) ); 1685 this.triggerCallbacks(); 1686 }, 1687 1688 /** 1689 * Load the values to be preselected before initializing field 1690 * 1691 * @param $field jQuery object reference to the <select> field 1692 * @param object ajaxData object containing ajax action, nonce, and shortcode & model data 1693 * @param string includeField how to specify the current selection, ie 'post__in' 1694 */ 1695 preselect: function( $field ) { 1696 var _preselected = String( this.getValue() ); 1697 1698 if ( _preselected.length ) { 1699 var request = { 1700 include : _preselected, 1701 shortcode : this.shortcode.get( 'shortcode_tag'), 1702 attr : this.model.get( 'attr' ) 1703 }; 1704 1705 $.get( ajaxurl, $.extend( request, this.ajaxData ), 1706 function( response ) { 1707 _.each( response.data.items, function( item ) { 1708 $('<option>') 1709 .attr( 'value', item.id ) 1710 .text( item.text ) 1711 .prop( 'selected', 'selected' ) 1712 .appendTo( $field ); 1713 } ); 1714 } 1715 ); 1716 } 1717 }, 1718 1719 /** 1720 * Make selections in this field sortable, if it's multiple select 1721 * 1722 * @param $field jQuery object reference to the <select> field 1723 */ 1724 sortable: function( $field ) { 1725 var ul = $field.next('.select2-container').first('ul.select2-selection__rendered'); 1726 ul.sortable({ 1727 placeholder : 'ui-state-highlight', 1728 forcePlaceholderSize: true, 1729 items : 'li:not(.select2-search__field)', 1730 tolerance : 'pointer', 1731 stop: function() { 1732 $( $(ul).find('.select2-selection__choice').get().reverse() ).each(function() { 1733 var id = $(this).data('data').id; 1734 var option = $field.find('option[value="' + id + '"]')[0]; 1735 $field.prepend(option); 1736 }); 1737 $field.trigger( 'change' ); 1738 } 1739 }); 1740 }, 1741 1790 1742 render: function() { 1791 1743 1792 var self = this; 1793 1794 // Render loading iFrame. 1795 this.renderIFrame({ 1796 head: self.head, 1797 body: self.getLoading(), 1798 }); 1799 1800 // Fetch shortcode preview. 1801 // Render iFrame with shortcode preview. 1802 this.fetchShortcode( function( response ) { 1803 self.renderIFrame({ 1804 head: self.head, 1805 body: response, 1806 }); 1807 }); 1744 var self = this, 1745 defaults = { multiple: false }; 1746 1747 for ( var arg in defaults ) { 1748 if ( ! this.model.get( arg ) ) { 1749 this.model.set( arg, defaults[ arg ] ); 1750 } 1751 } 1752 1753 var data = this.model.toJSON(); 1754 data.id = 'shortcode-ui-' + this.model.get( 'attr' ) + '-' + this.model.cid; 1755 1756 this.$el.html( this.template( data ) ); 1757 1758 var $field = this.$el.find( this.selector ); 1759 1760 this.preselect( $field ); 1761 1762 var $fieldSelect2 = $field.select2({ 1763 placeholder: "Search", 1764 multiple: this.model.get( 'multiple' ), 1765 1766 ajax: { 1767 url: ajaxurl, 1768 dataType: 'json', 1769 delay: 250, 1770 data: function (params) { 1771 return $.extend( { 1772 s : params.term, // search term 1773 page : params.page, 1774 shortcode : self.shortcode.get( 'shortcode_tag'), 1775 attr : self.model.get( 'attr' ) 1776 }, self.ajaxData ); 1777 }, 1778 processResults: function (response, params) { 1779 if ( ! response.success || 'undefined' === typeof response.data ) { 1780 return { results: [] }; 1781 } 1782 var data = response.data; 1783 params.page = params.page || 1; 1784 return { 1785 results: data.items, 1786 pagination: { 1787 more: ( params.page * data.items_per_page ) < data.found_items 1788 } 1789 }; 1790 }, 1791 cache: true 1792 }, 1793 escapeMarkup: function( markup ) { return markup; }, 1794 minimumInputLength: 1, 1795 templateResult: this.templateResult, 1796 templateSelection: this.templateSelection, 1797 } ); 1798 1799 if ( this.model.get( 'multiple' ) ) { 1800 this.sortable( $field ); 1801 } 1808 1802 1809 1803 return this; 1810 },1811 1812 /**1813 * Render a child iframe, removing any previously rendered iframe. Additionally, observe the rendered iframe1814 * for mutations and resize as necessary to match content.1815 *1816 * @param params1817 */1818 renderIFrame: function( params ) {1819 1820 var self = this, $iframe, resize;1821 1822 _.defaults( params || {}, { 'head': '', 'body': '', 'body_classes': 'shortcake shortcake-preview' });1823 1824 var isIE = typeof tinymce != 'undefined' ? tinymce.Env.ie : false;1825 1826 $iframe = $( '<iframe/>', {1827 src: isIE ? 'javascript:""' : '', // jshint ignore:line1828 frameBorder: '0',1829 allowTransparency: 'true',1830 scrolling: 'no',1831 style: "width: 100%; display: block",1832 } );1833 1834 /**1835 * Render preview in iFrame once loaded.1836 * This is required because you can't write to1837 * an iFrame contents before it exists.1838 */1839 $iframe.load( function() {1840 1841 self.autoresizeIframe( $(this) );1842 1843 var head = $(this).contents().find('head'),1844 body = $(this).contents().find('body');1845 1846 head.html( params.head );1847 body.html( params.body );1848 body.addClass( params.body_classes );1849 1850 } );1851 1852 this.$el.html( $iframe );1853 1854 },1855 1856 /**1857 * Watch for mutations in iFrame content.1858 * resize iFrame height on change.1859 *1860 * @param $ object $iframe1861 */1862 autoresizeIframe: function( $iframe ) {1863 1864 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;1865 1866 // Resize iFrame to size inner document.1867 var resize = function() {1868 $iframe.height( $iframe.contents().find('html').height() );1869 };1870 1871 resize();1872 1873 if ( MutationObserver ) {1874 1875 var observer = new MutationObserver( function() {1876 resize();1877 $iframe.contents().find('img,link').load( resize );1878 } );1879 1880 observer.observe(1881 $iframe.contents()[0],1882 { attributes: true, childList: true, subtree: true }1883 );1884 1885 } else {1886 1887 for ( i = 1; i < 6; i++ ) {1888 setTimeout( resize, i * 700 );1889 }1890 1891 }1892 1893 },1894 1895 1896 /**1897 * Makes an AJAX call to the server to render the shortcode based on user supplied attributes. Server-side1898 * rendering is necessary to allow for shortcodes that incorporate external content based on shortcode1899 * attributes.1900 *1901 * @method fetchShortcode1902 * @returns {String} Rendered shortcode markup (HTML).1903 */1904 fetchShortcode: function( callback ) {1905 1906 wp.ajax.post( 'do_shortcode', {1907 post_id: $( '#post_ID' ).val(),1908 shortcode: this.model.formatShortcode(),1909 nonce: shortcodeUIData.nonces.preview,1910 }).done( function( response ) {1911 callback( response );1912 }).fail( function() {1913 var span = $('<span />').addClass('shortcake-error').text( shortcodeUIData.strings.mce_view_error );1914 var wrapper = $('<div />').html( span );1915 callback( wrapper.html() );1916 } );1917 1918 },1919 1920 /**1921 * Returns an array of <link> tags for stylesheets applied to the TinyMCE editor.1922 *1923 * @method getEditorStyles1924 * @returns {Array}1925 */1926 getEditorStyles: function() {1927 var styles = {};1928 1929 var editors = typeof tinymce != 'undefined' ? tinymce.editors : [];1930 _.each( editors, function( editor ) {1931 _.each( editor.dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) {1932 if ( link.href ) {1933 styles[ link.href ] = true;1934 }1935 });1936 });1937 1938 styles = _.map( _.keys( styles ), function( href ) {1939 return $( '<link rel="stylesheet" type="text/css">' ).attr( 'href', href )[0].outerHTML;1940 });1941 1942 return styles;1943 1804 } 1944 1805 }); 1945 1806 1946 module.exports = ShortcodePreview; 1947 1948 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1949 },{}],22:[function(require,module,exports){ 1807 /** 1808 * Extending SUI Media Controller to hide Select2 UI Drop-Down when menu 1809 * changes in Meida modal 1810 * 1. going back/forth between different shortcakes (refresh) 1811 * 2. changing the menu in left column (deactivate) 1812 * 3. @TODO closing the modal. 1813 */ 1814 var mediaController = sui.controllers.MediaController; 1815 sui.controllers.MediaController = mediaController.extend({ 1816 1817 refresh: function(){ 1818 mediaController.prototype.refresh.apply( this, arguments ); 1819 this.destroySelect2UI(); 1820 }, 1821 1822 //doesn't need to call parent as it already an "abstract" method in parent to provide callback 1823 deactivate: function() { 1824 this.destroySelect2UI(); 1825 }, 1826 1827 destroySelect2UI: function() { 1828 $fieldSelect2.select2( 'close' ); 1829 } 1830 1831 }); 1832 1833 1834 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1835 },{"./../utils/sui.js":10}],24:[function(require,module,exports){ 1950 1836 (function (global){ 1951 1837 var Backbone = (typeof window !== "undefined" ? window['Backbone'] : typeof global !== "undefined" ? global['Backbone'] : null), 1952 1838 insertShortcodeList = require('./insert-shortcode-list.js'), 1953 ShortcodePreview = require('./shortcode-preview.js'),1954 1839 EditShortcodeForm = require('./edit-shortcode-form.js'), 1955 1840 Toolbar = require('./media-toolbar.js'), … … 2046 1931 this.render(); 2047 1932 1933 /* Trigger render_new */ 1934 /* 1935 * Action run after a new shortcode overlay is rendered. 1936 * 1937 * Called as `shortcode-ui.render_new`. 1938 * 1939 * @param shortcodeModel (object) 1940 * Reference to the shortcode model used in this overlay. 1941 */ 1942 var hookName = 'shortcode-ui.render_new'; 1943 var shortcodeModel = this.controller.props.get( 'currentShortcode' ); 1944 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 1945 2048 1946 }, 2049 1947 … … 2053 1951 2054 1952 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 2055 },{"./../utils/sui.js":10,"./edit-shortcode-form.js":1 5,"./insert-shortcode-list.js":17,"./media-toolbar.js":19,"./search-shortcode.js":20,"./shortcode-preview.js":21}]},{},[7]);1953 },{"./../utils/sui.js":10,"./edit-shortcode-form.js":17,"./insert-shortcode-list.js":19,"./media-toolbar.js":21,"./search-shortcode.js":22}]},{},[7]); -
shortcode-ui/trunk/js/src/controllers/media-controller.js
r1147525 r1536575 27 27 var pattern = new RegExp( searchTerm, "gi" ); 28 28 var filteredModels = sui.shortcodes.filter( function( model ) { 29 pattern.lastIndex = 0; 29 30 return pattern.test( model.get( "label" ) ); 30 31 }); -
shortcode-ui/trunk/js/src/models/shortcode.js
r1278066 r1536575 76 76 // Encode textareas incase HTML 77 77 if ( attr.get( 'encode' ) ) { 78 attr.set( 'value', encodeURIComponent( decodeURIComponent( attr.get( 'value' ) ) ), { silent: true } );78 attr.set( 'value', encodeURIComponent( decodeURIComponent( attr.get( 'value' ).replace( "%", "%" ) ) ), { silent: true } ); 79 79 } 80 80 … … 94 94 95 95 if ( attrs.length > 0 ) { 96 template = "[{{ shortcode }} {{ attributes }} ]";96 template = "[{{ shortcode }} {{ attributes }}"; 97 97 } else { 98 template = "[{{ shortcode }} ]";98 template = "[{{ shortcode }}"; 99 99 } 100 100 101 101 if ( content && content.length > 0 ) { 102 template += "{{ content }}[/{{ shortcode }}]"; 102 template += "]{{ content }}[/{{ shortcode }}]"; 103 } else { 104 // add closing slash to shortcodes without content 105 template += "/]"; 103 106 } 104 107 -
shortcode-ui/trunk/js/src/shortcode-ui.js
r1147525 r1536575 18 18 wp.mce.views.register( 19 19 shortcode.get('shortcode_tag'), 20 // Must extend for 4.1. 21 // This is handled by wp.mce.views.register in 4.2. 22 $.extend( true, {}, shortcodeViewConstructor ) 20 shortcodeViewConstructor 23 21 ); 24 22 } 25 23 } ); 26 24 25 $(document.body).on( 'click', '.shortcake-add-post-element', function( event ) { 26 var elem = $( event.currentTarget ), 27 editor = elem.data('editor'), 28 options = { 29 frame: 'post', 30 state: 'shortcode-ui', 31 title: shortcodeUIData.strings.media_frame_title 32 }; 33 34 event.preventDefault(); 35 36 // Remove focus from the `.shortcake-add-post-element` button. 37 // Prevents Opera from showing the outline of the button above the modal. 38 // 39 // See: https://core.trac.wordpress.org/ticket/22445 40 elem.blur(); 41 42 wp.media.editor.remove( editor ); 43 wp.media.editor.open( editor, options ); 44 } ); 45 27 46 }); -
shortcode-ui/trunk/js/src/utils/fetcher.js
r1278066 r1536575 82 82 } 83 83 84 var request = $.post( ajaxurl + '?action=bulk_do_shortcode', { 85 queries: _.pluck( fetcher.queries, 'query' ) 86 } 87 ); 84 var request = wp.ajax.post( 'bulk_do_shortcode', { 85 queries: _.pluck( fetcher.queries, 'query' ) 86 }); 88 87 89 request.done( function( response ) {90 _.each( response .data, function( result, index ) {88 request.done( function( responseData ) { 89 _.each( responseData, function( result, index ) { 91 90 var matchedQuery = _.findWhere( fetcher.queries, { 92 91 counter: parseInt( index ), -
shortcode-ui/trunk/js/src/utils/shortcode-view-constructor.js
r1281670 r1536575 85 85 if ( attr && attr.get('encode') ) { 86 86 value = decodeURIComponent( value ); 87 value = value.replace( "%", "%" ); 87 88 } 88 89 … … 161 162 */ 162 163 edit: function( shortcodeString ) { 163 var currentShortcode; 164 165 // Backwards compatability for WP pre-4.2 166 if ( 'object' === typeof( shortcodeString ) ) { 167 shortcodeString = decodeURIComponent( $(shortcodeString).attr('data-wpview-text') ); 168 } 169 170 currentShortcode = this.parseShortcodeString( shortcodeString ); 164 165 var currentShortcode = this.parseShortcodeString( shortcodeString ); 171 166 172 167 if ( currentShortcode ) { … … 180 175 wp_media_frame.open(); 181 176 177 /* Trigger render_edit */ 178 /* 179 * Action run after an edit shortcode overlay is rendered. 180 * 181 * Called as `shortcode-ui.render_edit`. 182 * 183 * @param shortcodeModel (object) 184 * Reference to the shortcode model used in this overlay. 185 */ 186 var hookName = 'shortcode-ui.render_edit'; 187 var shortcodeModel = this.shortcodeModel; 188 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 189 182 190 } 183 191 … … 200 208 var shortcode_tags = _.map( sui.shortcodes.pluck( 'shortcode_tag' ), this.pregQuote ).join( '|' ); 201 209 var regexp = wp.shortcode.regexp( shortcode_tags ); 210 regexp.lastIndex = 0; 202 211 var matches = regexp.exec( shortcodeString ); 203 212 … … 252 261 }, 253 262 254 // Backwards compatability for Pre WP 4.2.255 View: {256 257 overlay: true,258 259 initialize: function( options ) {260 this.shortcode = this.getShortcode( options );261 this.fetch();262 },263 264 getShortcode: function( options ) {265 266 var shortcodeModel, shortcode;267 268 shortcodeModel = sui.shortcodes.findWhere( { shortcode_tag: options.shortcode.tag } );269 270 if (!shortcodeModel) {271 return;272 }273 274 shortcode = shortcodeModel.clone();275 276 shortcode.get('attrs').each(277 function(attr) {278 279 if (attr.get('attr') in options.shortcode.attrs.named) {280 attr.set('value',281 options.shortcode.attrs.named[attr282 .get('attr')]);283 }284 285 });286 287 if ('content' in options.shortcode) {288 var inner_content = shortcode.get('inner_content');289 if ( inner_content ) {290 inner_content.set('value', options.shortcode.content);291 }292 }293 294 return shortcode;295 296 },297 298 fetch : function() {299 300 var self = this;301 302 if ( ! this.parsed ) {303 304 wp.ajax.post( 'do_shortcode', {305 post_id: $( '#post_ID' ).val(),306 shortcode: this.shortcode.formatShortcode(),307 nonce: shortcodeUIData.nonces.preview,308 }).done( function( response ) {309 if ( response.indexOf( '<script' ) !== -1 ) {310 self.setIframes( self.getEditorStyles(), response );311 } else {312 self.parsed = response;313 self.render( true );314 }315 }).fail( function() {316 self.parsed = '<span class="shortcake-error">' + shortcodeUIData.strings.mce_view_error + '</span>';317 self.render( true );318 } );319 320 }321 322 },323 324 /**325 * Render the shortcode326 *327 * To ensure consistent rendering - this makes an ajax request to the328 * admin and displays.329 *330 * @return string html331 */332 getHtml : function() {333 return this.parsed;334 },335 336 /**337 * Returns an array of <link> tags for stylesheets applied to the TinyMCE editor.338 *339 * @method getEditorStyles340 * @returns {Array}341 */342 getEditorStyles: function() {343 344 var styles = '';345 346 this.getNodes( function ( editor, node, content ) {347 var dom = editor.dom,348 bodyClasses = editor.getBody().className || '',349 iframe, iframeDoc, i, resize;350 351 tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), function( link ) {352 if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&353 link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {354 355 styles += dom.getOuterHTML( link ) + '\n';356 }357 358 });359 360 } );361 362 return styles;363 },364 365 },366 263 }; 367 264 -
shortcode-ui/trunk/js/src/views/edit-attribute-field-attachment.js
r1278066 r1536575 1 1 var sui = require('sui-utils/sui'); 2 var $ = require('jquery'); 2 3 3 4 var editAttributeFieldAttachment = sui.views.editAttributeField.extend( { 5 6 previewTemplate: wp.template( 'shortcake-image-preview' ), 4 7 5 8 events: { … … 10 13 }, 11 14 15 currentSelection: [], 16 17 initialize: function() { 18 19 var self = this; 20 21 _.bindAll( self, 'updateValue', 'initSelection', '_renderPreview', '_renderAll', '_removeAttachment' ); 22 23 self.initSelection(); 24 25 self.currentSelection.on( 'all', this.updateValue ); 26 self.currentSelection.on( 'add', this._renderPreview ); 27 self.currentSelection.on( 'reset', this._renderAll ); 28 29 }, 30 31 /** 32 * Initialize Selection. 33 * 34 * Selection is an Attachment collection containing full models for the current value. 35 * 36 * @return null 37 */ 38 initSelection: function() { 39 40 this.currentSelection = new wp.media.model.Selection( [], { 41 multiple: this.model.get( 'multiple' ) ? true : false, 42 } ); 43 44 // Initialize selection. 45 _.each( this.getValue(), function( item ) { 46 47 var model; 48 49 // Legacy. Handle storing full objects. 50 item = ( 'object' === typeof( item ) ) ? item.id : item; 51 model = new wp.media.attachment( item ); 52 53 this.currentSelection.add( model ); 54 55 // Re-render after attachments have synced. 56 model.fetch(); 57 model.on( 'sync', this._renderAll ); 58 59 }.bind(this) ); 60 61 }, 62 12 63 /** 13 64 * Update the field attachment. … … 17 68 * @param {int} id Attachment ID 18 69 */ 19 updateValue: function( id ) { 20 21 if ( ! id ) { 22 return; 23 } 24 25 this.setValue( id ); 26 27 var self = this; 28 29 if ( editAttributeFieldAttachment.getFromCache( id ) ) { 30 self._renderPreview( editAttributeFieldAttachment.getFromCache( id ) ); 31 32 // Call the updateValue() function, to trigger any listeners 33 // hooked on it. 34 self.triggerCallbacks(); 35 return; 36 } 37 38 this.$container.addClass( 'loading' ); 39 40 wp.ajax.post( 'get-attachment', { 41 'id': id 42 } ).done( function( attachment ) { 43 // Cache for later. 44 editAttributeFieldAttachment.setInCache( id, attachment ); 45 self._renderPreview( attachment ); 46 47 // Call the updateValue() function, to trigger any listeners 48 // hooked on it. 49 self.triggerCallbacks(); 50 } ).always( function( attachment ) { 51 self.$container.removeClass( 'loading' ); 52 }); 70 updateValue: function() { 71 var value = this.currentSelection.pluck( 'id' ); 72 this.setValue( value ); 73 this.triggerCallbacks(); 53 74 }, 54 75 … … 64 85 this.$el.html( this.template( this.model.toJSON() ) ); 65 86 66 this.$container = this.$el.find( '.shortcake-attachment-preview' );87 this.$container = this.$el.find( '.attachment-previews' ); 67 88 this.$thumbnailDetailsContainer = this.$el.find( '.thumbnail-details-container' ); 68 var $addButton = this.$container.find( 'button.add' );89 var $addButton = this.$container.find( 'button.add' ); 69 90 70 91 this.frame = wp.media( { 71 multiple: false,72 title: this.model.get( 'frameTitle' ),92 multiple: this.model.get( 'multiple' ) ? true : false, 93 title: this.model.get( 'frameTitle' ), 73 94 library: { 74 95 type: this.model.get( 'libraryType' ), … … 76 97 } ); 77 98 78 // Add initial Attachment if available. 79 this.updateValue( this.model.get( 'value' ) ); 99 this.frame.on( 'select', function() { 100 this.$el.trigger( 'selectAttachment' ); 101 }.bind( this ) ); 102 103 this._renderAll(); 104 105 }, 106 107 _renderAll: function() { 108 109 // Empty container. 110 this.$container.html(''); 111 112 // Render each attachment in current selection. 113 this.currentSelection.each( function( attachment ) { 114 this._renderPreview( attachment ); 115 }.bind(this) ); 80 116 81 117 }, … … 88 124 _renderPreview: function( attachment ) { 89 125 90 var $thumbnail = jQuery('<div class="thumbnail"></div>'); 91 92 if ( 'image' !== attachment.type ) { 93 94 jQuery( '<img/>', { 95 src: attachment.icon, 96 alt: attachment.title, 97 } ).appendTo( $thumbnail ); 98 99 jQuery( '<div/>', { 100 class: 'filename', 101 html: '<div>' + attachment.title + '</div>', 102 } ).appendTo( $thumbnail ); 103 104 } else { 105 106 attachmentThumb = (typeof attachment.sizes.thumbnail !== 'undefined') ? 107 attachment.sizes.thumbnail : 108 _.first( _.sortBy( attachment.sizes, 'width' ) ); 109 110 jQuery( '<img/>', { 111 src: attachmentThumb.url, 112 width: attachmentThumb.width, 113 height: attachmentThumb.height, 114 alt: attachment.alt, 115 } ) .appendTo( $thumbnail ); 116 117 } 118 119 $thumbnail.find( 'img' ).wrap( '<div class="centered"></div>' ); 120 this.$container.append( $thumbnail ); 121 this.$container.toggleClass( 'has-attachment', true ); 122 123 this.$thumbnailDetailsContainer.find( '.filename' ).text( attachment.filename ); 124 this.$thumbnailDetailsContainer.find( '.date-formatted' ).text( attachment.dateFormatted ); 125 this.$thumbnailDetailsContainer.find( '.size' ).text( attachment.filesizeHumanReadable ); 126 this.$thumbnailDetailsContainer.find( '.dimensions' ).text( attachment.height + ' × ' + attachment.width ); 127 this.$thumbnailDetailsContainer.find( '.edit-link a' ).attr( "href", attachment.editLink ); 128 this.$thumbnailDetailsContainer.toggleClass( 'has-attachment', true ); 126 var $thumbnail = $( this.previewTemplate( attachment.toJSON() ) ); 127 128 $thumbnail.appendTo( this.$container ); 129 130 attachment.on( 'remove', function() { 131 $thumbnail.remove(); 132 } ); 133 134 }, 135 136 getValue: function() { 137 138 var value = this.model.get( 'value' ); 139 140 if ( ! ( value instanceof Array ) ) { 141 value = value.split( ',' ); 142 } 143 144 value = value.map( function( id ) { 145 return parseInt( id, 10 ); 146 } ); 147 148 value = value.filter( function( id ) { 149 return id > 0; 150 } ); 151 152 value.sort( function( a, b ) { 153 return a < b; 154 } ); 155 156 return value; 129 157 130 158 }, … … 135 163 */ 136 164 _openMediaFrame: function(e) { 165 137 166 e.preventDefault(); 138 167 this.frame.open(); 139 if ( this.model.get( 'value' ) ) { 140 var selection = this.frame.state().get('selection'); 141 attachment = wp.media.attachment( this.model.get( 'value' ) ); 142 attachment.fetch(); 143 selection.reset( attachment ? [ attachment ] : [] ); 144 this.frame.state().set('selection', selection); 145 } 146 147 var self = this; 148 this.frame.on( 'select', function() { 149 self.$el.trigger( 'selectAttachment' ); 150 } ); 168 169 var selection = this.frame.state().get('selection'); 170 selection.reset( this.currentSelection.models ); 171 this.frame.state('library').set( 'selection', selection ); 151 172 152 173 }, … … 157 178 */ 158 179 _selectAttachment: function(e) { 180 159 181 var selection = this.frame.state().get('selection'); 160 attachment = selection.first(); 161 if ( attachment.id != this.model.get( 'value' ) ){ 162 this.model.set( 'value', null ); 163 this.$container.toggleClass( 'has-attachment', false ); 164 this.$container.find( '.thumbnail' ).remove(); 165 this.updateValue( attachment.id ); 166 } 182 this.currentSelection.reset( selection.toJSON() ); 183 167 184 this.frame.close(); 185 168 186 }, 169 187 … … 173 191 */ 174 192 _removeAttachment: function(e) { 193 175 194 e.preventDefault(); 176 195 177 this.model.set( 'value', null ); 178 179 this.$container.toggleClass( 'has-attachment', false ); 180 this.$container.find( '.thumbnail' ).remove(); 181 this.$thumbnailDetailsContainer.toggleClass( 'has-attachment', false ); 182 }, 183 184 }, { 185 186 _idCache: {}, 187 188 /** 189 * Store attachments in a cache for quicker loading. 190 */ 191 setInCache: function( id, attachment ) { 192 this._idCache[ id ] = attachment; 193 }, 194 195 /** 196 * Retrieve an attachment from the cache. 197 */ 198 getFromCache: function( id ){ 199 if ( 'undefined' === typeof this._idCache[ id ] ) { 200 return false; 201 } 202 return this._idCache[ id ]; 196 var id = $( e.target ).attr( 'data-id' ); 197 198 if ( ! id ) { 199 return; 200 } 201 202 var target = this.currentSelection.get( id ); 203 204 if ( target ) { 205 this.currentSelection.remove( target ); 206 } 207 203 208 }, 204 209 -
shortcode-ui/trunk/js/src/views/edit-attribute-field-post-select.js
r1231560 r1536575 1 ( function( $ ) { 1 var Backbone = require('backbone'), 2 sui = require('sui-utils/sui'), 3 select2Field = require('sui-views/select2-field.js'), 4 $ = require('jquery'); 2 5 3 var sui = window.Shortcode_UI; 6 sui.views.editAttributeFieldPostSelect = sui.views.editAttributeSelect2Field.extend( { 4 7 5 // Cached Data. 6 var postSelectCache = {}; 8 selector: '.shortcode-ui-post-select', 7 9 8 sui.views.editAttributeFieldPostSelect = sui.views.editAttributeField.extend( { 10 ajaxData: { 11 action : 'shortcode_ui_post_field', 12 nonce : shortcodeUiPostFieldData.nonce, 13 }, 9 14 10 events: {11 'change .shortcode-ui-post-select': 'inputChanged',12 },15 events: { 16 'change .shortcode-ui-post-select': 'inputChanged', 17 }, 13 18 14 inputChanged: function(e) { 15 this.setValue( e.val ); 16 this.triggerCallbacks(); 17 }, 18 19 render: function() { 20 21 var self = this, 22 defaults = { multiple: false }; 23 24 for ( var arg in defaults ) { 25 if ( ! this.model.get( arg ) ) { 26 this.model.set( arg, defaults[ arg ] ); 27 } 28 } 29 30 var data = this.model.toJSON(); 31 data.id = 'shortcode-ui-' + this.model.get( 'attr' ) + '-' + this.model.cid; 32 33 this.$el.html( this.template( data ) ); 34 35 var ajaxData = { 36 action : 'shortcode_ui_post_field', 37 nonce : shortcodeUiPostFieldData.nonce, 38 shortcode : this.shortcode.get( 'shortcode_tag'), 39 attr : this.model.get( 'attr' ) 40 }; 41 42 var $field = this.$el.find( '.shortcode-ui-post-select' ); 43 44 $field.select2({ 45 46 placeholder: "Search", 47 multiple: this.model.get( 'multiple' ), 48 ajax: { 49 url: ajaxurl, 50 dataType: 'json', 51 quietMillis: 250, 52 data: function (term, page) { 53 ajaxData.s = term; 54 ajaxData.page = page; 55 return ajaxData; 56 }, 57 results: function ( response, page ) { 58 59 if ( ! response.success ) { 60 return { results: {}, more: false }; 61 } 62 63 // Cache data for quicker rendering later. 64 postSelectCache = $.extend( postSelectCache, response.data.posts ); 65 66 var more = ( page * response.data.posts_per_page ) < response.data.found_posts; // whether or not there are more results available 67 return { results: response.data.posts, more: more }; 68 69 }, 70 }, 71 72 /** 73 * Initialize Callback 74 * Used to set render the initial value. 75 * Has to make a request to get the title for the current ID. 76 */ 77 initSelection: function(element, callback) { 78 79 var ids, parsedData = [], cached; 80 81 // Convert stored value to array of IDs (int). 82 ids = $(element) 83 .val() 84 .split(',') 85 .map( function (str) { return str.trim(); } ) 86 .map( function (str) { return parseInt( str ); } ); 87 88 if ( ids.length < 1 ) { 89 return; 90 } 91 92 // Check if there is already cached data. 93 for ( var i = 0; i < ids.length; i++ ) { 94 cached = _.find( postSelectCache, _.matches( { id: ids[i] } ) ); 95 if ( cached ) { 96 parsedData.push( cached ); 97 } 98 } 99 100 // If not multiple - return single value if we have one. 101 if ( parsedData.length && ! self.model.get( 'multiple' ) ) { 102 callback( parsedData[0] ); 103 return; 104 } 105 106 var uncachedIds = _.difference( ids, _.pluck( parsedData, 'id' ) ); 107 108 if ( ! uncachedIds.length ) { 109 110 callback( parsedData ); 111 112 } else { 113 114 var initAjaxData = jQuery.extend( true, {}, ajaxData ); 115 initAjaxData.action = 'shortcode_ui_post_field'; 116 initAjaxData.post__in = uncachedIds; 117 118 $.get( ajaxurl, initAjaxData ).done( function( response ) { 119 120 if ( ! response.success ) { 121 return { results: {}, more: false }; 122 } 123 124 postSelectCache = $.extend( postSelectCache, response.data.posts ); 125 126 // If not multi-select, expects single object, not array of objects. 127 if ( ! self.model.get( 'multiple' ) ) { 128 callback( response.data.posts[0] ); 129 return; 130 } 131 132 // Append new data to cached data. 133 // Sort by original order. 134 parsedData = parsedData 135 .concat( response.data.posts ) 136 .sort(function (a, b) { 137 if ( ids.indexOf( a.id ) > ids.indexOf( b.id ) ) return 1; 138 if ( ids.indexOf( a.id ) < ids.indexOf( b.id ) ) return -1; 139 return 0; 140 }); 141 142 callback( parsedData ); 143 return; 144 145 } ); 146 147 } 148 149 }, 150 151 } ); 152 153 // Make multiple values sortable. 154 if ( this.model.get( 'multiple' ) ) { 155 $field.select2('container').find('ul.select2-choices').sortable({ 156 containment: 'parent', 157 start: function() { $('.shortcode-ui-post-select').select2('onSortStart'); }, 158 update: function() { $('.shortcode-ui-post-select').select2('onSortEnd'); } 159 }); 160 } 161 162 return this; 163 19 templateResult: function( post ) { 20 if ( post.loading ) { 21 return post.text; 164 22 } 165 23 166 } ); 24 var markup = '<div class="clearfix select2-result-selectable">' + 25 post.text + 26 '</div>'; 167 27 168 /** 169 * Extending SUI Media Controller to hide Select2 UI Drop-Down when menu 170 * changes in Meida modal 171 * 1. going back/forth between different shortcakes (refresh) 172 * 2. changing the menu in left column (deactivate) 173 * 3. @TODO closing the modal. 174 */ 175 var mediaController = sui.controllers.MediaController; 176 sui.controllers.MediaController = mediaController.extend({ 28 return markup; 29 }, 177 30 178 refresh: function(){ 179 mediaController.prototype.refresh.apply( this, arguments ); 180 this.destroySelect2UI(); 181 }, 31 templateSelection: function( post, container ) { 32 return post.text; 33 }, 182 34 183 //doesn't need to call parent as it already an "abstract" method in parent to provide callback184 deactivate: function() {185 this.destroySelect2UI();186 },187 35 188 destroySelect2UI: function() { 189 $('.shortcode-ui-post-select.select2-container').select2( "close" ); 190 } 191 192 }); 193 194 } )( jQuery ); 36 } ); -
shortcode-ui/trunk/js/src/views/edit-attribute-field.js
r1284972 r1536575 42 42 43 43 data.meta = _meta.join( ' ' ); 44 45 // Ensure options are formatted correctly. 46 if ( 'options' in data ) { 47 data.options = this.parseOptions( data.options ); 48 } 44 49 45 50 this.$el.html( this.template( data ) ); … … 114 119 wp.shortcake.hooks.doAction( hookName, changed, collection, shortcode ); 115 120 121 }, 122 123 /** 124 * Parse Options to ensure they use the correct format. 125 * 126 * Backwards compatability for non-array options. 127 * Using objects was sub-optimal because properties don't have an order. 128 */ 129 parseOptions: function( options ) { 130 131 if ( ! Array.isArray( options ) ) { 132 var _options = []; 133 _.each( Object.keys( options ), function( key ) { 134 _options.push( { value: key, label: options[ key ] } ); 135 } ); 136 options = _options; 137 } else { 138 options = options.map( function( option ) { 139 if ( 'object' !== typeof option ) { 140 option = { value: option, label: option }; 141 } 142 return option; 143 } ); 144 } 145 146 return options; 147 116 148 } 117 149 -
shortcode-ui/trunk/js/src/views/edit-shortcode-form.js
r1278066 r1536575 8 8 editAttributeFieldAttachment = require( 'sui-views/edit-attribute-field-attachment' ), 9 9 editAttributeFieldPostSelect = require( 'sui-views/edit-attribute-field-post-select' ), 10 editAttributeFieldColor = require( 'sui-views/edit-attribute-field-color' ); 10 editAttributeFieldTermSelect = require( 'sui-views/edit-attribute-field-term-select' ), 11 editAttributeFieldUserSelect = require( 'sui-views/edit-attribute-field-user-select' ), 12 editAttributeFieldColor = require( 'sui-views/edit-attribute-field-color' ); 11 13 12 14 -
shortcode-ui/trunk/js/src/views/media-frame.js
r1282644 r1536575 113 113 114 114 insertAction: function() { 115 /* Trigger render_destroy */ 116 /* 117 * Action run before the shortcode overlay is destroyed. 118 * 119 * Called as `shortcode-ui.render_destroy`. 120 * 121 * @param shortcodeModel (object) 122 * Reference to the shortcode model used in this overlay. 123 */ 124 var hookName = 'shortcode-ui.render_destroy'; 125 var shortcodeModel = this.controller.state().props.get( 'currentShortcode' ); 126 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 127 115 128 this.controller.state().insert(); 129 116 130 }, 117 131 -
shortcode-ui/trunk/js/src/views/shortcode-ui.js
r1231560 r1536575 1 1 var Backbone = require('backbone'), 2 2 insertShortcodeList = require('sui-views/insert-shortcode-list'), 3 ShortcodePreview = require('sui-views/shortcode-preview'),4 3 EditShortcodeForm = require('sui-views/edit-shortcode-form'), 5 4 Toolbar = require('sui-views/media-toolbar'), … … 96 95 this.render(); 97 96 97 /* Trigger render_new */ 98 /* 99 * Action run after a new shortcode overlay is rendered. 100 * 101 * Called as `shortcode-ui.render_new`. 102 * 103 * @param shortcodeModel (object) 104 * Reference to the shortcode model used in this overlay. 105 */ 106 var hookName = 'shortcode-ui.render_new'; 107 var shortcodeModel = this.controller.props.get( 'currentShortcode' ); 108 wp.shortcake.hooks.doAction( hookName, shortcodeModel ); 109 98 110 }, 99 111 -
shortcode-ui/trunk/languages/shortcode-ui.pot
r1278066 r1536575 1 # Copyright (C) 201 5Fusion Engineering and community1 # Copyright (C) 2016 Fusion Engineering and community 2 2 # This file is distributed under the GPL v2 or later. 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Shortcake (Shortcode UI) 0. 6.0-alpha\n"5 "Project-Id-Version: Shortcake (Shortcode UI) 0.7.0-alpha\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/shortcode-ui\n" 7 "POT-Creation-Date: 201 5-10-09 18:13:32+00:00\n"7 "POT-Creation-Date: 2016-04-20 14:44:36+00:00\n" 8 8 "MIME-Version: 1.0\n" 9 9 "Content-Type: text/plain; charset=utf-8\n" 10 10 "Content-Transfer-Encoding: 8bit\n" 11 "PO-Revision-Date: 201 5-MO-DA HO:MI+ZONE\n"11 "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n" 12 12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 13 13 "Language-Team: LANGUAGE <LL@li.org>\n" 14 "X-Generator: grunt-wp-i18n 0.5. 3\n"14 "X-Generator: grunt-wp-i18n 0.5.4\n" 15 15 "X-Poedit-KeywordsList: " 16 16 "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_" … … 25 25 "X-Textdomain-Support: yes\n" 26 26 27 #: dev.php:75 27 #: dev.php:68 28 msgid "" 29 "Shortcode UI plugin must be active for Shortcode UI Example plugin to " 30 "function." 31 msgstr "" 32 33 #: dev.php:119 34 msgid "Shortcake With No Attributes" 35 msgstr "" 36 37 #: dev.php:159 28 38 msgid "Attachment" 29 39 msgstr "" 30 40 31 #: dev.php: 79 dev.php:8041 #: dev.php:169 dev.php:170 32 42 msgid "Select Image" 33 43 msgstr "" 34 44 35 #: dev.php: 8345 #: dev.php:173 36 46 msgid "Citation Source" 47 msgstr "" 48 49 #: dev.php:178 50 msgid "Test placeholder" 51 msgstr "" 52 53 #: dev.php:183 54 msgid "Select Page" 55 msgstr "" 56 57 #: dev.php:190 58 msgid "Background Color" 59 msgstr "" 60 61 #: dev.php:195 62 msgid "Hex color code" 63 msgstr "" 64 65 #: dev.php:199 66 msgid "Alignment" 67 msgstr "" 68 69 #: dev.php:200 70 msgid "" 71 "Whether the quotation should be displayed as pull-left, pull-right, or " 72 "neither." 73 msgstr "" 74 75 #: dev.php:204 76 msgid "None" 77 msgstr "" 78 79 #: dev.php:205 80 msgid "Pull Left" 81 msgstr "" 82 83 #: dev.php:206 84 msgid "Pull Right" 85 msgstr "" 86 87 #: dev.php:210 88 msgid "Year" 89 msgstr "" 90 91 #: dev.php:211 92 msgid "Optional. The year the quotation is from." 93 msgstr "" 94 95 #: dev.php:230 96 msgid "Shortcake Dev" 97 msgstr "" 98 99 #: dev.php:249 100 msgid "Quote" 101 msgstr "" 102 103 #: dev.php:250 104 msgid "Include a statement from someone famous." 105 msgstr "" 106 107 #: dev.php:288 108 msgid "Content:" 109 msgstr "" 110 111 #: dev.php:289 112 msgid "Source:" 113 msgstr "" 114 115 #: dev.php:290 116 msgid "Image:" 37 117 msgstr "" 38 118 … … 41 121 msgstr "" 42 122 43 #: inc/class-shortcode-ui.php:2 20 inc/class-shortcode-ui.php:221123 #: inc/class-shortcode-ui.php:236 inc/class-shortcode-ui.php:237 44 124 msgid "Insert Post Element" 45 125 msgstr "" 46 126 47 #: inc/class-shortcode-ui.php:2 22127 #: inc/class-shortcode-ui.php:238 48 128 msgid "%s Details" 49 129 msgstr "" 50 130 51 #: inc/class-shortcode-ui.php:2 23131 #: inc/class-shortcode-ui.php:239 52 132 msgid "Insert Element" 53 133 msgstr "" 54 134 55 #: inc/class-shortcode-ui.php:2 24135 #: inc/class-shortcode-ui.php:240 56 136 msgid "Update" 57 137 msgstr "" 58 138 59 #: inc/class-shortcode-ui.php:2 25139 #: inc/class-shortcode-ui.php:241 60 140 msgid "There are no attributes to configure for this Post Element." 61 141 msgstr "" 62 142 63 #: inc/class-shortcode-ui.php:2 26143 #: inc/class-shortcode-ui.php:242 64 144 msgid "Failed to load preview" 65 145 msgstr "" 66 146 67 #: inc/class-shortcode-ui.php:2 27147 #: inc/class-shortcode-ui.php:243 68 148 msgid "Search" 69 149 msgstr "" 70 150 71 #: inc/class-shortcode-ui.php:2 28151 #: inc/class-shortcode-ui.php:244 72 152 msgid "Insert Content" 73 153 msgstr "" 74 154 75 #: inc/class-shortcode-ui.php:3 23155 #: inc/class-shortcode-ui.php:339 76 156 msgid "Something's rotten in the state of Denmark" 77 157 msgstr "" -
shortcode-ui/trunk/package.json
r1278066 r1536575 11 11 "grunt": "^0.4.5", 12 12 "grunt-browserify": "^3.4.0", 13 "grunt-contrib-jasmine": "^ 0.8.2",13 "grunt-contrib-jasmine": "^1.0.3", 14 14 "grunt-contrib-jshint": "^0.11.2", 15 15 "grunt-contrib-watch": "^0.6.1", 16 16 "grunt-phpcs": "^0.4.0", 17 17 "grunt-postcss": "^0.6.0", 18 "grunt-sass": "^ 0.18.0",18 "grunt-sass": "^1.1.0", 19 19 "grunt-wp-i18n": "^0.5.0", 20 20 "grunt-wp-readme-to-markdown": "~1.0.0", -
shortcode-ui/trunk/readme.txt
r1284972 r1536575 1 1 === Shortcake (Shortcode UI) === 2 Contributors: fusionengineering, mattheu, danielbachhuber, zebulonj, goldenapples, jitendraharpalani, sanchothefat, bfintal, davisshaver, garyj, mte90, fredserva, khromov 2 Contributors: fusionengineering, mattheu, danielbachhuber, zebulonj, goldenapples, jitendraharpalani, sanchothefat, bfintal, davisshaver, garyj, mte90, fredserva, khromov, bronsonquick, dashaluna, mehigh, sc0ttkclark, kraftner, pravdomil 3 3 Tags: shortcodes 4 Requires at least: 4. 15 Tested up to: 4. 46 Stable tag: 0. 6.24 Requires at least: 4.5 5 Tested up to: 4.7 6 Stable tag: 0.7.0 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 32 32 Shortcake doesn't support custom key=>value pairs as shortcode attributes because it isn't a great user experience. 33 33 34 == Running tests == 35 36 We have test coverage for PHP using PHPunit, and JavaScript using Jasmine. 37 38 = Running tests locally = 39 40 Jasmine tests can be run using `grunt jasmine` and are also run as part of the `grunt scripts` task. To update the core WordPress files used by the Jasmine test suite, run `grunt updateJasmineCoreScripts --abspath="/path/to/wordpress-install"`. 34 41 35 42 == Screenshots == … … 51 58 52 59 == Changelog == 60 61 = 0.7.0 (November 18, 2016) = 62 * Adds "Add post element" button to media buttons - one click to open the shortcode list, rather than clicking "Add media" button and then finding "insert post element" in the menu. 63 * Added "Term Select" field type. 64 * Added "User Select" field type. 65 * Added new hooks that fire on rendering/editing/closing a shortcode, which can be used for field types which require custom javascript initialization or cleanup. 66 * Select fields: add full support for multiple select fields. 67 * Select fields: support custom ordering of options. 68 * Select fields: support grouping option in `<optgroup>`s by passing them as a nested array. 69 * Attachment fields: support multiple selection. 70 * Attachment fields: support SVG images (if svg uploads are enabled by a plugin or theme). 71 * Bug fix: Handle percent signs when decoding fields with `encode=true` specified. 72 * Bug fix: fix issue where it takes two clicks on a shortcode in editor to bring up the Edit Shortcode modal. 73 * Bug fix: fix issue when searching for shortcodes by name where if multiple shortcodes start with the search string, only the first is returned. 74 * Bug fix: only output a description field on an attribute if it's not empty. 75 * Compatability: Remove shims for handling the media modal in WP 4.1 and 4.2. 76 * Compatability: Upgrade Select2 library to 4.0.3 to avoid conflicts with other plugins which use the latest version of Select2. 77 * Added Turkish translation. 78 * Added Finnish translation. 79 * Added Swedish translation. 80 * Added Hungarian translation. 53 81 54 82 = 0.6.2 (November 12, 2015) = -
shortcode-ui/trunk/shortcode-ui.php
r1284972 r1536575 2 2 /** 3 3 * Plugin Name: Shortcake (Shortcode UI) 4 * Version: 0. 6.24 * Version: 0.7.0 5 5 * Description: User Interface for adding shortcodes. 6 6 * Author: Fusion Engineering and community … … 20 20 */ 21 21 22 define( 'SHORTCODE_UI_VERSION', '0. 6.2' );22 define( 'SHORTCODE_UI_VERSION', '0.7.0-alpha' ); 23 23 24 24 require_once dirname( __FILE__ ) . '/inc/class-shortcode-ui.php'; … … 27 27 require_once dirname( __FILE__ ) . '/inc/fields/class-field-color.php'; 28 28 require_once dirname( __FILE__ ) . '/inc/fields/class-field-post-select.php'; 29 require_once dirname( __FILE__ ) . '/inc/fields/class-field-term-select.php'; 30 require_once dirname( __FILE__ ) . '/inc/fields/class-field-user-select.php'; 29 31 30 32 add_action( 'init', 'shortcode_ui_load_textdomain' ); … … 43 45 $color_field = Shortcake_Field_Color::get_instance(); 44 46 $post_field = Shortcode_UI_Field_Post_Select::get_instance(); 47 $term_field = Shortcode_UI_Field_Term_Select::get_instance(); 48 $user_field = Shortcode_UI_Field_User_Select::get_instance(); 45 49 } 46 50 … … 59 63 // Load the textdomain according to the plugin first 60 64 $mofile = $domain . '-' . $locale . '.mo'; 61 if ( $loaded = load_textdomain( $domain, $path . '/' . $mofile ) ) {65 if ( $loaded = load_textdomain( $domain, $path . '/' . $mofile ) ) { 62 66 return; 63 67 }
Note: See TracChangeset
for help on using the changeset viewer.